Bug #51597 | Using mlock ulimits for SHM_HUGETLB deprecated | ||
---|---|---|---|
Submitted: | 1 Mar 2010 5:56 | Modified: | 14 Jan 2013 20:01 |
Reporter: | wenk Luis | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
Version: | 5.1.44 | OS: | Linux (gentoo 64bits) |
Assigned to: | Matthew Lord | CPU Architecture: | Any |
Tags: | Using mlock ulimits for SHM_HUGETLB deprecated |
[1 Mar 2010 5:56]
wenk Luis
[2 Aug 2010 12:33]
MySQL Verification Team
on my system, openSUSE 10.2 (X86-64), Linux box2 2.6.18.2-34-default. nothing in /var/log/messages and dmesg but innodb said: InnoDB: HugeTLB: Warning: Failed to allocate 419446784 bytes. errno 12 InnoDB HugeTLB: Warning: Using conventional memory pool
[2 Aug 2010 12:33]
Susanne Ebrecht
I am not able to repeat this exactly on Ubuntu. But I get the following message on start up: 100802 14:31:05 [Note] Plugin 'ndbcluster' is disabled. InnoDB: HugeTLB: Warning: Failed to allocate 8404992 bytes. errno 1 InnoDB HugeTLB: Warning: Using conventional memory pool
[14 Jan 2013 20:01]
Matthew Lord
The MySQL error log messages are simply the result of not having done the additional work outside of MySQL in order to get large pages working properly. For example: http://www.cyberciti.biz/tips/linux-hugetlbfs-and-mysql-performance.html http://time.to.pullthepl.ug/blog/2008/11/18/MySQL-Large-Pages-errors/ It is true that there is a potential to use the deprecated feature (fs/hugetlbfs/inode.c): 935 struct file *hugetlb_file_setup(const char *name, unsigned long addr, 936 size_t size, vm_flags_t acctflag, 937 struct user_struct **user, int creat_flags) 938 { 939 int error = -ENOMEM; 940 struct file *file; 941 struct inode *inode; 942 struct path path; 943 struct dentry *root; 944 struct qstr quick_string; 945 struct hstate *hstate; 946 unsigned long num_pages; 947 948 *user = NULL; 949 if (!hugetlbfs_vfsmount) 950 return ERR_PTR(-ENOENT); 951 952 if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { 953 *user = current_user(); 954 if (user_shm_lock(size, *user)) { 955 task_lock(current); 956 printk_once(KERN_WARNING 957 "%s (%d): Using mlock ulimits for SHM_HUGETLB is deprecated\n", 958 current->comm, current->pid); 959 task_unlock(current); 960 } else { 961 *user = NULL; 962 return ERR_PTR(-EPERM); 963 } 964 } However I am not able to repeat the issue using MySQL 5.5.29 on Ubuntu 12.10 x86_64. I get no kernel log message about this being used, and there is nowhere within MySQL that we make the hugetlb_file_setup call. The deprecated feature is used and the log message triggered when: creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm() All we are doing is calling shmget, shmat, and shmctl: http://linux.die.net/man/2/shmget http://linux.die.net/man/2/shmat http://linux.die.net/man/2/shmctl From "mysys/my_largepage.c": uchar* my_large_malloc_int(size_t size, myf my_flags) { int shmid; uchar* ptr; struct shmid_ds buf; DBUG_ENTER("my_large_malloc_int"); /* Align block size to my_large_page_size */ size= MY_ALIGN(size, (size_t) my_large_page_size); shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) { if (my_flags & MY_WME) fprintf(stderr, "Warning: Failed to allocate %lu bytes from HugeTLB memory." " errno %d\n", (ulong) size, errno); DBUG_RETURN(NULL); } ptr = (uchar*) shmat(shmid, NULL, 0); if (ptr == (uchar *) -1) { if (my_flags& MY_WME) fprintf(stderr, "Warning: Failed to attach shared memory segment," " errno %d\n", errno); shmctl(shmid, IPC_RMID, &buf); DBUG_RETURN(NULL); } /* Remove the shared memory segment so that it will be automatically freed after memory is detached or process exits */ shmctl(shmid, IPC_RMID, &buf); DBUG_RETURN(ptr); } I don't see where we're ever directly modifying, setting, or specifying anything related to either conditional: creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm() It seems that this is something handled by the local kernel and its large pages implementation. Perhaps it's related to whether you use /proc/sys/vm/hugetlb_shm_group as the can_do_hugetlb_shm() call does this (from fs/hugetlbfs/inode.c): 928 static int can_do_hugetlb_shm(void) 929 { 930 kgid_t shm_group; 931 shm_group = make_kgid(&init_user_ns, sysctl_hugetlb_shm_group); 932 return capable(CAP_IPC_LOCK) || in_group_p(shm_group); 933 } Please correct me if I'm wrong. For now at least, I will mark this as can't repeat. It seems that this is all done outside of MySQL and in the general large pages setup on the system. I don't see any clear documentation on setting up large pages WITHOUT using /proc/sys/vm/hugetlb_shm_group.