diff options
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 4fa8d84599b0..7ba11e12a11f 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -1259,6 +1259,12 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
1259 | return false; | 1259 | return false; |
1260 | 1260 | ||
1261 | /* | 1261 | /* |
1262 | * First make sure the mappings are removed from all page-tables | ||
1263 | * before they are freed. | ||
1264 | */ | ||
1265 | vmalloc_sync_all(); | ||
1266 | |||
1267 | /* | ||
1262 | * TODO: to calculate a flush range without looping. | 1268 | * TODO: to calculate a flush range without looping. |
1263 | * The list can be up to lazy_max_pages() elements. | 1269 | * The list can be up to lazy_max_pages() elements. |
1264 | */ | 1270 | */ |
@@ -3038,6 +3044,9 @@ EXPORT_SYMBOL(remap_vmalloc_range); | |||
3038 | /* | 3044 | /* |
3039 | * Implement a stub for vmalloc_sync_all() if the architecture chose not to | 3045 | * Implement a stub for vmalloc_sync_all() if the architecture chose not to |
3040 | * have one. | 3046 | * have one. |
3047 | * | ||
3048 | * The purpose of this function is to make sure the vmalloc area | ||
3049 | * mappings are identical in all page-tables in the system. | ||
3041 | */ | 3050 | */ |
3042 | void __weak vmalloc_sync_all(void) | 3051 | void __weak vmalloc_sync_all(void) |
3043 | { | 3052 | { |
@@ -3270,9 +3279,19 @@ retry: | |||
3270 | goto overflow; | 3279 | goto overflow; |
3271 | 3280 | ||
3272 | /* | 3281 | /* |
3282 | * If required width exeeds current VA block, move | ||
3283 | * base downwards and then recheck. | ||
3284 | */ | ||
3285 | if (base + end > va->va_end) { | ||
3286 | base = pvm_determine_end_from_reverse(&va, align) - end; | ||
3287 | term_area = area; | ||
3288 | continue; | ||
3289 | } | ||
3290 | |||
3291 | /* | ||
3273 | * If this VA does not fit, move base downwards and recheck. | 3292 | * If this VA does not fit, move base downwards and recheck. |
3274 | */ | 3293 | */ |
3275 | if (base + start < va->va_start || base + end > va->va_end) { | 3294 | if (base + start < va->va_start) { |
3276 | va = node_to_va(rb_prev(&va->rb_node)); | 3295 | va = node_to_va(rb_prev(&va->rb_node)); |
3277 | base = pvm_determine_end_from_reverse(&va, align) - end; | 3296 | base = pvm_determine_end_from_reverse(&va, align) - end; |
3278 | term_area = area; | 3297 | term_area = area; |