aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2015-02-11 18:26:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 20:06:03 -0500
commit21afa38eed655def15475b76681fa006c435b9de (patch)
treee0e21ba464c2337c61f7ef9aab2c5f3705ca5fb5 /mm
parent95a045f63d9868ee189fe24ee61689df5a133d5b (diff)
mm: memcontrol: consolidate swap controller code
The swap controller code is scattered all over the file. Gather all the code that isn't directly needed by the memory controller at the end of the file in its own CONFIG_MEMCG_SWAP section. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> Reviewed-by: Vladimir Davydov <vdavydov@parallels.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c264
1 files changed, 125 insertions, 139 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index ebf1139f323e..c7a9cb627180 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -72,22 +72,13 @@ EXPORT_SYMBOL(memory_cgrp_subsys);
72#define MEM_CGROUP_RECLAIM_RETRIES 5 72#define MEM_CGROUP_RECLAIM_RETRIES 5
73static struct mem_cgroup *root_mem_cgroup __read_mostly; 73static struct mem_cgroup *root_mem_cgroup __read_mostly;
74 74
75/* Whether the swap controller is active */
75#ifdef CONFIG_MEMCG_SWAP 76#ifdef CONFIG_MEMCG_SWAP
76/* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */
77int do_swap_account __read_mostly; 77int do_swap_account __read_mostly;
78
79/* for remember boot option*/
80#ifdef CONFIG_MEMCG_SWAP_ENABLED
81static int really_do_swap_account __initdata = 1;
82#else
83static int really_do_swap_account __initdata;
84#endif
85
86#else 78#else
87#define do_swap_account 0 79#define do_swap_account 0
88#endif 80#endif
89 81
90
91static const char * const mem_cgroup_stat_names[] = { 82static const char * const mem_cgroup_stat_names[] = {
92 "cache", 83 "cache",
93 "rss", 84 "rss",
@@ -4373,34 +4364,6 @@ static struct cftype mem_cgroup_legacy_files[] = {
4373 { }, /* terminate */ 4364 { }, /* terminate */
4374}; 4365};
4375 4366
4376#ifdef CONFIG_MEMCG_SWAP
4377static struct cftype memsw_cgroup_files[] = {
4378 {
4379 .name = "memsw.usage_in_bytes",
4380 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
4381 .read_u64 = mem_cgroup_read_u64,
4382 },
4383 {
4384 .name = "memsw.max_usage_in_bytes",
4385 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
4386 .write = mem_cgroup_reset,
4387 .read_u64 = mem_cgroup_read_u64,
4388 },
4389 {
4390 .name = "memsw.limit_in_bytes",
4391 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
4392 .write = mem_cgroup_write,
4393 .read_u64 = mem_cgroup_read_u64,
4394 },
4395 {
4396 .name = "memsw.failcnt",
4397 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
4398 .write = mem_cgroup_reset,
4399 .read_u64 = mem_cgroup_read_u64,
4400 },
4401 { }, /* terminate */
4402};
4403#endif
4404static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) 4367static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
4405{ 4368{
4406 struct mem_cgroup_per_node *pn; 4369 struct mem_cgroup_per_node *pn;
@@ -5391,37 +5354,6 @@ struct cgroup_subsys memory_cgrp_subsys = {
5391 .early_init = 0, 5354 .early_init = 0,
5392}; 5355};
5393 5356
5394#ifdef CONFIG_MEMCG_SWAP
5395static int __init enable_swap_account(char *s)
5396{
5397 if (!strcmp(s, "1"))
5398 really_do_swap_account = 1;
5399 else if (!strcmp(s, "0"))
5400 really_do_swap_account = 0;
5401 return 1;
5402}
5403__setup("swapaccount=", enable_swap_account);
5404
5405static void __init memsw_file_init(void)
5406{
5407 WARN_ON(cgroup_add_legacy_cftypes(&memory_cgrp_subsys,
5408 memsw_cgroup_files));
5409}
5410
5411static void __init enable_swap_cgroup(void)
5412{
5413 if (!mem_cgroup_disabled() && really_do_swap_account) {
5414 do_swap_account = 1;
5415 memsw_file_init();
5416 }
5417}
5418
5419#else
5420static void __init enable_swap_cgroup(void)
5421{
5422}
5423#endif
5424
5425/** 5357/**
5426 * mem_cgroup_events - count memory events against a cgroup 5358 * mem_cgroup_events - count memory events against a cgroup
5427 * @memcg: the memory cgroup 5359 * @memcg: the memory cgroup
@@ -5472,74 +5404,6 @@ bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg)
5472 return true; 5404 return true;
5473} 5405}
5474 5406
5475#ifdef CONFIG_MEMCG_SWAP
5476/**
5477 * mem_cgroup_swapout - transfer a memsw charge to swap
5478 * @page: page whose memsw charge to transfer
5479 * @entry: swap entry to move the charge to
5480 *
5481 * Transfer the memsw charge of @page to @entry.
5482 */
5483void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
5484{
5485 struct mem_cgroup *memcg;
5486 unsigned short oldid;
5487
5488 VM_BUG_ON_PAGE(PageLRU(page), page);
5489 VM_BUG_ON_PAGE(page_count(page), page);
5490
5491 if (!do_swap_account)
5492 return;
5493
5494 memcg = page->mem_cgroup;
5495
5496 /* Readahead page, never charged */
5497 if (!memcg)
5498 return;
5499
5500 oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
5501 VM_BUG_ON_PAGE(oldid, page);
5502 mem_cgroup_swap_statistics(memcg, true);
5503
5504 page->mem_cgroup = NULL;
5505
5506 if (!mem_cgroup_is_root(memcg))
5507 page_counter_uncharge(&memcg->memory, 1);
5508
5509 /* XXX: caller holds IRQ-safe mapping->tree_lock */
5510 VM_BUG_ON(!irqs_disabled());
5511
5512 mem_cgroup_charge_statistics(memcg, page, -1);
5513 memcg_check_events(memcg, page);
5514}
5515
5516/**
5517 * mem_cgroup_uncharge_swap - uncharge a swap entry
5518 * @entry: swap entry to uncharge
5519 *
5520 * Drop the memsw charge associated with @entry.
5521 */
5522void mem_cgroup_uncharge_swap(swp_entry_t entry)
5523{
5524 struct mem_cgroup *memcg;
5525 unsigned short id;
5526
5527 if (!do_swap_account)
5528 return;
5529
5530 id = swap_cgroup_record(entry, 0);
5531 rcu_read_lock();
5532 memcg = mem_cgroup_lookup(id);
5533 if (memcg) {
5534 if (!mem_cgroup_is_root(memcg))
5535 page_counter_uncharge(&memcg->memsw, 1);
5536 mem_cgroup_swap_statistics(memcg, false);
5537 css_put(&memcg->css);
5538 }
5539 rcu_read_unlock();
5540}
5541#endif
5542
5543/** 5407/**
5544 * mem_cgroup_try_charge - try charging a page 5408 * mem_cgroup_try_charge - try charging a page
5545 * @page: page to charge 5409 * @page: page to charge
@@ -5897,8 +5761,130 @@ static int __init mem_cgroup_init(void)
5897 soft_limit_tree.rb_tree_per_node[node] = rtpn; 5761 soft_limit_tree.rb_tree_per_node[node] = rtpn;
5898 } 5762 }
5899 5763
5900 enable_swap_cgroup();
5901
5902 return 0; 5764 return 0;
5903} 5765}
5904subsys_initcall(mem_cgroup_init); 5766subsys_initcall(mem_cgroup_init);
5767
5768#ifdef CONFIG_MEMCG_SWAP
5769/**
5770 * mem_cgroup_swapout - transfer a memsw charge to swap
5771 * @page: page whose memsw charge to transfer
5772 * @entry: swap entry to move the charge to
5773 *
5774 * Transfer the memsw charge of @page to @entry.
5775 */
5776void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
5777{
5778 struct mem_cgroup *memcg;
5779 unsigned short oldid;
5780
5781 VM_BUG_ON_PAGE(PageLRU(page), page);
5782 VM_BUG_ON_PAGE(page_count(page), page);
5783
5784 if (!do_swap_account)
5785 return;
5786
5787 memcg = page->mem_cgroup;
5788
5789 /* Readahead page, never charged */
5790 if (!memcg)
5791 return;
5792
5793 oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
5794 VM_BUG_ON_PAGE(oldid, page);
5795 mem_cgroup_swap_statistics(memcg, true);
5796
5797 page->mem_cgroup = NULL;
5798
5799 if (!mem_cgroup_is_root(memcg))
5800 page_counter_uncharge(&memcg->memory, 1);
5801
5802 /* XXX: caller holds IRQ-safe mapping->tree_lock */
5803 VM_BUG_ON(!irqs_disabled());
5804
5805 mem_cgroup_charge_statistics(memcg, page, -1);
5806 memcg_check_events(memcg, page);
5807}
5808
5809/**
5810 * mem_cgroup_uncharge_swap - uncharge a swap entry
5811 * @entry: swap entry to uncharge
5812 *
5813 * Drop the memsw charge associated with @entry.
5814 */
5815void mem_cgroup_uncharge_swap(swp_entry_t entry)
5816{
5817 struct mem_cgroup *memcg;
5818 unsigned short id;
5819
5820 if (!do_swap_account)
5821 return;
5822
5823 id = swap_cgroup_record(entry, 0);
5824 rcu_read_lock();
5825 memcg = mem_cgroup_lookup(id);
5826 if (memcg) {
5827 if (!mem_cgroup_is_root(memcg))
5828 page_counter_uncharge(&memcg->memsw, 1);
5829 mem_cgroup_swap_statistics(memcg, false);
5830 css_put(&memcg->css);
5831 }
5832 rcu_read_unlock();
5833}
5834
5835/* for remember boot option*/
5836#ifdef CONFIG_MEMCG_SWAP_ENABLED
5837static int really_do_swap_account __initdata = 1;
5838#else
5839static int really_do_swap_account __initdata;
5840#endif
5841
5842static int __init enable_swap_account(char *s)
5843{
5844 if (!strcmp(s, "1"))
5845 really_do_swap_account = 1;
5846 else if (!strcmp(s, "0"))
5847 really_do_swap_account = 0;
5848 return 1;
5849}
5850__setup("swapaccount=", enable_swap_account);
5851
5852static struct cftype memsw_cgroup_files[] = {
5853 {
5854 .name = "memsw.usage_in_bytes",
5855 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
5856 .read_u64 = mem_cgroup_read_u64,
5857 },
5858 {
5859 .name = "memsw.max_usage_in_bytes",
5860 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
5861 .write = mem_cgroup_reset,
5862 .read_u64 = mem_cgroup_read_u64,
5863 },
5864 {
5865 .name = "memsw.limit_in_bytes",
5866 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
5867 .write = mem_cgroup_write,
5868 .read_u64 = mem_cgroup_read_u64,
5869 },
5870 {
5871 .name = "memsw.failcnt",
5872 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
5873 .write = mem_cgroup_reset,
5874 .read_u64 = mem_cgroup_read_u64,
5875 },
5876 { }, /* terminate */
5877};
5878
5879static int __init mem_cgroup_swap_init(void)
5880{
5881 if (!mem_cgroup_disabled() && really_do_swap_account) {
5882 do_swap_account = 1;
5883 WARN_ON(cgroup_add_legacy_cftypes(&memory_cgrp_subsys,
5884 memsw_cgroup_files));
5885 }
5886 return 0;
5887}
5888subsys_initcall(mem_cgroup_swap_init);
5889
5890#endif /* CONFIG_MEMCG_SWAP */