aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 8d95902e9a38..214b6a258eeb 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -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);
665static inline int is_mergeable_vma(struct vm_area_struct *vma, 668static 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;
@@ -1087,6 +1090,15 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
1087 mapping_cap_account_dirty(vma->vm_file->f_mapping); 1090 mapping_cap_account_dirty(vma->vm_file->f_mapping);
1088} 1091}
1089 1092
1093/*
1094 * We account for memory if it's a private writeable mapping,
1095 * and VM_NORESERVE wasn't set.
1096 */
1097static inline int accountable_mapping(unsigned int vm_flags)
1098{
1099 return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
1100}
1101
1090unsigned long mmap_region(struct file *file, unsigned long addr, 1102unsigned long mmap_region(struct file *file, unsigned long addr,
1091 unsigned long len, unsigned long flags, 1103 unsigned long len, unsigned long flags,
1092 unsigned int vm_flags, unsigned long pgoff, 1104 unsigned int vm_flags, unsigned long pgoff,
@@ -1114,36 +1126,32 @@ munmap_back:
1114 if (!may_expand_vm(mm, len >> PAGE_SHIFT)) 1126 if (!may_expand_vm(mm, len >> PAGE_SHIFT))
1115 return -ENOMEM; 1127 return -ENOMEM;
1116 1128
1117 if (flags & MAP_NORESERVE) 1129 /*
1130 * Set 'VM_NORESERVE' if we should not account for the
1131 * memory use of this mapping. We only honor MAP_NORESERVE
1132 * if we're allowed to overcommit memory.
1133 */
1134 if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER)
1135 vm_flags |= VM_NORESERVE;
1136 if (!accountable)
1118 vm_flags |= VM_NORESERVE; 1137 vm_flags |= VM_NORESERVE;
1119 1138
1120 if (accountable && (!(flags & MAP_NORESERVE) || 1139 /*
1121 sysctl_overcommit_memory == OVERCOMMIT_NEVER)) { 1140 * Private writable mapping: check memory availability
1122 if (vm_flags & VM_SHARED) { 1141 */
1123 /* Check memory availability in shmem_file_setup? */ 1142 if (accountable_mapping(vm_flags)) {
1124 vm_flags |= VM_ACCOUNT; 1143 charged = len >> PAGE_SHIFT;
1125 } else if (vm_flags & VM_WRITE) { 1144 if (security_vm_enough_memory(charged))
1126 /* 1145 return -ENOMEM;
1127 * Private writable mapping: check memory availability 1146 vm_flags |= VM_ACCOUNT;
1128 */
1129 charged = len >> PAGE_SHIFT;
1130 if (security_vm_enough_memory(charged))
1131 return -ENOMEM;
1132 vm_flags |= VM_ACCOUNT;
1133 }
1134 } 1147 }
1135 1148
1136 /* 1149 /*
1137 * Can we just expand an old private anonymous mapping? 1150 * Can we just expand an old mapping?
1138 * The VM_SHARED test is necessary because shmem_zero_setup
1139 * will create the file object for a shared anonymous map below.
1140 */ 1151 */
1141 if (!file && !(vm_flags & VM_SHARED)) { 1152 vma = vma_merge(mm, prev, addr, addr + len, vm_flags, NULL, file, pgoff, NULL);
1142 vma = vma_merge(mm, prev, addr, addr + len, vm_flags, 1153 if (vma)
1143 NULL, NULL, pgoff, NULL); 1154 goto out;
1144 if (vma)
1145 goto out;
1146 }
1147 1155
1148 /* 1156 /*
1149 * Determine the object being mapped and call the appropriate 1157 * Determine the object being mapped and call the appropriate
@@ -1186,14 +1194,6 @@ munmap_back:
1186 goto free_vma; 1194 goto free_vma;
1187 } 1195 }
1188 1196
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?? 1197 /* Can addr have changed??
1198 * 1198 *
1199 * Answer: Yes, several device drivers can do it in their 1199 * Answer: Yes, several device drivers can do it in their
@@ -1206,17 +1206,8 @@ munmap_back:
1206 if (vma_wants_writenotify(vma)) 1206 if (vma_wants_writenotify(vma))
1207 vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); 1207 vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
1208 1208
1209 if (file && vma_merge(mm, prev, addr, vma->vm_end, 1209 vma_link(mm, vma, prev, rb_link, rb_parent);
1210 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { 1210 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 1211
1221 /* Once vma denies write, undo our temporary denial count */ 1212 /* Once vma denies write, undo our temporary denial count */
1222 if (correct_wcount) 1213 if (correct_wcount)