diff options
-rw-r--r-- | mm/vmscan.c | 108 |
1 files changed, 62 insertions, 46 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index f7c4f37c3b18..5feef4d4650e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1431,13 +1431,14 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask) | |||
1431 | int ret = 0; | 1431 | int ret = 0; |
1432 | int total_scanned = 0, total_reclaimed = 0; | 1432 | int total_scanned = 0, total_reclaimed = 0; |
1433 | struct reclaim_state *reclaim_state = current->reclaim_state; | 1433 | struct reclaim_state *reclaim_state = current->reclaim_state; |
1434 | struct scan_control sc; | ||
1435 | unsigned long lru_pages = 0; | 1434 | unsigned long lru_pages = 0; |
1436 | int i; | 1435 | int i; |
1437 | 1436 | struct scan_control sc = { | |
1438 | sc.gfp_mask = gfp_mask; | 1437 | .gfp_mask = gfp_mask, |
1439 | sc.may_writepage = !laptop_mode; | 1438 | .may_writepage = !laptop_mode, |
1440 | sc.may_swap = 1; | 1439 | .swap_cluster_max = SWAP_CLUSTER_MAX, |
1440 | .may_swap = 1, | ||
1441 | }; | ||
1441 | 1442 | ||
1442 | inc_page_state(allocstall); | 1443 | inc_page_state(allocstall); |
1443 | 1444 | ||
@@ -1455,7 +1456,6 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask) | |||
1455 | sc.nr_mapped = read_page_state(nr_mapped); | 1456 | sc.nr_mapped = read_page_state(nr_mapped); |
1456 | sc.nr_scanned = 0; | 1457 | sc.nr_scanned = 0; |
1457 | sc.nr_reclaimed = 0; | 1458 | sc.nr_reclaimed = 0; |
1458 | sc.swap_cluster_max = SWAP_CLUSTER_MAX; | ||
1459 | if (!priority) | 1459 | if (!priority) |
1460 | disable_swap_token(); | 1460 | disable_swap_token(); |
1461 | shrink_caches(priority, zones, &sc); | 1461 | shrink_caches(priority, zones, &sc); |
@@ -1478,7 +1478,8 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask) | |||
1478 | * that's undesirable in laptop mode, where we *want* lumpy | 1478 | * that's undesirable in laptop mode, where we *want* lumpy |
1479 | * writeout. So in laptop mode, write out the whole world. | 1479 | * writeout. So in laptop mode, write out the whole world. |
1480 | */ | 1480 | */ |
1481 | if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) { | 1481 | if (total_scanned > sc.swap_cluster_max + |
1482 | sc.swap_cluster_max / 2) { | ||
1482 | wakeup_pdflush(laptop_mode ? 0 : total_scanned); | 1483 | wakeup_pdflush(laptop_mode ? 0 : total_scanned); |
1483 | sc.may_writepage = 1; | 1484 | sc.may_writepage = 1; |
1484 | } | 1485 | } |
@@ -1532,14 +1533,16 @@ static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int order) | |||
1532 | int i; | 1533 | int i; |
1533 | int total_scanned, total_reclaimed; | 1534 | int total_scanned, total_reclaimed; |
1534 | struct reclaim_state *reclaim_state = current->reclaim_state; | 1535 | struct reclaim_state *reclaim_state = current->reclaim_state; |
1535 | struct scan_control sc; | 1536 | struct scan_control sc = { |
1537 | .gfp_mask = GFP_KERNEL, | ||
1538 | .may_swap = 1, | ||
1539 | .swap_cluster_max = nr_pages ? nr_pages : SWAP_CLUSTER_MAX, | ||
1540 | }; | ||
1536 | 1541 | ||
1537 | loop_again: | 1542 | loop_again: |
1538 | total_scanned = 0; | 1543 | total_scanned = 0; |
1539 | total_reclaimed = 0; | 1544 | total_reclaimed = 0; |
1540 | sc.gfp_mask = GFP_KERNEL; | 1545 | sc.may_writepage = !laptop_mode, |
1541 | sc.may_writepage = !laptop_mode; | ||
1542 | sc.may_swap = 1; | ||
1543 | sc.nr_mapped = read_page_state(nr_mapped); | 1546 | sc.nr_mapped = read_page_state(nr_mapped); |
1544 | 1547 | ||
1545 | inc_page_state(pageoutrun); | 1548 | inc_page_state(pageoutrun); |
@@ -1621,7 +1624,6 @@ scan: | |||
1621 | zone->prev_priority = priority; | 1624 | zone->prev_priority = priority; |
1622 | sc.nr_scanned = 0; | 1625 | sc.nr_scanned = 0; |
1623 | sc.nr_reclaimed = 0; | 1626 | sc.nr_reclaimed = 0; |
1624 | sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; | ||
1625 | shrink_zone(priority, zone, &sc); | 1627 | shrink_zone(priority, zone, &sc); |
1626 | reclaim_state->reclaimed_slab = 0; | 1628 | reclaim_state->reclaimed_slab = 0; |
1627 | nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, | 1629 | nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, |
@@ -1869,46 +1871,21 @@ int zone_reclaim_interval __read_mostly = 30*HZ; | |||
1869 | /* | 1871 | /* |
1870 | * Try to free up some pages from this zone through reclaim. | 1872 | * Try to free up some pages from this zone through reclaim. |
1871 | */ | 1873 | */ |
1872 | int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | 1874 | static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) |
1873 | { | 1875 | { |
1874 | int nr_pages; | 1876 | const int nr_pages = 1 << order; |
1875 | struct task_struct *p = current; | 1877 | struct task_struct *p = current; |
1876 | struct reclaim_state reclaim_state; | 1878 | struct reclaim_state reclaim_state; |
1877 | struct scan_control sc; | ||
1878 | cpumask_t mask; | ||
1879 | int node_id; | ||
1880 | int priority; | 1879 | int priority; |
1881 | 1880 | struct scan_control sc = { | |
1882 | if (time_before(jiffies, | 1881 | .may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE), |
1883 | zone->last_unsuccessful_zone_reclaim + zone_reclaim_interval)) | 1882 | .may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP), |
1884 | return 0; | 1883 | .nr_mapped = read_page_state(nr_mapped), |
1885 | 1884 | .swap_cluster_max = max(nr_pages, SWAP_CLUSTER_MAX), | |
1886 | if (!(gfp_mask & __GFP_WAIT) || | 1885 | .gfp_mask = gfp_mask, |
1887 | zone->all_unreclaimable || | 1886 | }; |
1888 | atomic_read(&zone->reclaim_in_progress) > 0 || | ||
1889 | (p->flags & PF_MEMALLOC)) | ||
1890 | return 0; | ||
1891 | |||
1892 | node_id = zone->zone_pgdat->node_id; | ||
1893 | mask = node_to_cpumask(node_id); | ||
1894 | if (!cpus_empty(mask) && node_id != numa_node_id()) | ||
1895 | return 0; | ||
1896 | |||
1897 | sc.may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE); | ||
1898 | sc.may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP); | ||
1899 | sc.nr_scanned = 0; | ||
1900 | sc.nr_reclaimed = 0; | ||
1901 | sc.nr_mapped = read_page_state(nr_mapped); | ||
1902 | sc.gfp_mask = gfp_mask; | ||
1903 | 1887 | ||
1904 | disable_swap_token(); | 1888 | disable_swap_token(); |
1905 | |||
1906 | nr_pages = 1 << order; | ||
1907 | if (nr_pages > SWAP_CLUSTER_MAX) | ||
1908 | sc.swap_cluster_max = nr_pages; | ||
1909 | else | ||
1910 | sc.swap_cluster_max = SWAP_CLUSTER_MAX; | ||
1911 | |||
1912 | cond_resched(); | 1889 | cond_resched(); |
1913 | /* | 1890 | /* |
1914 | * We need to be able to allocate from the reserves for RECLAIM_SWAP | 1891 | * We need to be able to allocate from the reserves for RECLAIM_SWAP |
@@ -1949,5 +1926,44 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
1949 | 1926 | ||
1950 | return sc.nr_reclaimed >= nr_pages; | 1927 | return sc.nr_reclaimed >= nr_pages; |
1951 | } | 1928 | } |
1929 | |||
1930 | int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | ||
1931 | { | ||
1932 | cpumask_t mask; | ||
1933 | int node_id; | ||
1934 | |||
1935 | /* | ||
1936 | * Do not reclaim if there was a recent unsuccessful attempt at zone | ||
1937 | * reclaim. In that case we let allocations go off node for the | ||
1938 | * zone_reclaim_interval. Otherwise we would scan for each off-node | ||
1939 | * page allocation. | ||
1940 | */ | ||
1941 | if (time_before(jiffies, | ||
1942 | zone->last_unsuccessful_zone_reclaim + zone_reclaim_interval)) | ||
1943 | return 0; | ||
1944 | |||
1945 | /* | ||
1946 | * Avoid concurrent zone reclaims, do not reclaim in a zone that does | ||
1947 | * not have reclaimable pages and if we should not delay the allocation | ||
1948 | * then do not scan. | ||
1949 | */ | ||
1950 | if (!(gfp_mask & __GFP_WAIT) || | ||
1951 | zone->all_unreclaimable || | ||
1952 | atomic_read(&zone->reclaim_in_progress) > 0 || | ||
1953 | (current->flags & PF_MEMALLOC)) | ||
1954 | return 0; | ||
1955 | |||
1956 | /* | ||
1957 | * Only run zone reclaim on the local zone or on zones that do not | ||
1958 | * have associated processors. This will favor the local processor | ||
1959 | * over remote processors and spread off node memory allocations | ||
1960 | * as wide as possible. | ||
1961 | */ | ||
1962 | node_id = zone->zone_pgdat->node_id; | ||
1963 | mask = node_to_cpumask(node_id); | ||
1964 | if (!cpus_empty(mask) && node_id != numa_node_id()) | ||
1965 | return 0; | ||
1966 | return __zone_reclaim(zone, gfp_mask, order); | ||
1967 | } | ||
1952 | #endif | 1968 | #endif |
1953 | 1969 | ||