diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 49 |
1 files changed, 17 insertions, 32 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 13de53fe0108..62bbb48980e5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -504,11 +504,6 @@ static void mem_cgroup_remove_from_trees(struct mem_cgroup *mem) | |||
504 | } | 504 | } |
505 | } | 505 | } |
506 | 506 | ||
507 | static inline unsigned long mem_cgroup_get_excess(struct mem_cgroup *mem) | ||
508 | { | ||
509 | return res_counter_soft_limit_excess(&mem->res) >> PAGE_SHIFT; | ||
510 | } | ||
511 | |||
512 | static struct mem_cgroup_per_zone * | 507 | static struct mem_cgroup_per_zone * |
513 | __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) | 508 | __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) |
514 | { | 509 | { |
@@ -1127,33 +1122,21 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, | |||
1127 | #define mem_cgroup_from_res_counter(counter, member) \ | 1122 | #define mem_cgroup_from_res_counter(counter, member) \ |
1128 | container_of(counter, struct mem_cgroup, member) | 1123 | container_of(counter, struct mem_cgroup, member) |
1129 | 1124 | ||
1130 | static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) | ||
1131 | { | ||
1132 | if (do_swap_account) { | ||
1133 | if (res_counter_check_under_limit(&mem->res) && | ||
1134 | res_counter_check_under_limit(&mem->memsw)) | ||
1135 | return true; | ||
1136 | } else | ||
1137 | if (res_counter_check_under_limit(&mem->res)) | ||
1138 | return true; | ||
1139 | return false; | ||
1140 | } | ||
1141 | |||
1142 | /** | 1125 | /** |
1143 | * mem_cgroup_check_margin - check if the memory cgroup allows charging | 1126 | * mem_cgroup_margin - calculate chargeable space of a memory cgroup |
1144 | * @mem: memory cgroup to check | 1127 | * @mem: the memory cgroup |
1145 | * @bytes: the number of bytes the caller intends to charge | ||
1146 | * | 1128 | * |
1147 | * Returns a boolean value on whether @mem can be charged @bytes or | 1129 | * Returns the maximum amount of memory @mem can be charged with, in |
1148 | * whether this would exceed the limit. | 1130 | * bytes. |
1149 | */ | 1131 | */ |
1150 | static bool mem_cgroup_check_margin(struct mem_cgroup *mem, unsigned long bytes) | 1132 | static unsigned long long mem_cgroup_margin(struct mem_cgroup *mem) |
1151 | { | 1133 | { |
1152 | if (!res_counter_check_margin(&mem->res, bytes)) | 1134 | unsigned long long margin; |
1153 | return false; | 1135 | |
1154 | if (do_swap_account && !res_counter_check_margin(&mem->memsw, bytes)) | 1136 | margin = res_counter_margin(&mem->res); |
1155 | return false; | 1137 | if (do_swap_account) |
1156 | return true; | 1138 | margin = min(margin, res_counter_margin(&mem->memsw)); |
1139 | return margin; | ||
1157 | } | 1140 | } |
1158 | 1141 | ||
1159 | static unsigned int get_swappiness(struct mem_cgroup *memcg) | 1142 | static unsigned int get_swappiness(struct mem_cgroup *memcg) |
@@ -1420,7 +1403,9 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, | |||
1420 | bool noswap = reclaim_options & MEM_CGROUP_RECLAIM_NOSWAP; | 1403 | bool noswap = reclaim_options & MEM_CGROUP_RECLAIM_NOSWAP; |
1421 | bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK; | 1404 | bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK; |
1422 | bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT; | 1405 | bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT; |
1423 | unsigned long excess = mem_cgroup_get_excess(root_mem); | 1406 | unsigned long excess; |
1407 | |||
1408 | excess = res_counter_soft_limit_excess(&root_mem->res) >> PAGE_SHIFT; | ||
1424 | 1409 | ||
1425 | /* If memsw_is_minimum==1, swap-out is of-no-use. */ | 1410 | /* If memsw_is_minimum==1, swap-out is of-no-use. */ |
1426 | if (root_mem->memsw_is_minimum) | 1411 | if (root_mem->memsw_is_minimum) |
@@ -1477,9 +1462,9 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, | |||
1477 | return ret; | 1462 | return ret; |
1478 | total += ret; | 1463 | total += ret; |
1479 | if (check_soft) { | 1464 | if (check_soft) { |
1480 | if (res_counter_check_within_soft_limit(&root_mem->res)) | 1465 | if (!res_counter_soft_limit_excess(&root_mem->res)) |
1481 | return total; | 1466 | return total; |
1482 | } else if (mem_cgroup_check_under_limit(root_mem)) | 1467 | } else if (mem_cgroup_margin(root_mem)) |
1483 | return 1 + total; | 1468 | return 1 + total; |
1484 | } | 1469 | } |
1485 | return total; | 1470 | return total; |
@@ -1898,7 +1883,7 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, | |||
1898 | 1883 | ||
1899 | ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, | 1884 | ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, |
1900 | gfp_mask, flags); | 1885 | gfp_mask, flags); |
1901 | if (mem_cgroup_check_margin(mem_over_limit, csize)) | 1886 | if (mem_cgroup_margin(mem_over_limit) >= csize) |
1902 | return CHARGE_RETRY; | 1887 | return CHARGE_RETRY; |
1903 | /* | 1888 | /* |
1904 | * Even though the limit is exceeded at this point, reclaim | 1889 | * Even though the limit is exceeded at this point, reclaim |