diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index faa0a088f9cc..4f49535d4cd3 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1124,8 +1124,20 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, | |||
1124 | nr_lumpy_dirty++; | 1124 | nr_lumpy_dirty++; |
1125 | scan++; | 1125 | scan++; |
1126 | } else { | 1126 | } else { |
1127 | /* the page is freed already. */ | 1127 | /* |
1128 | if (!page_count(cursor_page)) | 1128 | * Check if the page is freed already. |
1129 | * | ||
1130 | * We can't use page_count() as that | ||
1131 | * requires compound_head and we don't | ||
1132 | * have a pin on the page here. If a | ||
1133 | * page is tail, we may or may not | ||
1134 | * have isolated the head, so assume | ||
1135 | * it's not free, it'd be tricky to | ||
1136 | * track the head status without a | ||
1137 | * page pin. | ||
1138 | */ | ||
1139 | if (!PageTail(cursor_page) && | ||
1140 | !atomic_read(&cursor_page->_count)) | ||
1129 | continue; | 1141 | continue; |
1130 | break; | 1142 | break; |
1131 | } | 1143 | } |
@@ -1983,14 +1995,13 @@ restart: | |||
1983 | * If a zone is deemed to be full of pinned pages then just give it a light | 1995 | * If a zone is deemed to be full of pinned pages then just give it a light |
1984 | * scan then give up on it. | 1996 | * scan then give up on it. |
1985 | */ | 1997 | */ |
1986 | static unsigned long shrink_zones(int priority, struct zonelist *zonelist, | 1998 | static void shrink_zones(int priority, struct zonelist *zonelist, |
1987 | struct scan_control *sc) | 1999 | struct scan_control *sc) |
1988 | { | 2000 | { |
1989 | struct zoneref *z; | 2001 | struct zoneref *z; |
1990 | struct zone *zone; | 2002 | struct zone *zone; |
1991 | unsigned long nr_soft_reclaimed; | 2003 | unsigned long nr_soft_reclaimed; |
1992 | unsigned long nr_soft_scanned; | 2004 | unsigned long nr_soft_scanned; |
1993 | unsigned long total_scanned = 0; | ||
1994 | 2005 | ||
1995 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 2006 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
1996 | gfp_zone(sc->gfp_mask), sc->nodemask) { | 2007 | gfp_zone(sc->gfp_mask), sc->nodemask) { |
@@ -2005,19 +2016,23 @@ static unsigned long shrink_zones(int priority, struct zonelist *zonelist, | |||
2005 | continue; | 2016 | continue; |
2006 | if (zone->all_unreclaimable && priority != DEF_PRIORITY) | 2017 | if (zone->all_unreclaimable && priority != DEF_PRIORITY) |
2007 | continue; /* Let kswapd poll it */ | 2018 | continue; /* Let kswapd poll it */ |
2019 | /* | ||
2020 | * This steals pages from memory cgroups over softlimit | ||
2021 | * and returns the number of reclaimed pages and | ||
2022 | * scanned pages. This works for global memory pressure | ||
2023 | * and balancing, not for a memcg's limit. | ||
2024 | */ | ||
2025 | nr_soft_scanned = 0; | ||
2026 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone, | ||
2027 | sc->order, sc->gfp_mask, | ||
2028 | &nr_soft_scanned); | ||
2029 | sc->nr_reclaimed += nr_soft_reclaimed; | ||
2030 | sc->nr_scanned += nr_soft_scanned; | ||
2031 | /* need some check for avoid more shrink_zone() */ | ||
2008 | } | 2032 | } |
2009 | 2033 | ||
2010 | nr_soft_scanned = 0; | ||
2011 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone, | ||
2012 | sc->order, sc->gfp_mask, | ||
2013 | &nr_soft_scanned); | ||
2014 | sc->nr_reclaimed += nr_soft_reclaimed; | ||
2015 | total_scanned += nr_soft_scanned; | ||
2016 | |||
2017 | shrink_zone(priority, zone, sc); | 2034 | shrink_zone(priority, zone, sc); |
2018 | } | 2035 | } |
2019 | |||
2020 | return total_scanned; | ||
2021 | } | 2036 | } |
2022 | 2037 | ||
2023 | static bool zone_reclaimable(struct zone *zone) | 2038 | static bool zone_reclaimable(struct zone *zone) |
@@ -2081,8 +2096,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
2081 | for (priority = DEF_PRIORITY; priority >= 0; priority--) { | 2096 | for (priority = DEF_PRIORITY; priority >= 0; priority--) { |
2082 | sc->nr_scanned = 0; | 2097 | sc->nr_scanned = 0; |
2083 | if (!priority) | 2098 | if (!priority) |
2084 | disable_swap_token(); | 2099 | disable_swap_token(sc->mem_cgroup); |
2085 | total_scanned += shrink_zones(priority, zonelist, sc); | 2100 | shrink_zones(priority, zonelist, sc); |
2086 | /* | 2101 | /* |
2087 | * Don't shrink slabs when reclaiming memory from | 2102 | * Don't shrink slabs when reclaiming memory from |
2088 | * over limit cgroups | 2103 | * over limit cgroups |
@@ -2407,7 +2422,7 @@ loop_again: | |||
2407 | 2422 | ||
2408 | /* The swap token gets in the way of swapout... */ | 2423 | /* The swap token gets in the way of swapout... */ |
2409 | if (!priority) | 2424 | if (!priority) |
2410 | disable_swap_token(); | 2425 | disable_swap_token(NULL); |
2411 | 2426 | ||
2412 | all_zones_ok = 1; | 2427 | all_zones_ok = 1; |
2413 | balanced = 0; | 2428 | balanced = 0; |