diff options
Diffstat (limited to 'mm/compaction.c')
| -rw-r--r-- | mm/compaction.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index b48c5259ea33..918577595ea8 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
| @@ -251,7 +251,6 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
| 251 | { | 251 | { |
| 252 | int nr_scanned = 0, total_isolated = 0; | 252 | int nr_scanned = 0, total_isolated = 0; |
| 253 | struct page *cursor, *valid_page = NULL; | 253 | struct page *cursor, *valid_page = NULL; |
| 254 | unsigned long nr_strict_required = end_pfn - blockpfn; | ||
| 255 | unsigned long flags; | 254 | unsigned long flags; |
| 256 | bool locked = false; | 255 | bool locked = false; |
| 257 | 256 | ||
| @@ -264,11 +263,12 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
| 264 | 263 | ||
| 265 | nr_scanned++; | 264 | nr_scanned++; |
| 266 | if (!pfn_valid_within(blockpfn)) | 265 | if (!pfn_valid_within(blockpfn)) |
| 267 | continue; | 266 | goto isolate_fail; |
| 267 | |||
| 268 | if (!valid_page) | 268 | if (!valid_page) |
| 269 | valid_page = page; | 269 | valid_page = page; |
| 270 | if (!PageBuddy(page)) | 270 | if (!PageBuddy(page)) |
| 271 | continue; | 271 | goto isolate_fail; |
| 272 | 272 | ||
| 273 | /* | 273 | /* |
| 274 | * The zone lock must be held to isolate freepages. | 274 | * The zone lock must be held to isolate freepages. |
| @@ -289,12 +289,10 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
| 289 | 289 | ||
| 290 | /* Recheck this is a buddy page under lock */ | 290 | /* Recheck this is a buddy page under lock */ |
| 291 | if (!PageBuddy(page)) | 291 | if (!PageBuddy(page)) |
| 292 | continue; | 292 | goto isolate_fail; |
| 293 | 293 | ||
| 294 | /* Found a free page, break it into order-0 pages */ | 294 | /* Found a free page, break it into order-0 pages */ |
| 295 | isolated = split_free_page(page); | 295 | isolated = split_free_page(page); |
| 296 | if (!isolated && strict) | ||
| 297 | break; | ||
| 298 | total_isolated += isolated; | 296 | total_isolated += isolated; |
| 299 | for (i = 0; i < isolated; i++) { | 297 | for (i = 0; i < isolated; i++) { |
| 300 | list_add(&page->lru, freelist); | 298 | list_add(&page->lru, freelist); |
| @@ -305,7 +303,15 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
| 305 | if (isolated) { | 303 | if (isolated) { |
| 306 | blockpfn += isolated - 1; | 304 | blockpfn += isolated - 1; |
| 307 | cursor += isolated - 1; | 305 | cursor += isolated - 1; |
| 306 | continue; | ||
| 308 | } | 307 | } |
| 308 | |||
| 309 | isolate_fail: | ||
| 310 | if (strict) | ||
| 311 | break; | ||
| 312 | else | ||
| 313 | continue; | ||
| 314 | |||
| 309 | } | 315 | } |
| 310 | 316 | ||
| 311 | trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated); | 317 | trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated); |
| @@ -315,7 +321,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
| 315 | * pages requested were isolated. If there were any failures, 0 is | 321 | * pages requested were isolated. If there were any failures, 0 is |
| 316 | * returned and CMA will fail. | 322 | * returned and CMA will fail. |
| 317 | */ | 323 | */ |
| 318 | if (strict && nr_strict_required > total_isolated) | 324 | if (strict && blockpfn < end_pfn) |
| 319 | total_isolated = 0; | 325 | total_isolated = 0; |
| 320 | 326 | ||
| 321 | if (locked) | 327 | if (locked) |
