diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 48 |
1 files changed, 28 insertions, 20 deletions
@@ -918,7 +918,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
918 | struct inode *inode; | 918 | struct inode *inode; |
919 | unsigned int vm_flags; | 919 | unsigned int vm_flags; |
920 | int error; | 920 | int error; |
921 | int accountable = 1; | ||
922 | unsigned long reqprot = prot; | 921 | unsigned long reqprot = prot; |
923 | 922 | ||
924 | /* | 923 | /* |
@@ -1019,8 +1018,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1019 | return -EPERM; | 1018 | return -EPERM; |
1020 | vm_flags &= ~VM_MAYEXEC; | 1019 | vm_flags &= ~VM_MAYEXEC; |
1021 | } | 1020 | } |
1022 | if (is_file_hugepages(file)) | ||
1023 | accountable = 0; | ||
1024 | 1021 | ||
1025 | if (!file->f_op || !file->f_op->mmap) | 1022 | if (!file->f_op || !file->f_op->mmap) |
1026 | return -ENODEV; | 1023 | return -ENODEV; |
@@ -1053,8 +1050,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1053 | if (error) | 1050 | if (error) |
1054 | return error; | 1051 | return error; |
1055 | 1052 | ||
1056 | return mmap_region(file, addr, len, flags, vm_flags, pgoff, | 1053 | return mmap_region(file, addr, len, flags, vm_flags, pgoff); |
1057 | accountable); | ||
1058 | } | 1054 | } |
1059 | EXPORT_SYMBOL(do_mmap_pgoff); | 1055 | EXPORT_SYMBOL(do_mmap_pgoff); |
1060 | 1056 | ||
@@ -1092,17 +1088,23 @@ int vma_wants_writenotify(struct vm_area_struct *vma) | |||
1092 | 1088 | ||
1093 | /* | 1089 | /* |
1094 | * We account for memory if it's a private writeable mapping, | 1090 | * We account for memory if it's a private writeable mapping, |
1095 | * and VM_NORESERVE wasn't set. | 1091 | * not hugepages and VM_NORESERVE wasn't set. |
1096 | */ | 1092 | */ |
1097 | static inline int accountable_mapping(unsigned int vm_flags) | 1093 | static inline int accountable_mapping(struct file *file, unsigned int vm_flags) |
1098 | { | 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 | |||
1099 | return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE; | 1102 | return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE; |
1100 | } | 1103 | } |
1101 | 1104 | ||
1102 | unsigned long mmap_region(struct file *file, unsigned long addr, | 1105 | unsigned long mmap_region(struct file *file, unsigned long addr, |
1103 | unsigned long len, unsigned long flags, | 1106 | unsigned long len, unsigned long flags, |
1104 | unsigned int vm_flags, unsigned long pgoff, | 1107 | unsigned int vm_flags, unsigned long pgoff) |
1105 | int accountable) | ||
1106 | { | 1108 | { |
1107 | struct mm_struct *mm = current->mm; | 1109 | struct mm_struct *mm = current->mm; |
1108 | struct vm_area_struct *vma, *prev; | 1110 | struct vm_area_struct *vma, *prev; |
@@ -1128,18 +1130,22 @@ munmap_back: | |||
1128 | 1130 | ||
1129 | /* | 1131 | /* |
1130 | * Set 'VM_NORESERVE' if we should not account for the | 1132 | * Set 'VM_NORESERVE' if we should not account for the |
1131 | * memory use of this mapping. We only honor MAP_NORESERVE | 1133 | * memory use of this mapping. |
1132 | * if we're allowed to overcommit memory. | ||
1133 | */ | 1134 | */ |
1134 | if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER) | 1135 | if ((flags & MAP_NORESERVE)) { |
1135 | vm_flags |= VM_NORESERVE; | 1136 | /* We honor MAP_NORESERVE if allowed to overcommit */ |
1136 | if (!accountable) | 1137 | if (sysctl_overcommit_memory != OVERCOMMIT_NEVER) |
1137 | vm_flags |= VM_NORESERVE; | 1138 | vm_flags |= VM_NORESERVE; |
1139 | |||
1140 | /* hugetlb applies strict overcommit unless MAP_NORESERVE */ | ||
1141 | if (file && is_file_hugepages(file)) | ||
1142 | vm_flags |= VM_NORESERVE; | ||
1143 | } | ||
1138 | 1144 | ||
1139 | /* | 1145 | /* |
1140 | * Private writable mapping: check memory availability | 1146 | * Private writable mapping: check memory availability |
1141 | */ | 1147 | */ |
1142 | if (accountable_mapping(vm_flags)) { | 1148 | if (accountable_mapping(file, vm_flags)) { |
1143 | charged = len >> PAGE_SHIFT; | 1149 | charged = len >> PAGE_SHIFT; |
1144 | if (security_vm_enough_memory(charged)) | 1150 | if (security_vm_enough_memory(charged)) |
1145 | return -ENOMEM; | 1151 | return -ENOMEM; |
@@ -2078,12 +2084,8 @@ void exit_mmap(struct mm_struct *mm) | |||
2078 | unsigned long end; | 2084 | unsigned long end; |
2079 | 2085 | ||
2080 | /* 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 */ |
2081 | arch_exit_mmap(mm); | ||
2082 | mmu_notifier_release(mm); | 2087 | mmu_notifier_release(mm); |
2083 | 2088 | ||
2084 | if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ | ||
2085 | return; | ||
2086 | |||
2087 | if (mm->locked_vm) { | 2089 | if (mm->locked_vm) { |
2088 | vma = mm->mmap; | 2090 | vma = mm->mmap; |
2089 | while (vma) { | 2091 | while (vma) { |
@@ -2092,7 +2094,13 @@ void exit_mmap(struct mm_struct *mm) | |||
2092 | vma = vma->vm_next; | 2094 | vma = vma->vm_next; |
2093 | } | 2095 | } |
2094 | } | 2096 | } |
2097 | |||
2098 | arch_exit_mmap(mm); | ||
2099 | |||
2095 | vma = mm->mmap; | 2100 | vma = mm->mmap; |
2101 | if (!vma) /* Can happen if dup_mmap() received an OOM */ | ||
2102 | return; | ||
2103 | |||
2096 | lru_add_drain(); | 2104 | lru_add_drain(); |
2097 | flush_cache_mm(mm); | 2105 | flush_cache_mm(mm); |
2098 | tlb = tlb_gather_mmu(mm, 1); | 2106 | tlb = tlb_gather_mmu(mm, 1); |