diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memcontrol.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 50eb50e100fd..0e81eb5f0aea 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1111,6 +1111,23 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) | |||
1111 | return false; | 1111 | return false; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | /** | ||
1115 | * mem_cgroup_check_margin - check if the memory cgroup allows charging | ||
1116 | * @mem: memory cgroup to check | ||
1117 | * @bytes: the number of bytes the caller intends to charge | ||
1118 | * | ||
1119 | * Returns a boolean value on whether @mem can be charged @bytes or | ||
1120 | * whether this would exceed the limit. | ||
1121 | */ | ||
1122 | static bool mem_cgroup_check_margin(struct mem_cgroup *mem, unsigned long bytes) | ||
1123 | { | ||
1124 | if (!res_counter_check_margin(&mem->res, bytes)) | ||
1125 | return false; | ||
1126 | if (do_swap_account && !res_counter_check_margin(&mem->memsw, bytes)) | ||
1127 | return false; | ||
1128 | return true; | ||
1129 | } | ||
1130 | |||
1114 | static unsigned int get_swappiness(struct mem_cgroup *memcg) | 1131 | static unsigned int get_swappiness(struct mem_cgroup *memcg) |
1115 | { | 1132 | { |
1116 | struct cgroup *cgrp = memcg->css.cgroup; | 1133 | struct cgroup *cgrp = memcg->css.cgroup; |
@@ -1852,15 +1869,19 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, | |||
1852 | return CHARGE_WOULDBLOCK; | 1869 | return CHARGE_WOULDBLOCK; |
1853 | 1870 | ||
1854 | ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, | 1871 | ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, |
1855 | gfp_mask, flags); | 1872 | gfp_mask, flags); |
1873 | if (mem_cgroup_check_margin(mem_over_limit, csize)) | ||
1874 | return CHARGE_RETRY; | ||
1856 | /* | 1875 | /* |
1857 | * try_to_free_mem_cgroup_pages() might not give us a full | 1876 | * Even though the limit is exceeded at this point, reclaim |
1858 | * picture of reclaim. Some pages are reclaimed and might be | 1877 | * may have been able to free some pages. Retry the charge |
1859 | * moved to swap cache or just unmapped from the cgroup. | 1878 | * before killing the task. |
1860 | * Check the limit again to see if the reclaim reduced the | 1879 | * |
1861 | * current usage of the cgroup before giving up | 1880 | * Only for regular pages, though: huge pages are rather |
1881 | * unlikely to succeed so close to the limit, and we fall back | ||
1882 | * to regular pages anyway in case of failure. | ||
1862 | */ | 1883 | */ |
1863 | if (ret || mem_cgroup_check_under_limit(mem_over_limit)) | 1884 | if (csize == PAGE_SIZE && ret) |
1864 | return CHARGE_RETRY; | 1885 | return CHARGE_RETRY; |
1865 | 1886 | ||
1866 | /* | 1887 | /* |