diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index e5117b6897a9..2e34b61a70c7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1572,3 +1572,71 @@ static int __init kswapd_init(void) | |||
1572 | } | 1572 | } |
1573 | 1573 | ||
1574 | module_init(kswapd_init) | 1574 | module_init(kswapd_init) |
1575 | |||
1576 | #ifdef CONFIG_NUMA | ||
1577 | /* | ||
1578 | * Zone reclaim mode | ||
1579 | * | ||
1580 | * If non-zero call zone_reclaim when the number of free pages falls below | ||
1581 | * the watermarks. | ||
1582 | * | ||
1583 | * In the future we may add flags to the mode. However, the page allocator | ||
1584 | * should only have to check that zone_reclaim_mode != 0 before calling | ||
1585 | * zone_reclaim(). | ||
1586 | */ | ||
1587 | int zone_reclaim_mode __read_mostly; | ||
1588 | |||
1589 | /* | ||
1590 | * Mininum time between zone reclaim scans | ||
1591 | */ | ||
1592 | #define ZONE_RECLAIM_INTERVAL HZ/2 | ||
1593 | /* | ||
1594 | * Try to free up some pages from this zone through reclaim. | ||
1595 | */ | ||
1596 | int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | ||
1597 | { | ||
1598 | int nr_pages = 1 << order; | ||
1599 | struct task_struct *p = current; | ||
1600 | struct reclaim_state reclaim_state; | ||
1601 | struct scan_control sc = { | ||
1602 | .gfp_mask = gfp_mask, | ||
1603 | .may_writepage = 0, | ||
1604 | .may_swap = 0, | ||
1605 | .nr_mapped = read_page_state(nr_mapped), | ||
1606 | .nr_scanned = 0, | ||
1607 | .nr_reclaimed = 0, | ||
1608 | .priority = 0 | ||
1609 | }; | ||
1610 | |||
1611 | if (!(gfp_mask & __GFP_WAIT) || | ||
1612 | zone->zone_pgdat->node_id != numa_node_id() || | ||
1613 | zone->all_unreclaimable || | ||
1614 | atomic_read(&zone->reclaim_in_progress) > 0) | ||
1615 | return 0; | ||
1616 | |||
1617 | if (time_before(jiffies, | ||
1618 | zone->last_unsuccessful_zone_reclaim + ZONE_RECLAIM_INTERVAL)) | ||
1619 | return 0; | ||
1620 | |||
1621 | disable_swap_token(); | ||
1622 | |||
1623 | if (nr_pages > SWAP_CLUSTER_MAX) | ||
1624 | sc.swap_cluster_max = nr_pages; | ||
1625 | else | ||
1626 | sc.swap_cluster_max = SWAP_CLUSTER_MAX; | ||
1627 | |||
1628 | cond_resched(); | ||
1629 | p->flags |= PF_MEMALLOC; | ||
1630 | reclaim_state.reclaimed_slab = 0; | ||
1631 | p->reclaim_state = &reclaim_state; | ||
1632 | shrink_zone(zone, &sc); | ||
1633 | p->reclaim_state = NULL; | ||
1634 | current->flags &= ~PF_MEMALLOC; | ||
1635 | |||
1636 | if (sc.nr_reclaimed == 0) | ||
1637 | zone->last_unsuccessful_zone_reclaim = jiffies; | ||
1638 | |||
1639 | return sc.nr_reclaimed > nr_pages; | ||
1640 | } | ||
1641 | #endif | ||
1642 | |||