diff options
| -rw-r--r-- | include/linux/res_counter.h | 20 | ||||
| -rw-r--r-- | mm/memcontrol.c | 35 |
2 files changed, 48 insertions, 7 deletions
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h index fcb9884df618..a5930cb66145 100644 --- a/include/linux/res_counter.h +++ b/include/linux/res_counter.h | |||
| @@ -182,6 +182,26 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt) | |||
| 182 | return ret; | 182 | return ret; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /** | ||
| 186 | * res_counter_check_margin - check if the counter allows charging | ||
| 187 | * @cnt: the resource counter to check | ||
| 188 | * @bytes: the number of bytes to check the remaining space against | ||
| 189 | * | ||
| 190 | * Returns a boolean value on whether the counter can be charged | ||
| 191 | * @bytes or whether this would exceed the limit. | ||
| 192 | */ | ||
| 193 | static inline bool res_counter_check_margin(struct res_counter *cnt, | ||
| 194 | unsigned long bytes) | ||
| 195 | { | ||
| 196 | bool ret; | ||
| 197 | unsigned long flags; | ||
| 198 | |||
| 199 | spin_lock_irqsave(&cnt->lock, flags); | ||
| 200 | ret = cnt->limit - cnt->usage >= bytes; | ||
| 201 | spin_unlock_irqrestore(&cnt->lock, flags); | ||
| 202 | return ret; | ||
| 203 | } | ||
| 204 | |||
| 185 | static inline bool res_counter_check_under_soft_limit(struct res_counter *cnt) | 205 | static inline bool res_counter_check_under_soft_limit(struct res_counter *cnt) |
| 186 | { | 206 | { |
| 187 | bool ret; | 207 | bool ret; |
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 | /* |
