aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2009-06-17 19:27:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:03:47 -0400
commit8a9478ca7f4bcb8945cec7f95d52dae2d5e50cbd (patch)
tree935e6ee3340ebe999374b54967cc2fa14e8d0060 /mm/swapfile.c
parent20ebcdda78a282d1d5266887ddf8a2d670182576 (diff)
memcg: fix swap accounting
This patch fixes mis-accounting of swap usage in memcg. In the current implementation, memcg's swap account is uncharged only when swap is completely freed. But there are several cases where swap cannot be freed cleanly. For handling that, this patch changes that memcg uncharges swap account when swap has no references other than cache. By this, memcg's swap entry accounting can be fully synchronous with the application's behavior. This patch also changes memcg's hooks for swap-out. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Acked-by: Balbir Singh <balbir@in.ibm.com> Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Dhaval Giani <dhaval@linux.vnet.ibm.com> Cc: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 28faa01cf578..d1ade1a48ee7 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -583,8 +583,9 @@ static int swap_entry_free(struct swap_info_struct *p,
583 swap_list.next = p - swap_info; 583 swap_list.next = p - swap_info;
584 nr_swap_pages++; 584 nr_swap_pages++;
585 p->inuse_pages--; 585 p->inuse_pages--;
586 mem_cgroup_uncharge_swap(ent);
587 } 586 }
587 if (!swap_count(count))
588 mem_cgroup_uncharge_swap(ent);
588 return count; 589 return count;
589} 590}
590 591
@@ -609,12 +610,19 @@ void swap_free(swp_entry_t entry)
609void swapcache_free(swp_entry_t entry, struct page *page) 610void swapcache_free(swp_entry_t entry, struct page *page)
610{ 611{
611 struct swap_info_struct *p; 612 struct swap_info_struct *p;
613 int ret;
612 614
613 if (page)
614 mem_cgroup_uncharge_swapcache(page, entry);
615 p = swap_info_get(entry); 615 p = swap_info_get(entry);
616 if (p) { 616 if (p) {
617 swap_entry_free(p, entry, SWAP_CACHE); 617 ret = swap_entry_free(p, entry, SWAP_CACHE);
618 if (page) {
619 bool swapout;
620 if (ret)
621 swapout = true; /* the end of swap out */
622 else
623 swapout = false; /* no more swap users! */
624 mem_cgroup_uncharge_swapcache(page, entry, swapout);
625 }
618 spin_unlock(&swap_lock); 626 spin_unlock(&swap_lock);
619 } 627 }
620 return; 628 return;