diff options
author | Davidlohr Bueso <davidlohr@hp.com> | 2014-01-21 18:49:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 19:19:44 -0500 |
commit | 363ee17f0f405faff74d9aaf93d21d5f41d5102d (patch) | |
tree | 4ff07b1b36a024b455467ac78e07fec6f18a6780 /mm/mmap.c | |
parent | 49f0ce5f92321cdcf741e35f385669a421013cb7 (diff) |
mm/mmap.c: add mlock_future_check() helper
Both do_brk and do_mmap_pgoff verify that we are actually capable of
locking future pages if the corresponding VM_LOCKED flags are used.
Encapsulate this logic into a single mlock_future_check() helper
function.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Cc: Rik van Riel <riel@redhat.com>
Reviewed-by: Michel Lespinasse <walken@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 45 |
1 files changed, 23 insertions, 22 deletions
@@ -1191,6 +1191,24 @@ static inline unsigned long round_hint_to_min(unsigned long hint) | |||
1191 | return hint; | 1191 | return hint; |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | static inline int mlock_future_check(struct mm_struct *mm, | ||
1195 | unsigned long flags, | ||
1196 | unsigned long len) | ||
1197 | { | ||
1198 | unsigned long locked, lock_limit; | ||
1199 | |||
1200 | /* mlock MCL_FUTURE? */ | ||
1201 | if (flags & VM_LOCKED) { | ||
1202 | locked = len >> PAGE_SHIFT; | ||
1203 | locked += mm->locked_vm; | ||
1204 | lock_limit = rlimit(RLIMIT_MEMLOCK); | ||
1205 | lock_limit >>= PAGE_SHIFT; | ||
1206 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | ||
1207 | return -EAGAIN; | ||
1208 | } | ||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1194 | /* | 1212 | /* |
1195 | * The caller must hold down_write(¤t->mm->mmap_sem). | 1213 | * The caller must hold down_write(¤t->mm->mmap_sem). |
1196 | */ | 1214 | */ |
@@ -1252,16 +1270,8 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1252 | if (!can_do_mlock()) | 1270 | if (!can_do_mlock()) |
1253 | return -EPERM; | 1271 | return -EPERM; |
1254 | 1272 | ||
1255 | /* mlock MCL_FUTURE? */ | 1273 | if (mlock_future_check(mm, vm_flags, len)) |
1256 | if (vm_flags & VM_LOCKED) { | 1274 | return -EAGAIN; |
1257 | unsigned long locked, lock_limit; | ||
1258 | locked = len >> PAGE_SHIFT; | ||
1259 | locked += mm->locked_vm; | ||
1260 | lock_limit = rlimit(RLIMIT_MEMLOCK); | ||
1261 | lock_limit >>= PAGE_SHIFT; | ||
1262 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | ||
1263 | return -EAGAIN; | ||
1264 | } | ||
1265 | 1275 | ||
1266 | if (file) { | 1276 | if (file) { |
1267 | struct inode *inode = file_inode(file); | 1277 | struct inode *inode = file_inode(file); |
@@ -2592,18 +2602,9 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) | |||
2592 | if (error & ~PAGE_MASK) | 2602 | if (error & ~PAGE_MASK) |
2593 | return error; | 2603 | return error; |
2594 | 2604 | ||
2595 | /* | 2605 | error = mlock_future_check(mm, mm->def_flags, len); |
2596 | * mlock MCL_FUTURE? | 2606 | if (error) |
2597 | */ | 2607 | return error; |
2598 | if (mm->def_flags & VM_LOCKED) { | ||
2599 | unsigned long locked, lock_limit; | ||
2600 | locked = len >> PAGE_SHIFT; | ||
2601 | locked += mm->locked_vm; | ||
2602 | lock_limit = rlimit(RLIMIT_MEMLOCK); | ||
2603 | lock_limit >>= PAGE_SHIFT; | ||
2604 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | ||
2605 | return -EAGAIN; | ||
2606 | } | ||
2607 | 2608 | ||
2608 | /* | 2609 | /* |
2609 | * mm->mmap_sem is required to protect against another thread | 2610 | * mm->mmap_sem is required to protect against another thread |