diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 08ef3d2ca663..6903e7d8c7be 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -87,6 +87,12 @@ int do_swap_account __read_mostly; | |||
87 | #define do_swap_account 0 | 87 | #define do_swap_account 0 |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | /* Whether legacy memory+swap accounting is active */ | ||
91 | static bool do_memsw_account(void) | ||
92 | { | ||
93 | return !cgroup_subsys_on_dfl(memory_cgrp_subsys) && do_swap_account; | ||
94 | } | ||
95 | |||
90 | static const char * const mem_cgroup_stat_names[] = { | 96 | static const char * const mem_cgroup_stat_names[] = { |
91 | "cache", | 97 | "cache", |
92 | "rss", | 98 | "rss", |
@@ -1199,7 +1205,7 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg) | |||
1199 | if (count < limit) | 1205 | if (count < limit) |
1200 | margin = limit - count; | 1206 | margin = limit - count; |
1201 | 1207 | ||
1202 | if (do_swap_account) { | 1208 | if (do_memsw_account()) { |
1203 | count = page_counter_read(&memcg->memsw); | 1209 | count = page_counter_read(&memcg->memsw); |
1204 | limit = READ_ONCE(memcg->memsw.limit); | 1210 | limit = READ_ONCE(memcg->memsw.limit); |
1205 | if (count <= limit) | 1211 | if (count <= limit) |
@@ -1302,7 +1308,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | |||
1302 | pr_cont(":"); | 1308 | pr_cont(":"); |
1303 | 1309 | ||
1304 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { | 1310 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { |
1305 | if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) | 1311 | if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) |
1306 | continue; | 1312 | continue; |
1307 | pr_cont(" %s:%luKB", mem_cgroup_stat_names[i], | 1313 | pr_cont(" %s:%luKB", mem_cgroup_stat_names[i], |
1308 | K(mem_cgroup_read_stat(iter, i))); | 1314 | K(mem_cgroup_read_stat(iter, i))); |
@@ -1925,7 +1931,7 @@ static void drain_stock(struct memcg_stock_pcp *stock) | |||
1925 | 1931 | ||
1926 | if (stock->nr_pages) { | 1932 | if (stock->nr_pages) { |
1927 | page_counter_uncharge(&old->memory, stock->nr_pages); | 1933 | page_counter_uncharge(&old->memory, stock->nr_pages); |
1928 | if (do_swap_account) | 1934 | if (do_memsw_account()) |
1929 | page_counter_uncharge(&old->memsw, stock->nr_pages); | 1935 | page_counter_uncharge(&old->memsw, stock->nr_pages); |
1930 | css_put_many(&old->css, stock->nr_pages); | 1936 | css_put_many(&old->css, stock->nr_pages); |
1931 | stock->nr_pages = 0; | 1937 | stock->nr_pages = 0; |
@@ -2055,11 +2061,11 @@ retry: | |||
2055 | if (consume_stock(memcg, nr_pages)) | 2061 | if (consume_stock(memcg, nr_pages)) |
2056 | return 0; | 2062 | return 0; |
2057 | 2063 | ||
2058 | if (!do_swap_account || | 2064 | if (!do_memsw_account() || |
2059 | page_counter_try_charge(&memcg->memsw, batch, &counter)) { | 2065 | page_counter_try_charge(&memcg->memsw, batch, &counter)) { |
2060 | if (page_counter_try_charge(&memcg->memory, batch, &counter)) | 2066 | if (page_counter_try_charge(&memcg->memory, batch, &counter)) |
2061 | goto done_restock; | 2067 | goto done_restock; |
2062 | if (do_swap_account) | 2068 | if (do_memsw_account()) |
2063 | page_counter_uncharge(&memcg->memsw, batch); | 2069 | page_counter_uncharge(&memcg->memsw, batch); |
2064 | mem_over_limit = mem_cgroup_from_counter(counter, memory); | 2070 | mem_over_limit = mem_cgroup_from_counter(counter, memory); |
2065 | } else { | 2071 | } else { |
@@ -2146,7 +2152,7 @@ force: | |||
2146 | * temporarily by force charging it. | 2152 | * temporarily by force charging it. |
2147 | */ | 2153 | */ |
2148 | page_counter_charge(&memcg->memory, nr_pages); | 2154 | page_counter_charge(&memcg->memory, nr_pages); |
2149 | if (do_swap_account) | 2155 | if (do_memsw_account()) |
2150 | page_counter_charge(&memcg->memsw, nr_pages); | 2156 | page_counter_charge(&memcg->memsw, nr_pages); |
2151 | css_get_many(&memcg->css, nr_pages); | 2157 | css_get_many(&memcg->css, nr_pages); |
2152 | 2158 | ||
@@ -2183,7 +2189,7 @@ static void cancel_charge(struct mem_cgroup *memcg, unsigned int nr_pages) | |||
2183 | return; | 2189 | return; |
2184 | 2190 | ||
2185 | page_counter_uncharge(&memcg->memory, nr_pages); | 2191 | page_counter_uncharge(&memcg->memory, nr_pages); |
2186 | if (do_swap_account) | 2192 | if (do_memsw_account()) |
2187 | page_counter_uncharge(&memcg->memsw, nr_pages); | 2193 | page_counter_uncharge(&memcg->memsw, nr_pages); |
2188 | 2194 | ||
2189 | css_put_many(&memcg->css, nr_pages); | 2195 | css_put_many(&memcg->css, nr_pages); |
@@ -2469,7 +2475,7 @@ void __memcg_kmem_uncharge(struct page *page, int order) | |||
2469 | 2475 | ||
2470 | page_counter_uncharge(&memcg->kmem, nr_pages); | 2476 | page_counter_uncharge(&memcg->kmem, nr_pages); |
2471 | page_counter_uncharge(&memcg->memory, nr_pages); | 2477 | page_counter_uncharge(&memcg->memory, nr_pages); |
2472 | if (do_swap_account) | 2478 | if (do_memsw_account()) |
2473 | page_counter_uncharge(&memcg->memsw, nr_pages); | 2479 | page_counter_uncharge(&memcg->memsw, nr_pages); |
2474 | 2480 | ||
2475 | page->mem_cgroup = NULL; | 2481 | page->mem_cgroup = NULL; |
@@ -3184,7 +3190,7 @@ static int memcg_stat_show(struct seq_file *m, void *v) | |||
3184 | BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); | 3190 | BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); |
3185 | 3191 | ||
3186 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { | 3192 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { |
3187 | if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) | 3193 | if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) |
3188 | continue; | 3194 | continue; |
3189 | seq_printf(m, "%s %lu\n", mem_cgroup_stat_names[i], | 3195 | seq_printf(m, "%s %lu\n", mem_cgroup_stat_names[i], |
3190 | mem_cgroup_read_stat(memcg, i) * PAGE_SIZE); | 3196 | mem_cgroup_read_stat(memcg, i) * PAGE_SIZE); |
@@ -3206,14 +3212,14 @@ static int memcg_stat_show(struct seq_file *m, void *v) | |||
3206 | } | 3212 | } |
3207 | seq_printf(m, "hierarchical_memory_limit %llu\n", | 3213 | seq_printf(m, "hierarchical_memory_limit %llu\n", |
3208 | (u64)memory * PAGE_SIZE); | 3214 | (u64)memory * PAGE_SIZE); |
3209 | if (do_swap_account) | 3215 | if (do_memsw_account()) |
3210 | seq_printf(m, "hierarchical_memsw_limit %llu\n", | 3216 | seq_printf(m, "hierarchical_memsw_limit %llu\n", |
3211 | (u64)memsw * PAGE_SIZE); | 3217 | (u64)memsw * PAGE_SIZE); |
3212 | 3218 | ||
3213 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { | 3219 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { |
3214 | unsigned long long val = 0; | 3220 | unsigned long long val = 0; |
3215 | 3221 | ||
3216 | if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account) | 3222 | if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account()) |
3217 | continue; | 3223 | continue; |
3218 | for_each_mem_cgroup_tree(mi, memcg) | 3224 | for_each_mem_cgroup_tree(mi, memcg) |
3219 | val += mem_cgroup_read_stat(mi, i) * PAGE_SIZE; | 3225 | val += mem_cgroup_read_stat(mi, i) * PAGE_SIZE; |
@@ -3344,7 +3350,7 @@ static void mem_cgroup_threshold(struct mem_cgroup *memcg) | |||
3344 | { | 3350 | { |
3345 | while (memcg) { | 3351 | while (memcg) { |
3346 | __mem_cgroup_threshold(memcg, false); | 3352 | __mem_cgroup_threshold(memcg, false); |
3347 | if (do_swap_account) | 3353 | if (do_memsw_account()) |
3348 | __mem_cgroup_threshold(memcg, true); | 3354 | __mem_cgroup_threshold(memcg, true); |
3349 | 3355 | ||
3350 | memcg = parent_mem_cgroup(memcg); | 3356 | memcg = parent_mem_cgroup(memcg); |
@@ -4497,7 +4503,7 @@ static struct page *mc_handle_swap_pte(struct vm_area_struct *vma, | |||
4497 | * we call find_get_page() with swapper_space directly. | 4503 | * we call find_get_page() with swapper_space directly. |
4498 | */ | 4504 | */ |
4499 | page = find_get_page(swap_address_space(ent), ent.val); | 4505 | page = find_get_page(swap_address_space(ent), ent.val); |
4500 | if (do_swap_account) | 4506 | if (do_memsw_account()) |
4501 | entry->val = ent.val; | 4507 | entry->val = ent.val; |
4502 | 4508 | ||
4503 | return page; | 4509 | return page; |
@@ -4532,7 +4538,7 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, | |||
4532 | page = find_get_entry(mapping, pgoff); | 4538 | page = find_get_entry(mapping, pgoff); |
4533 | if (radix_tree_exceptional_entry(page)) { | 4539 | if (radix_tree_exceptional_entry(page)) { |
4534 | swp_entry_t swp = radix_to_swp_entry(page); | 4540 | swp_entry_t swp = radix_to_swp_entry(page); |
4535 | if (do_swap_account) | 4541 | if (do_memsw_account()) |
4536 | *entry = swp; | 4542 | *entry = swp; |
4537 | page = find_get_page(swap_address_space(swp), swp.val); | 4543 | page = find_get_page(swap_address_space(swp), swp.val); |
4538 | } | 4544 | } |
@@ -5325,7 +5331,7 @@ int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, | |||
5325 | if (page->mem_cgroup) | 5331 | if (page->mem_cgroup) |
5326 | goto out; | 5332 | goto out; |
5327 | 5333 | ||
5328 | if (do_swap_account) { | 5334 | if (do_memsw_account()) { |
5329 | swp_entry_t ent = { .val = page_private(page), }; | 5335 | swp_entry_t ent = { .val = page_private(page), }; |
5330 | unsigned short id = lookup_swap_cgroup_id(ent); | 5336 | unsigned short id = lookup_swap_cgroup_id(ent); |
5331 | 5337 | ||
@@ -5399,7 +5405,7 @@ void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, | |||
5399 | memcg_check_events(memcg, page); | 5405 | memcg_check_events(memcg, page); |
5400 | local_irq_enable(); | 5406 | local_irq_enable(); |
5401 | 5407 | ||
5402 | if (do_swap_account && PageSwapCache(page)) { | 5408 | if (do_memsw_account() && PageSwapCache(page)) { |
5403 | swp_entry_t entry = { .val = page_private(page) }; | 5409 | swp_entry_t entry = { .val = page_private(page) }; |
5404 | /* | 5410 | /* |
5405 | * The swap entry might not get freed for a long time, | 5411 | * The swap entry might not get freed for a long time, |
@@ -5448,7 +5454,7 @@ static void uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout, | |||
5448 | 5454 | ||
5449 | if (!mem_cgroup_is_root(memcg)) { | 5455 | if (!mem_cgroup_is_root(memcg)) { |
5450 | page_counter_uncharge(&memcg->memory, nr_pages); | 5456 | page_counter_uncharge(&memcg->memory, nr_pages); |
5451 | if (do_swap_account) | 5457 | if (do_memsw_account()) |
5452 | page_counter_uncharge(&memcg->memsw, nr_pages); | 5458 | page_counter_uncharge(&memcg->memsw, nr_pages); |
5453 | memcg_oom_recover(memcg); | 5459 | memcg_oom_recover(memcg); |
5454 | } | 5460 | } |
@@ -5656,7 +5662,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | |||
5656 | VM_BUG_ON_PAGE(PageLRU(page), page); | 5662 | VM_BUG_ON_PAGE(PageLRU(page), page); |
5657 | VM_BUG_ON_PAGE(page_count(page), page); | 5663 | VM_BUG_ON_PAGE(page_count(page), page); |
5658 | 5664 | ||
5659 | if (!do_swap_account) | 5665 | if (!do_memsw_account()) |
5660 | return; | 5666 | return; |
5661 | 5667 | ||
5662 | memcg = page->mem_cgroup; | 5668 | memcg = page->mem_cgroup; |
@@ -5696,7 +5702,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t entry) | |||
5696 | struct mem_cgroup *memcg; | 5702 | struct mem_cgroup *memcg; |
5697 | unsigned short id; | 5703 | unsigned short id; |
5698 | 5704 | ||
5699 | if (!do_swap_account) | 5705 | if (!do_memsw_account()) |
5700 | return; | 5706 | return; |
5701 | 5707 | ||
5702 | id = swap_cgroup_record(entry, 0); | 5708 | id = swap_cgroup_record(entry, 0); |