diff options
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r-- | arch/x86_64/kernel/sys_x86_64.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index d9798dd433fc..cc7821c68851 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c | |||
@@ -105,6 +105,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
105 | (!vma || addr + len <= vma->vm_start)) | 105 | (!vma || addr + len <= vma->vm_start)) |
106 | return addr; | 106 | return addr; |
107 | } | 107 | } |
108 | if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32)) | ||
109 | && len <= mm->cached_hole_size) { | ||
110 | mm->cached_hole_size = 0; | ||
111 | mm->free_area_cache = begin; | ||
112 | } | ||
108 | addr = mm->free_area_cache; | 113 | addr = mm->free_area_cache; |
109 | if (addr < begin) | 114 | if (addr < begin) |
110 | addr = begin; | 115 | addr = begin; |
@@ -120,6 +125,7 @@ full_search: | |||
120 | */ | 125 | */ |
121 | if (start_addr != begin) { | 126 | if (start_addr != begin) { |
122 | start_addr = addr = begin; | 127 | start_addr = addr = begin; |
128 | mm->cached_hole_size = 0; | ||
123 | goto full_search; | 129 | goto full_search; |
124 | } | 130 | } |
125 | return -ENOMEM; | 131 | return -ENOMEM; |
@@ -131,6 +137,9 @@ full_search: | |||
131 | mm->free_area_cache = addr + len; | 137 | mm->free_area_cache = addr + len; |
132 | return addr; | 138 | return addr; |
133 | } | 139 | } |
140 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
141 | mm->cached_hole_size = vma->vm_start - addr; | ||
142 | |||
134 | addr = vma->vm_end; | 143 | addr = vma->vm_end; |
135 | } | 144 | } |
136 | } | 145 | } |