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 ---