compaction.c (7454f4ba40b419eb999a3c61a99da662bf1a2bb8) | compaction.c (f9e35b3b41f47c4e17d8132edbcab305a6aaa4b0) |
---|---|
1/* 2 * linux/mm/compaction.c 3 * 4 * Memory compaction for the reduction of external fragmentation. Note that 5 * this heavily depends upon page migration to do all the real heavy 6 * lifting 7 * 8 * Copyright IBM Corp. 2007-2010 Mel Gorman <mel@csn.ul.ie> --- 237 unchanged lines hidden (view full) --- 246 active = zone_page_state(zone, NR_ACTIVE_FILE) + 247 zone_page_state(zone, NR_ACTIVE_ANON); 248 isolated = zone_page_state(zone, NR_ISOLATED_FILE) + 249 zone_page_state(zone, NR_ISOLATED_ANON); 250 251 return isolated > (inactive + active) / 2; 252} 253 | 1/* 2 * linux/mm/compaction.c 3 * 4 * Memory compaction for the reduction of external fragmentation. Note that 5 * this heavily depends upon page migration to do all the real heavy 6 * lifting 7 * 8 * Copyright IBM Corp. 2007-2010 Mel Gorman <mel@csn.ul.ie> --- 237 unchanged lines hidden (view full) --- 246 active = zone_page_state(zone, NR_ACTIVE_FILE) + 247 zone_page_state(zone, NR_ACTIVE_ANON); 248 isolated = zone_page_state(zone, NR_ISOLATED_FILE) + 249 zone_page_state(zone, NR_ISOLATED_ANON); 250 251 return isolated > (inactive + active) / 2; 252} 253 |
254/* possible outcome of isolate_migratepages */ 255typedef enum { 256 ISOLATE_ABORT, /* Abort compaction now */ 257 ISOLATE_NONE, /* No pages isolated, continue scanning */ 258 ISOLATE_SUCCESS, /* Pages isolated, migrate */ 259} isolate_migrate_t; 260 |
|
254/* 255 * Isolate all pages that can be migrated from the block pointed to by 256 * the migrate scanner within compact_control. 257 */ | 261/* 262 * Isolate all pages that can be migrated from the block pointed to by 263 * the migrate scanner within compact_control. 264 */ |
258static unsigned long isolate_migratepages(struct zone *zone, | 265static isolate_migrate_t isolate_migratepages(struct zone *zone, |
259 struct compact_control *cc) 260{ 261 unsigned long low_pfn, end_pfn; 262 unsigned long last_pageblock_nr = 0, pageblock_nr; 263 unsigned long nr_scanned = 0, nr_isolated = 0; 264 struct list_head *migratelist = &cc->migratepages; 265 266 /* Do not scan outside zone boundaries */ 267 low_pfn = max(cc->migrate_pfn, zone->zone_start_pfn); 268 269 /* Only scan within a pageblock boundary */ 270 end_pfn = ALIGN(low_pfn + pageblock_nr_pages, pageblock_nr_pages); 271 272 /* Do not cross the free scanner or scan within a memory hole */ 273 if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) { 274 cc->migrate_pfn = end_pfn; | 266 struct compact_control *cc) 267{ 268 unsigned long low_pfn, end_pfn; 269 unsigned long last_pageblock_nr = 0, pageblock_nr; 270 unsigned long nr_scanned = 0, nr_isolated = 0; 271 struct list_head *migratelist = &cc->migratepages; 272 273 /* Do not scan outside zone boundaries */ 274 low_pfn = max(cc->migrate_pfn, zone->zone_start_pfn); 275 276 /* Only scan within a pageblock boundary */ 277 end_pfn = ALIGN(low_pfn + pageblock_nr_pages, pageblock_nr_pages); 278 279 /* Do not cross the free scanner or scan within a memory hole */ 280 if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) { 281 cc->migrate_pfn = end_pfn; |
275 return 0; | 282 return ISOLATE_NONE; |
276 } 277 278 /* 279 * Ensure that there are not too many pages isolated from the LRU 280 * list by either parallel reclaimers or compaction. If there are, 281 * delay for some time until fewer pages are isolated 282 */ 283 while (unlikely(too_many_isolated(zone))) { | 283 } 284 285 /* 286 * Ensure that there are not too many pages isolated from the LRU 287 * list by either parallel reclaimers or compaction. If there are, 288 * delay for some time until fewer pages are isolated 289 */ 290 while (unlikely(too_many_isolated(zone))) { |
291 /* async migration should just abort */ 292 if (!cc->sync) 293 return ISOLATE_ABORT; 294 |
|
284 congestion_wait(BLK_RW_ASYNC, HZ/10); 285 286 if (fatal_signal_pending(current)) | 295 congestion_wait(BLK_RW_ASYNC, HZ/10); 296 297 if (fatal_signal_pending(current)) |
287 return 0; | 298 return ISOLATE_ABORT; |
288 } 289 290 /* Time to isolate some pages for migration */ 291 cond_resched(); 292 spin_lock_irq(&zone->lru_lock); 293 for (; low_pfn < end_pfn; low_pfn++) { 294 struct page *page; 295 bool locked = true; --- 68 unchanged lines hidden (view full) --- 364 365 acct_isolated(zone, cc); 366 367 spin_unlock_irq(&zone->lru_lock); 368 cc->migrate_pfn = low_pfn; 369 370 trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); 371 | 299 } 300 301 /* Time to isolate some pages for migration */ 302 cond_resched(); 303 spin_lock_irq(&zone->lru_lock); 304 for (; low_pfn < end_pfn; low_pfn++) { 305 struct page *page; 306 bool locked = true; --- 68 unchanged lines hidden (view full) --- 375 376 acct_isolated(zone, cc); 377 378 spin_unlock_irq(&zone->lru_lock); 379 cc->migrate_pfn = low_pfn; 380 381 trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); 382 |
372 return cc->nr_migratepages; | 383 return ISOLATE_SUCCESS; |
373} 374 375/* 376 * This is a migrate-callback that "allocates" freepages by taking pages 377 * from the isolated freelists in the block we are migrating to. 378 */ 379static struct page *compaction_alloc(struct page *migratepage, 380 unsigned long data, --- 149 unchanged lines hidden (view full) --- 530 cc->free_pfn &= ~(pageblock_nr_pages-1); 531 532 migrate_prep_local(); 533 534 while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) { 535 unsigned long nr_migrate, nr_remaining; 536 int err; 537 | 384} 385 386/* 387 * This is a migrate-callback that "allocates" freepages by taking pages 388 * from the isolated freelists in the block we are migrating to. 389 */ 390static struct page *compaction_alloc(struct page *migratepage, 391 unsigned long data, --- 149 unchanged lines hidden (view full) --- 541 cc->free_pfn &= ~(pageblock_nr_pages-1); 542 543 migrate_prep_local(); 544 545 while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) { 546 unsigned long nr_migrate, nr_remaining; 547 int err; 548 |
538 if (!isolate_migratepages(zone, cc)) | 549 switch (isolate_migratepages(zone, cc)) { 550 case ISOLATE_ABORT: 551 ret = COMPACT_PARTIAL; 552 goto out; 553 case ISOLATE_NONE: |
539 continue; | 554 continue; |
555 case ISOLATE_SUCCESS: 556 ; 557 } |
|
540 541 nr_migrate = cc->nr_migratepages; 542 err = migrate_pages(&cc->migratepages, compaction_alloc, 543 (unsigned long)cc, false, 544 cc->sync); 545 update_nr_listpages(cc); 546 nr_remaining = cc->nr_migratepages; 547 --- 7 unchanged lines hidden (view full) --- 555 /* Release LRU pages not migrated */ 556 if (err) { 557 putback_lru_pages(&cc->migratepages); 558 cc->nr_migratepages = 0; 559 } 560 561 } 562 | 558 559 nr_migrate = cc->nr_migratepages; 560 err = migrate_pages(&cc->migratepages, compaction_alloc, 561 (unsigned long)cc, false, 562 cc->sync); 563 update_nr_listpages(cc); 564 nr_remaining = cc->nr_migratepages; 565 --- 7 unchanged lines hidden (view full) --- 573 /* Release LRU pages not migrated */ 574 if (err) { 575 putback_lru_pages(&cc->migratepages); 576 cc->nr_migratepages = 0; 577 } 578 579 } 580 |
581out: |
|
563 /* Release free pages and check accounting */ 564 cc->nr_freepages -= release_freepages(&cc->freepages); 565 VM_BUG_ON(cc->nr_freepages != 0); 566 567 return ret; 568} 569 570unsigned long compact_zone_order(struct zone *zone, --- 158 unchanged lines hidden --- | 582 /* Release free pages and check accounting */ 583 cc->nr_freepages -= release_freepages(&cc->freepages); 584 VM_BUG_ON(cc->nr_freepages != 0); 585 586 return ret; 587} 588 589unsigned long compact_zone_order(struct zone *zone, --- 158 unchanged lines hidden --- |