diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/fremap.c | 2 | ||||
-rw-r--r-- | mm/hugetlb.c | 28 | ||||
-rw-r--r-- | mm/memcontrol.c | 25 | ||||
-rw-r--r-- | mm/memory.c | 2 | ||||
-rw-r--r-- | mm/migrate.c | 2 | ||||
-rw-r--r-- | mm/mlock.c | 48 | ||||
-rw-r--r-- | mm/mmap.c | 109 | ||||
-rw-r--r-- | mm/mprotect.c | 5 | ||||
-rw-r--r-- | mm/page-writeback.c | 20 | ||||
-rw-r--r-- | mm/page_cgroup.c | 3 | ||||
-rw-r--r-- | mm/rmap.c | 3 | ||||
-rw-r--r-- | mm/shmem.c | 2 | ||||
-rw-r--r-- | mm/slub.c | 2 | ||||
-rw-r--r-- | mm/swapfile.c | 5 |
14 files changed, 139 insertions, 117 deletions
diff --git a/mm/fremap.c b/mm/fremap.c index 736ba7f3306a..b6ec85abbb39 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
@@ -198,7 +198,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
198 | flags &= MAP_NONBLOCK; | 198 | flags &= MAP_NONBLOCK; |
199 | get_file(file); | 199 | get_file(file); |
200 | addr = mmap_region(file, start, size, | 200 | addr = mmap_region(file, start, size, |
201 | flags, vma->vm_flags, pgoff, 1); | 201 | flags, vma->vm_flags, pgoff); |
202 | fput(file); | 202 | fput(file); |
203 | if (IS_ERR_VALUE(addr)) { | 203 | if (IS_ERR_VALUE(addr)) { |
204 | err = addr; | 204 | err = addr; |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 618e98304080..107da3d809a8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2269,12 +2269,18 @@ void hugetlb_change_protection(struct vm_area_struct *vma, | |||
2269 | 2269 | ||
2270 | int hugetlb_reserve_pages(struct inode *inode, | 2270 | int hugetlb_reserve_pages(struct inode *inode, |
2271 | long from, long to, | 2271 | long from, long to, |
2272 | struct vm_area_struct *vma) | 2272 | struct vm_area_struct *vma, |
2273 | int acctflag) | ||
2273 | { | 2274 | { |
2274 | long ret, chg; | 2275 | long ret, chg; |
2275 | struct hstate *h = hstate_inode(inode); | 2276 | struct hstate *h = hstate_inode(inode); |
2276 | 2277 | ||
2277 | if (vma && vma->vm_flags & VM_NORESERVE) | 2278 | /* |
2279 | * Only apply hugepage reservation if asked. At fault time, an | ||
2280 | * attempt will be made for VM_NORESERVE to allocate a page | ||
2281 | * and filesystem quota without using reserves | ||
2282 | */ | ||
2283 | if (acctflag & VM_NORESERVE) | ||
2278 | return 0; | 2284 | return 0; |
2279 | 2285 | ||
2280 | /* | 2286 | /* |
@@ -2299,13 +2305,31 @@ int hugetlb_reserve_pages(struct inode *inode, | |||
2299 | if (chg < 0) | 2305 | if (chg < 0) |
2300 | return chg; | 2306 | return chg; |
2301 | 2307 | ||
2308 | /* There must be enough filesystem quota for the mapping */ | ||
2302 | if (hugetlb_get_quota(inode->i_mapping, chg)) | 2309 | if (hugetlb_get_quota(inode->i_mapping, chg)) |
2303 | return -ENOSPC; | 2310 | return -ENOSPC; |
2311 | |||
2312 | /* | ||
2313 | * Check enough hugepages are available for the reservation. | ||
2314 | * Hand back the quota if there are not | ||
2315 | */ | ||
2304 | ret = hugetlb_acct_memory(h, chg); | 2316 | ret = hugetlb_acct_memory(h, chg); |
2305 | if (ret < 0) { | 2317 | if (ret < 0) { |
2306 | hugetlb_put_quota(inode->i_mapping, chg); | 2318 | hugetlb_put_quota(inode->i_mapping, chg); |
2307 | return ret; | 2319 | return ret; |
2308 | } | 2320 | } |
2321 | |||
2322 | /* | ||
2323 | * Account for the reservations made. Shared mappings record regions | ||
2324 | * that have reservations as they are shared by multiple VMAs. | ||
2325 | * When the last VMA disappears, the region map says how much | ||
2326 | * the reservation was and the page cache tells how much of | ||
2327 | * the reservation was consumed. Private mappings are per-VMA and | ||
2328 | * only the consumed reservations are tracked. When the VMA | ||
2329 | * disappears, the original reservation is the VMA size and the | ||
2330 | * consumed reservations are stored in the map. Hence, nothing | ||
2331 | * else has to be done for private mappings here | ||
2332 | */ | ||
2309 | if (!vma || vma->vm_flags & VM_SHARED) | 2333 | if (!vma || vma->vm_flags & VM_SHARED) |
2310 | region_add(&inode->i_mapping->private_list, from, to); | 2334 | region_add(&inode->i_mapping->private_list, from, to); |
2311 | return 0; | 2335 | return 0; |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 4d0ea3ceba6d..8e4be9cb2a6a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -202,6 +202,7 @@ pcg_default_flags[NR_CHARGE_TYPE] = { | |||
202 | 202 | ||
203 | static void mem_cgroup_get(struct mem_cgroup *mem); | 203 | static void mem_cgroup_get(struct mem_cgroup *mem); |
204 | static void mem_cgroup_put(struct mem_cgroup *mem); | 204 | static void mem_cgroup_put(struct mem_cgroup *mem); |
205 | static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem); | ||
205 | 206 | ||
206 | static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, | 207 | static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, |
207 | struct page_cgroup *pc, | 208 | struct page_cgroup *pc, |
@@ -1684,7 +1685,7 @@ move_account: | |||
1684 | /* This is for making all *used* pages to be on LRU. */ | 1685 | /* This is for making all *used* pages to be on LRU. */ |
1685 | lru_add_drain_all(); | 1686 | lru_add_drain_all(); |
1686 | ret = 0; | 1687 | ret = 0; |
1687 | for_each_node_state(node, N_POSSIBLE) { | 1688 | for_each_node_state(node, N_HIGH_MEMORY) { |
1688 | for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) { | 1689 | for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) { |
1689 | enum lru_list l; | 1690 | enum lru_list l; |
1690 | for_each_lru(l) { | 1691 | for_each_lru(l) { |
@@ -2193,10 +2194,23 @@ static void mem_cgroup_get(struct mem_cgroup *mem) | |||
2193 | 2194 | ||
2194 | static void mem_cgroup_put(struct mem_cgroup *mem) | 2195 | static void mem_cgroup_put(struct mem_cgroup *mem) |
2195 | { | 2196 | { |
2196 | if (atomic_dec_and_test(&mem->refcnt)) | 2197 | if (atomic_dec_and_test(&mem->refcnt)) { |
2198 | struct mem_cgroup *parent = parent_mem_cgroup(mem); | ||
2197 | __mem_cgroup_free(mem); | 2199 | __mem_cgroup_free(mem); |
2200 | if (parent) | ||
2201 | mem_cgroup_put(parent); | ||
2202 | } | ||
2198 | } | 2203 | } |
2199 | 2204 | ||
2205 | /* | ||
2206 | * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. | ||
2207 | */ | ||
2208 | static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem) | ||
2209 | { | ||
2210 | if (!mem->res.parent) | ||
2211 | return NULL; | ||
2212 | return mem_cgroup_from_res_counter(mem->res.parent, res); | ||
2213 | } | ||
2200 | 2214 | ||
2201 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP | 2215 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP |
2202 | static void __init enable_swap_cgroup(void) | 2216 | static void __init enable_swap_cgroup(void) |
@@ -2235,6 +2249,13 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | |||
2235 | if (parent && parent->use_hierarchy) { | 2249 | if (parent && parent->use_hierarchy) { |
2236 | res_counter_init(&mem->res, &parent->res); | 2250 | res_counter_init(&mem->res, &parent->res); |
2237 | res_counter_init(&mem->memsw, &parent->memsw); | 2251 | res_counter_init(&mem->memsw, &parent->memsw); |
2252 | /* | ||
2253 | * We increment refcnt of the parent to ensure that we can | ||
2254 | * safely access it on res_counter_charge/uncharge. | ||
2255 | * This refcnt will be decremented when freeing this | ||
2256 | * mem_cgroup(see mem_cgroup_put). | ||
2257 | */ | ||
2258 | mem_cgroup_get(parent); | ||
2238 | } else { | 2259 | } else { |
2239 | res_counter_init(&mem->res, NULL); | 2260 | res_counter_init(&mem->res, NULL); |
2240 | res_counter_init(&mem->memsw, NULL); | 2261 | res_counter_init(&mem->memsw, NULL); |
diff --git a/mm/memory.c b/mm/memory.c index 22bfa7a47a0b..baa999e87cd2 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1999,7 +1999,7 @@ gotten: | |||
1999 | * Don't let another task, with possibly unlocked vma, | 1999 | * Don't let another task, with possibly unlocked vma, |
2000 | * keep the mlocked page. | 2000 | * keep the mlocked page. |
2001 | */ | 2001 | */ |
2002 | if (vma->vm_flags & VM_LOCKED) { | 2002 | if ((vma->vm_flags & VM_LOCKED) && old_page) { |
2003 | lock_page(old_page); /* for LRU manipulation */ | 2003 | lock_page(old_page); /* for LRU manipulation */ |
2004 | clear_page_mlock(old_page); | 2004 | clear_page_mlock(old_page); |
2005 | unlock_page(old_page); | 2005 | unlock_page(old_page); |
diff --git a/mm/migrate.c b/mm/migrate.c index 2bb4e1d63520..a9eff3f092f6 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -1129,7 +1129,7 @@ int migrate_vmas(struct mm_struct *mm, const nodemask_t *to, | |||
1129 | struct vm_area_struct *vma; | 1129 | struct vm_area_struct *vma; |
1130 | int err = 0; | 1130 | int err = 0; |
1131 | 1131 | ||
1132 | for(vma = mm->mmap; vma->vm_next && !err; vma = vma->vm_next) { | 1132 | for (vma = mm->mmap; vma && !err; vma = vma->vm_next) { |
1133 | if (vma->vm_ops && vma->vm_ops->migrate) { | 1133 | if (vma->vm_ops && vma->vm_ops->migrate) { |
1134 | err = vma->vm_ops->migrate(vma, to, from, flags); | 1134 | err = vma->vm_ops->migrate(vma, to, from, flags); |
1135 | if (err) | 1135 | if (err) |
diff --git a/mm/mlock.c b/mm/mlock.c index 2904a347e476..037161d61b4e 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -294,14 +294,10 @@ static inline int __mlock_posix_error_return(long retval) | |||
294 | * | 294 | * |
295 | * return number of pages [> 0] to be removed from locked_vm on success | 295 | * return number of pages [> 0] to be removed from locked_vm on success |
296 | * of "special" vmas. | 296 | * of "special" vmas. |
297 | * | ||
298 | * return negative error if vma spanning @start-@range disappears while | ||
299 | * mmap semaphore is dropped. Unlikely? | ||
300 | */ | 297 | */ |
301 | long mlock_vma_pages_range(struct vm_area_struct *vma, | 298 | long mlock_vma_pages_range(struct vm_area_struct *vma, |
302 | unsigned long start, unsigned long end) | 299 | unsigned long start, unsigned long end) |
303 | { | 300 | { |
304 | struct mm_struct *mm = vma->vm_mm; | ||
305 | int nr_pages = (end - start) / PAGE_SIZE; | 301 | int nr_pages = (end - start) / PAGE_SIZE; |
306 | BUG_ON(!(vma->vm_flags & VM_LOCKED)); | 302 | BUG_ON(!(vma->vm_flags & VM_LOCKED)); |
307 | 303 | ||
@@ -314,20 +310,11 @@ long mlock_vma_pages_range(struct vm_area_struct *vma, | |||
314 | if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) || | 310 | if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) || |
315 | is_vm_hugetlb_page(vma) || | 311 | is_vm_hugetlb_page(vma) || |
316 | vma == get_gate_vma(current))) { | 312 | vma == get_gate_vma(current))) { |
317 | long error; | ||
318 | downgrade_write(&mm->mmap_sem); | ||
319 | |||
320 | error = __mlock_vma_pages_range(vma, start, end, 1); | ||
321 | 313 | ||
322 | up_read(&mm->mmap_sem); | 314 | __mlock_vma_pages_range(vma, start, end, 1); |
323 | /* vma can change or disappear */ | ||
324 | down_write(&mm->mmap_sem); | ||
325 | vma = find_vma(mm, start); | ||
326 | /* non-NULL vma must contain @start, but need to check @end */ | ||
327 | if (!vma || end > vma->vm_end) | ||
328 | return -ENOMEM; | ||
329 | 315 | ||
330 | return 0; /* hide other errors from mmap(), et al */ | 316 | /* Hide errors from mmap() and other callers */ |
317 | return 0; | ||
331 | } | 318 | } |
332 | 319 | ||
333 | /* | 320 | /* |
@@ -438,41 +425,14 @@ success: | |||
438 | vma->vm_flags = newflags; | 425 | vma->vm_flags = newflags; |
439 | 426 | ||
440 | if (lock) { | 427 | if (lock) { |
441 | /* | ||
442 | * mmap_sem is currently held for write. Downgrade the write | ||
443 | * lock to a read lock so that other faults, mmap scans, ... | ||
444 | * while we fault in all pages. | ||
445 | */ | ||
446 | downgrade_write(&mm->mmap_sem); | ||
447 | |||
448 | ret = __mlock_vma_pages_range(vma, start, end, 1); | 428 | ret = __mlock_vma_pages_range(vma, start, end, 1); |
449 | 429 | ||
450 | /* | 430 | if (ret > 0) { |
451 | * Need to reacquire mmap sem in write mode, as our callers | ||
452 | * expect this. We have no support for atomically upgrading | ||
453 | * a sem to write, so we need to check for ranges while sem | ||
454 | * is unlocked. | ||
455 | */ | ||
456 | up_read(&mm->mmap_sem); | ||
457 | /* vma can change or disappear */ | ||
458 | down_write(&mm->mmap_sem); | ||
459 | *prev = find_vma(mm, start); | ||
460 | /* non-NULL *prev must contain @start, but need to check @end */ | ||
461 | if (!(*prev) || end > (*prev)->vm_end) | ||
462 | ret = -ENOMEM; | ||
463 | else if (ret > 0) { | ||
464 | mm->locked_vm -= ret; | 431 | mm->locked_vm -= ret; |
465 | ret = 0; | 432 | ret = 0; |
466 | } else | 433 | } else |
467 | ret = __mlock_posix_error_return(ret); /* translate if needed */ | 434 | ret = __mlock_posix_error_return(ret); /* translate if needed */ |
468 | } else { | 435 | } else { |
469 | /* | ||
470 | * TODO: for unlocking, pages will already be resident, so | ||
471 | * we don't need to wait for allocations/reclaim/pagein, ... | ||
472 | * However, unlocking a very large region can still take a | ||
473 | * while. Should we downgrade the semaphore for both lock | ||
474 | * AND unlock ? | ||
475 | */ | ||
476 | __mlock_vma_pages_range(vma, start, end, 0); | 436 | __mlock_vma_pages_range(vma, start, end, 0); |
477 | } | 437 | } |
478 | 438 | ||
@@ -658,6 +658,9 @@ again: remove_next = 1 + (end > next->vm_end); | |||
658 | validate_mm(mm); | 658 | validate_mm(mm); |
659 | } | 659 | } |
660 | 660 | ||
661 | /* Flags that can be inherited from an existing mapping when merging */ | ||
662 | #define VM_MERGEABLE_FLAGS (VM_CAN_NONLINEAR) | ||
663 | |||
661 | /* | 664 | /* |
662 | * If the vma has a ->close operation then the driver probably needs to release | 665 | * If the vma has a ->close operation then the driver probably needs to release |
663 | * per-vma resources, so we don't attempt to merge those. | 666 | * per-vma resources, so we don't attempt to merge those. |
@@ -665,7 +668,7 @@ again: remove_next = 1 + (end > next->vm_end); | |||
665 | static inline int is_mergeable_vma(struct vm_area_struct *vma, | 668 | static inline int is_mergeable_vma(struct vm_area_struct *vma, |
666 | struct file *file, unsigned long vm_flags) | 669 | struct file *file, unsigned long vm_flags) |
667 | { | 670 | { |
668 | if (vma->vm_flags != vm_flags) | 671 | if ((vma->vm_flags ^ vm_flags) & ~VM_MERGEABLE_FLAGS) |
669 | return 0; | 672 | return 0; |
670 | if (vma->vm_file != file) | 673 | if (vma->vm_file != file) |
671 | return 0; | 674 | return 0; |
@@ -915,7 +918,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
915 | struct inode *inode; | 918 | struct inode *inode; |
916 | unsigned int vm_flags; | 919 | unsigned int vm_flags; |
917 | int error; | 920 | int error; |
918 | int accountable = 1; | ||
919 | unsigned long reqprot = prot; | 921 | unsigned long reqprot = prot; |
920 | 922 | ||
921 | /* | 923 | /* |
@@ -1016,8 +1018,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1016 | return -EPERM; | 1018 | return -EPERM; |
1017 | vm_flags &= ~VM_MAYEXEC; | 1019 | vm_flags &= ~VM_MAYEXEC; |
1018 | } | 1020 | } |
1019 | if (is_file_hugepages(file)) | ||
1020 | accountable = 0; | ||
1021 | 1021 | ||
1022 | if (!file->f_op || !file->f_op->mmap) | 1022 | if (!file->f_op || !file->f_op->mmap) |
1023 | return -ENODEV; | 1023 | return -ENODEV; |
@@ -1050,8 +1050,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1050 | if (error) | 1050 | if (error) |
1051 | return error; | 1051 | return error; |
1052 | 1052 | ||
1053 | return mmap_region(file, addr, len, flags, vm_flags, pgoff, | 1053 | return mmap_region(file, addr, len, flags, vm_flags, pgoff); |
1054 | accountable); | ||
1055 | } | 1054 | } |
1056 | EXPORT_SYMBOL(do_mmap_pgoff); | 1055 | EXPORT_SYMBOL(do_mmap_pgoff); |
1057 | 1056 | ||
@@ -1087,10 +1086,25 @@ int vma_wants_writenotify(struct vm_area_struct *vma) | |||
1087 | mapping_cap_account_dirty(vma->vm_file->f_mapping); | 1086 | mapping_cap_account_dirty(vma->vm_file->f_mapping); |
1088 | } | 1087 | } |
1089 | 1088 | ||
1089 | /* | ||
1090 | * We account for memory if it's a private writeable mapping, | ||
1091 | * not hugepages and VM_NORESERVE wasn't set. | ||
1092 | */ | ||
1093 | static inline int accountable_mapping(struct file *file, unsigned int vm_flags) | ||
1094 | { | ||
1095 | /* | ||
1096 | * hugetlb has its own accounting separate from the core VM | ||
1097 | * VM_HUGETLB may not be set yet so we cannot check for that flag. | ||
1098 | */ | ||
1099 | if (file && is_file_hugepages(file)) | ||
1100 | return 0; | ||
1101 | |||
1102 | return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE; | ||
1103 | } | ||
1104 | |||
1090 | unsigned long mmap_region(struct file *file, unsigned long addr, | 1105 | unsigned long mmap_region(struct file *file, unsigned long addr, |
1091 | unsigned long len, unsigned long flags, | 1106 | unsigned long len, unsigned long flags, |
1092 | unsigned int vm_flags, unsigned long pgoff, | 1107 | unsigned int vm_flags, unsigned long pgoff) |
1093 | int accountable) | ||
1094 | { | 1108 | { |
1095 | struct mm_struct *mm = current->mm; | 1109 | struct mm_struct *mm = current->mm; |
1096 | struct vm_area_struct *vma, *prev; | 1110 | struct vm_area_struct *vma, *prev; |
@@ -1114,38 +1128,38 @@ munmap_back: | |||
1114 | if (!may_expand_vm(mm, len >> PAGE_SHIFT)) | 1128 | if (!may_expand_vm(mm, len >> PAGE_SHIFT)) |
1115 | return -ENOMEM; | 1129 | return -ENOMEM; |
1116 | 1130 | ||
1117 | if (flags & MAP_NORESERVE) | 1131 | /* |
1118 | vm_flags |= VM_NORESERVE; | 1132 | * Set 'VM_NORESERVE' if we should not account for the |
1133 | * memory use of this mapping. | ||
1134 | */ | ||
1135 | if ((flags & MAP_NORESERVE)) { | ||
1136 | /* We honor MAP_NORESERVE if allowed to overcommit */ | ||
1137 | if (sysctl_overcommit_memory != OVERCOMMIT_NEVER) | ||
1138 | vm_flags |= VM_NORESERVE; | ||
1119 | 1139 | ||
1120 | if (accountable && (!(flags & MAP_NORESERVE) || | 1140 | /* hugetlb applies strict overcommit unless MAP_NORESERVE */ |
1121 | sysctl_overcommit_memory == OVERCOMMIT_NEVER)) { | 1141 | if (file && is_file_hugepages(file)) |
1122 | if (vm_flags & VM_SHARED) { | 1142 | vm_flags |= VM_NORESERVE; |
1123 | /* Check memory availability in shmem_file_setup? */ | ||
1124 | vm_flags |= VM_ACCOUNT; | ||
1125 | } else if (vm_flags & VM_WRITE) { | ||
1126 | /* | ||
1127 | * Private writable mapping: check memory availability | ||
1128 | */ | ||
1129 | charged = len >> PAGE_SHIFT; | ||
1130 | if (security_vm_enough_memory(charged)) | ||
1131 | return -ENOMEM; | ||
1132 | vm_flags |= VM_ACCOUNT; | ||
1133 | } | ||
1134 | } | 1143 | } |
1135 | 1144 | ||
1136 | /* | 1145 | /* |
1137 | * Can we just expand an old private anonymous mapping? | 1146 | * Private writable mapping: check memory availability |
1138 | * The VM_SHARED test is necessary because shmem_zero_setup | ||
1139 | * will create the file object for a shared anonymous map below. | ||
1140 | */ | 1147 | */ |
1141 | if (!file && !(vm_flags & VM_SHARED)) { | 1148 | if (accountable_mapping(file, vm_flags)) { |
1142 | vma = vma_merge(mm, prev, addr, addr + len, vm_flags, | 1149 | charged = len >> PAGE_SHIFT; |
1143 | NULL, NULL, pgoff, NULL); | 1150 | if (security_vm_enough_memory(charged)) |
1144 | if (vma) | 1151 | return -ENOMEM; |
1145 | goto out; | 1152 | vm_flags |= VM_ACCOUNT; |
1146 | } | 1153 | } |
1147 | 1154 | ||
1148 | /* | 1155 | /* |
1156 | * Can we just expand an old mapping? | ||
1157 | */ | ||
1158 | vma = vma_merge(mm, prev, addr, addr + len, vm_flags, NULL, file, pgoff, NULL); | ||
1159 | if (vma) | ||
1160 | goto out; | ||
1161 | |||
1162 | /* | ||
1149 | * Determine the object being mapped and call the appropriate | 1163 | * Determine the object being mapped and call the appropriate |
1150 | * specific mapper. the address has already been validated, but | 1164 | * specific mapper. the address has already been validated, but |
1151 | * not unmapped, but the maps are removed from the list. | 1165 | * not unmapped, but the maps are removed from the list. |
@@ -1186,14 +1200,6 @@ munmap_back: | |||
1186 | goto free_vma; | 1200 | goto free_vma; |
1187 | } | 1201 | } |
1188 | 1202 | ||
1189 | /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform | ||
1190 | * shmem_zero_setup (perhaps called through /dev/zero's ->mmap) | ||
1191 | * that memory reservation must be checked; but that reservation | ||
1192 | * belongs to shared memory object, not to vma: so now clear it. | ||
1193 | */ | ||
1194 | if ((vm_flags & (VM_SHARED|VM_ACCOUNT)) == (VM_SHARED|VM_ACCOUNT)) | ||
1195 | vma->vm_flags &= ~VM_ACCOUNT; | ||
1196 | |||
1197 | /* Can addr have changed?? | 1203 | /* Can addr have changed?? |
1198 | * | 1204 | * |
1199 | * Answer: Yes, several device drivers can do it in their | 1205 | * Answer: Yes, several device drivers can do it in their |
@@ -1206,17 +1212,8 @@ munmap_back: | |||
1206 | if (vma_wants_writenotify(vma)) | 1212 | if (vma_wants_writenotify(vma)) |
1207 | vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); | 1213 | vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); |
1208 | 1214 | ||
1209 | if (file && vma_merge(mm, prev, addr, vma->vm_end, | 1215 | vma_link(mm, vma, prev, rb_link, rb_parent); |
1210 | vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { | 1216 | file = vma->vm_file; |
1211 | mpol_put(vma_policy(vma)); | ||
1212 | kmem_cache_free(vm_area_cachep, vma); | ||
1213 | fput(file); | ||
1214 | if (vm_flags & VM_EXECUTABLE) | ||
1215 | removed_exe_file_vma(mm); | ||
1216 | } else { | ||
1217 | vma_link(mm, vma, prev, rb_link, rb_parent); | ||
1218 | file = vma->vm_file; | ||
1219 | } | ||
1220 | 1217 | ||
1221 | /* Once vma denies write, undo our temporary denial count */ | 1218 | /* Once vma denies write, undo our temporary denial count */ |
1222 | if (correct_wcount) | 1219 | if (correct_wcount) |
@@ -2087,12 +2084,8 @@ void exit_mmap(struct mm_struct *mm) | |||
2087 | unsigned long end; | 2084 | unsigned long end; |
2088 | 2085 | ||
2089 | /* mm's last user has gone, and its about to be pulled down */ | 2086 | /* mm's last user has gone, and its about to be pulled down */ |
2090 | arch_exit_mmap(mm); | ||
2091 | mmu_notifier_release(mm); | 2087 | mmu_notifier_release(mm); |
2092 | 2088 | ||
2093 | if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ | ||
2094 | return; | ||
2095 | |||
2096 | if (mm->locked_vm) { | 2089 | if (mm->locked_vm) { |
2097 | vma = mm->mmap; | 2090 | vma = mm->mmap; |
2098 | while (vma) { | 2091 | while (vma) { |
@@ -2101,7 +2094,13 @@ void exit_mmap(struct mm_struct *mm) | |||
2101 | vma = vma->vm_next; | 2094 | vma = vma->vm_next; |
2102 | } | 2095 | } |
2103 | } | 2096 | } |
2097 | |||
2098 | arch_exit_mmap(mm); | ||
2099 | |||
2104 | vma = mm->mmap; | 2100 | vma = mm->mmap; |
2101 | if (!vma) /* Can happen if dup_mmap() received an OOM */ | ||
2102 | return; | ||
2103 | |||
2105 | lru_add_drain(); | 2104 | lru_add_drain(); |
2106 | flush_cache_mm(mm); | 2105 | flush_cache_mm(mm); |
2107 | tlb = tlb_gather_mmu(mm, 1); | 2106 | tlb = tlb_gather_mmu(mm, 1); |
diff --git a/mm/mprotect.c b/mm/mprotect.c index abe2694e13f4..258197b76fb4 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -151,10 +151,11 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, | |||
151 | /* | 151 | /* |
152 | * If we make a private mapping writable we increase our commit; | 152 | * If we make a private mapping writable we increase our commit; |
153 | * but (without finer accounting) cannot reduce our commit if we | 153 | * but (without finer accounting) cannot reduce our commit if we |
154 | * make it unwritable again. | 154 | * make it unwritable again. hugetlb mapping were accounted for |
155 | * even if read-only so there is no need to account for them here | ||
155 | */ | 156 | */ |
156 | if (newflags & VM_WRITE) { | 157 | if (newflags & VM_WRITE) { |
157 | if (!(oldflags & (VM_ACCOUNT|VM_WRITE| | 158 | if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| |
158 | VM_SHARED|VM_NORESERVE))) { | 159 | VM_SHARED|VM_NORESERVE))) { |
159 | charged = nrpages; | 160 | charged = nrpages; |
160 | if (security_vm_enough_memory(charged)) | 161 | if (security_vm_enough_memory(charged)) |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b493db7841dc..6106a5c7ed44 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -209,7 +209,7 @@ int dirty_bytes_handler(struct ctl_table *table, int write, | |||
209 | struct file *filp, void __user *buffer, size_t *lenp, | 209 | struct file *filp, void __user *buffer, size_t *lenp, |
210 | loff_t *ppos) | 210 | loff_t *ppos) |
211 | { | 211 | { |
212 | int old_bytes = vm_dirty_bytes; | 212 | unsigned long old_bytes = vm_dirty_bytes; |
213 | int ret; | 213 | int ret; |
214 | 214 | ||
215 | ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); | 215 | ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); |
@@ -1051,13 +1051,25 @@ continue_unlock: | |||
1051 | } | 1051 | } |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | if (wbc->sync_mode == WB_SYNC_NONE) { | 1054 | if (nr_to_write > 0) { |
1055 | wbc->nr_to_write--; | 1055 | nr_to_write--; |
1056 | if (wbc->nr_to_write <= 0) { | 1056 | if (nr_to_write == 0 && |
1057 | wbc->sync_mode == WB_SYNC_NONE) { | ||
1058 | /* | ||
1059 | * We stop writing back only if we are | ||
1060 | * not doing integrity sync. In case of | ||
1061 | * integrity sync we have to keep going | ||
1062 | * because someone may be concurrently | ||
1063 | * dirtying pages, and we might have | ||
1064 | * synced a lot of newly appeared dirty | ||
1065 | * pages, but have not synced all of the | ||
1066 | * old dirty pages. | ||
1067 | */ | ||
1057 | done = 1; | 1068 | done = 1; |
1058 | break; | 1069 | break; |
1059 | } | 1070 | } |
1060 | } | 1071 | } |
1072 | |||
1061 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 1073 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
1062 | wbc->encountered_congestion = 1; | 1074 | wbc->encountered_congestion = 1; |
1063 | done = 1; | 1075 | done = 1; |
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 7006a11350c8..ceecfbb143fa 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c | |||
@@ -114,7 +114,8 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn) | |||
114 | nid = page_to_nid(pfn_to_page(pfn)); | 114 | nid = page_to_nid(pfn_to_page(pfn)); |
115 | table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; | 115 | table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; |
116 | if (slab_is_available()) { | 116 | if (slab_is_available()) { |
117 | base = kmalloc_node(table_size, GFP_KERNEL, nid); | 117 | base = kmalloc_node(table_size, |
118 | GFP_KERNEL | __GFP_NOWARN, nid); | ||
118 | if (!base) | 119 | if (!base) |
119 | base = vmalloc_node(table_size, nid); | 120 | base = vmalloc_node(table_size, nid); |
120 | } else { | 121 | } else { |
@@ -1072,7 +1072,8 @@ static int try_to_unmap_file(struct page *page, int unlock, int migration) | |||
1072 | spin_lock(&mapping->i_mmap_lock); | 1072 | spin_lock(&mapping->i_mmap_lock); |
1073 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 1073 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { |
1074 | if (MLOCK_PAGES && unlikely(unlock)) { | 1074 | if (MLOCK_PAGES && unlikely(unlock)) { |
1075 | if (!(vma->vm_flags & VM_LOCKED)) | 1075 | if (!((vma->vm_flags & VM_LOCKED) && |
1076 | page_mapped_in_vma(page, vma))) | ||
1076 | continue; /* must visit all vmas */ | 1077 | continue; /* must visit all vmas */ |
1077 | ret = SWAP_MLOCK; | 1078 | ret = SWAP_MLOCK; |
1078 | } else { | 1079 | } else { |
diff --git a/mm/shmem.c b/mm/shmem.c index 5d0de96c9789..19d566ccdeea 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2628,7 +2628,7 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) | |||
2628 | goto close_file; | 2628 | goto close_file; |
2629 | 2629 | ||
2630 | #ifdef CONFIG_SHMEM | 2630 | #ifdef CONFIG_SHMEM |
2631 | SHMEM_I(inode)->flags = flags & VM_ACCOUNT; | 2631 | SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT; |
2632 | #endif | 2632 | #endif |
2633 | d_instantiate(dentry, inode); | 2633 | d_instantiate(dentry, inode); |
2634 | inode->i_size = size; | 2634 | inode->i_size = size; |
@@ -1996,7 +1996,7 @@ static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s, | |||
1996 | static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu) | 1996 | static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu) |
1997 | { | 1997 | { |
1998 | if (c < per_cpu(kmem_cache_cpu, cpu) || | 1998 | if (c < per_cpu(kmem_cache_cpu, cpu) || |
1999 | c > per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) { | 1999 | c >= per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) { |
2000 | kfree(c); | 2000 | kfree(c); |
2001 | return; | 2001 | return; |
2002 | } | 2002 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index f48b831e5e5c..7e6304dfafab 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -698,8 +698,10 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, | |||
698 | pte_t *pte; | 698 | pte_t *pte; |
699 | int ret = 1; | 699 | int ret = 1; |
700 | 700 | ||
701 | if (mem_cgroup_try_charge_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) | 701 | if (mem_cgroup_try_charge_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) { |
702 | ret = -ENOMEM; | 702 | ret = -ENOMEM; |
703 | goto out_nolock; | ||
704 | } | ||
703 | 705 | ||
704 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); | 706 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
705 | if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) { | 707 | if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) { |
@@ -723,6 +725,7 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, | |||
723 | activate_page(page); | 725 | activate_page(page); |
724 | out: | 726 | out: |
725 | pte_unmap_unlock(pte, ptl); | 727 | pte_unmap_unlock(pte, ptl); |
728 | out_nolock: | ||
726 | return ret; | 729 | return ret; |
727 | } | 730 | } |
728 | 731 | ||