diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 92887b286246..20e3619870ae 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2258,7 +2258,8 @@ enum { | |||
2258 | }; | 2258 | }; |
2259 | 2259 | ||
2260 | static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, | 2260 | static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, |
2261 | unsigned int nr_pages, bool oom_check) | 2261 | unsigned int nr_pages, unsigned int min_pages, |
2262 | bool oom_check) | ||
2262 | { | 2263 | { |
2263 | unsigned long csize = nr_pages * PAGE_SIZE; | 2264 | unsigned long csize = nr_pages * PAGE_SIZE; |
2264 | struct mem_cgroup *mem_over_limit; | 2265 | struct mem_cgroup *mem_over_limit; |
@@ -2281,18 +2282,18 @@ static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, | |||
2281 | } else | 2282 | } else |
2282 | mem_over_limit = mem_cgroup_from_res_counter(fail_res, res); | 2283 | mem_over_limit = mem_cgroup_from_res_counter(fail_res, res); |
2283 | /* | 2284 | /* |
2284 | * nr_pages can be either a huge page (HPAGE_PMD_NR), a batch | ||
2285 | * of regular pages (CHARGE_BATCH), or a single regular page (1). | ||
2286 | * | ||
2287 | * Never reclaim on behalf of optional batching, retry with a | 2285 | * Never reclaim on behalf of optional batching, retry with a |
2288 | * single page instead. | 2286 | * single page instead. |
2289 | */ | 2287 | */ |
2290 | if (nr_pages == CHARGE_BATCH) | 2288 | if (nr_pages > min_pages) |
2291 | return CHARGE_RETRY; | 2289 | return CHARGE_RETRY; |
2292 | 2290 | ||
2293 | if (!(gfp_mask & __GFP_WAIT)) | 2291 | if (!(gfp_mask & __GFP_WAIT)) |
2294 | return CHARGE_WOULDBLOCK; | 2292 | return CHARGE_WOULDBLOCK; |
2295 | 2293 | ||
2294 | if (gfp_mask & __GFP_NORETRY) | ||
2295 | return CHARGE_NOMEM; | ||
2296 | |||
2296 | ret = mem_cgroup_reclaim(mem_over_limit, gfp_mask, flags); | 2297 | ret = mem_cgroup_reclaim(mem_over_limit, gfp_mask, flags); |
2297 | if (mem_cgroup_margin(mem_over_limit) >= nr_pages) | 2298 | if (mem_cgroup_margin(mem_over_limit) >= nr_pages) |
2298 | return CHARGE_RETRY; | 2299 | return CHARGE_RETRY; |
@@ -2305,7 +2306,7 @@ static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, | |||
2305 | * unlikely to succeed so close to the limit, and we fall back | 2306 | * unlikely to succeed so close to the limit, and we fall back |
2306 | * to regular pages anyway in case of failure. | 2307 | * to regular pages anyway in case of failure. |
2307 | */ | 2308 | */ |
2308 | if (nr_pages == 1 && ret) | 2309 | if (nr_pages <= (1 << PAGE_ALLOC_COSTLY_ORDER) && ret) |
2309 | return CHARGE_RETRY; | 2310 | return CHARGE_RETRY; |
2310 | 2311 | ||
2311 | /* | 2312 | /* |
@@ -2439,7 +2440,8 @@ again: | |||
2439 | nr_oom_retries = MEM_CGROUP_RECLAIM_RETRIES; | 2440 | nr_oom_retries = MEM_CGROUP_RECLAIM_RETRIES; |
2440 | } | 2441 | } |
2441 | 2442 | ||
2442 | ret = mem_cgroup_do_charge(memcg, gfp_mask, batch, oom_check); | 2443 | ret = mem_cgroup_do_charge(memcg, gfp_mask, batch, nr_pages, |
2444 | oom_check); | ||
2443 | switch (ret) { | 2445 | switch (ret) { |
2444 | case CHARGE_OK: | 2446 | case CHARGE_OK: |
2445 | break; | 2447 | break; |