Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757553AbZKROys (ORCPT ); Wed, 18 Nov 2009 09:54:48 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757232AbZKROyq (ORCPT ); Wed, 18 Nov 2009 09:54:46 -0500 Received: from server1.wserver.cz ([82.113.45.157]:51270 "EHLO server1.wserver.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754454AbZKROwA (ORCPT ); Wed, 18 Nov 2009 09:52:00 -0500 From: Jiri Slaby To: jirislaby@gmail.com Cc: mingo@elte.hu, nhorman@tuxdriver.com, sfr@canb.auug.org.au, linux-kernel@vger.kernel.org, akpm@linux-foundation.org, marcin.slusarz@gmail.com, tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, torvalds@linux-foundation.org, Jiri Slaby , James Morris , Heiko Carstens , linux-mm@kvack.org Subject: [PATCH 09/16] MM: use ACCESS_ONCE for rlimits Date: Wed, 18 Nov 2009 15:51:55 +0100 Message-Id: <1258555922-2064-9-git-send-email-jslaby@novell.com> X-Mailer: git-send-email 1.6.4.2 In-Reply-To: <4B040A03.2020508@gmail.com> References: <4B040A03.2020508@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6131 Lines: 173 Make sure compiler won't do weird things with limits. E.g. fetching them twice may return 2 different values after writable limits are implemented. Signed-off-by: Jiri Slaby Cc: James Morris Cc: Heiko Carstens Cc: Andrew Morton Cc: Ingo Molnar Cc: linux-mm@kvack.org --- mm/filemap.c | 3 ++- mm/mlock.c | 15 +++++++++------ mm/mmap.c | 16 ++++++++++------ mm/mremap.c | 3 ++- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index ef169f3..667e62e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1971,7 +1971,8 @@ EXPORT_SYMBOL(iov_iter_single_seg_count); inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk) { struct inode *inode = file->f_mapping->host; - unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + unsigned long limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_FSIZE].rlim_cur); if (unlikely(*pos < 0)) return -EINVAL; diff --git a/mm/mlock.c b/mm/mlock.c index bd6f0e4..9fcd392 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -25,7 +25,7 @@ int can_do_mlock(void) { if (capable(CAP_IPC_LOCK)) return 1; - if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0) + if (ACCESS_ONCE(current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) != 0) return 1; return 0; } @@ -490,7 +490,8 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len) locked = len >> PAGE_SHIFT; locked += current->mm->locked_vm; - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_MEMLOCK].rlim_cur); lock_limit >>= PAGE_SHIFT; /* check against resource limits */ @@ -553,7 +554,8 @@ SYSCALL_DEFINE1(mlockall, int, flags) down_write(¤t->mm->mmap_sem); - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal->rlim[RLIMIT_MEMLOCK]. + rlim_cur); lock_limit >>= PAGE_SHIFT; ret = -ENOMEM; @@ -587,7 +589,8 @@ int user_shm_lock(size_t size, struct user_struct *user) int allowed = 0; locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_MEMLOCK].rlim_cur); if (lock_limit == RLIM_INFINITY) allowed = 1; lock_limit >>= PAGE_SHIFT; @@ -621,12 +624,12 @@ int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, down_write(&mm->mmap_sem); - lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; + lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT; vm = mm->total_vm + pgsz; if (lim < vm) goto out; - lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; + lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT; vm = mm->locked_vm + pgsz; if (lim < vm) goto out; diff --git a/mm/mmap.c b/mm/mmap.c index 73f5e4b..5017ed5 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -266,7 +266,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) * segment grow beyond its set limit the in case where the limit is * not page aligned -Ram Gupta */ - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; + rlim = ACCESS_ONCE(current->signal->rlim[RLIMIT_DATA].rlim_cur); if (rlim < RLIM_INFINITY && (brk - mm->start_brk) + (mm->end_data - mm->start_data) > rlim) goto out; @@ -990,7 +990,8 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long locked, lock_limit; locked = len >> PAGE_SHIFT; locked += mm->locked_vm; - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_MEMLOCK].rlim_cur); lock_limit >>= PAGE_SHIFT; if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; @@ -1565,7 +1566,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns return -ENOMEM; /* Stack limit test */ - if (size > rlim[RLIMIT_STACK].rlim_cur) + if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) return -ENOMEM; /* mlock limit tests */ @@ -1573,7 +1574,8 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns unsigned long locked; unsigned long limit; locked = mm->locked_vm + grow; - limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; + limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur); + limit >>= PAGE_SHIFT; if (locked > limit && !capable(CAP_IPC_LOCK)) return -ENOMEM; } @@ -2026,7 +2028,8 @@ unsigned long do_brk(unsigned long addr, unsigned long len) unsigned long locked, lock_limit; locked = len >> PAGE_SHIFT; locked += mm->locked_vm; - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_MEMLOCK].rlim_cur); lock_limit >>= PAGE_SHIFT; if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; @@ -2240,7 +2243,8 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) unsigned long cur = mm->total_vm; /* pages */ unsigned long lim; - lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; + lim = ACCESS_ONCE(current->signal->rlim[RLIMIT_AS].rlim_cur); + lim >>= PAGE_SHIFT; if (cur + npages > lim) return 0; diff --git a/mm/mremap.c b/mm/mremap.c index 97bff25..809641b 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -358,7 +358,8 @@ unsigned long do_mremap(unsigned long addr, if (vma->vm_flags & VM_LOCKED) { unsigned long locked, lock_limit; locked = mm->locked_vm << PAGE_SHIFT; - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit = ACCESS_ONCE(current->signal-> + rlim[RLIMIT_MEMLOCK].rlim_cur); locked += new_len - old_len; ret = -EAGAIN; if (locked > lock_limit && !capable(CAP_IPC_LOCK)) -- 1.6.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/