memcg: swap cgroup for remembering usage
For accounting swap, we need a record per swap entry, at least. This patch adds following function. - swap_cgroup_swapon() .... called from swapon - swap_cgroup_swapoff() ... called at the end of swapoff. - swap_cgroup_record() .... record information of swap entry. - swap_cgroup_lookup() .... lookup information of swap entry. This patch just implements "how to record information". No actual method for limit the usage of swap. These routine uses flat table to record and lookup. "wise" lookup system like radix-tree requires requires memory allocation at new records but swap-out is usually called under memory shortage (or memcg hits limit.) So, I used static allocation. (maybe dynamic allocation is not very hard but it adds additional memory allocation in memory shortage path.) Note1: In this, we use pointer to record information and this means 8bytes per swap entry. I think we can reduce this when we create "id of cgroup" in the range of 0-65535 or 0-255. Reported-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Reviewed-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Tested-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Reported-by: Hugh Dickins <hugh@veritas.com> Reported-by: Balbir Singh <balbir@linux.vnet.ibm.com> Reported-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Pavel Emelianov <xemul@openvz.org> Cc: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
c077719be8
commit
27a7faa077
@ -33,6 +33,7 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <linux/swapops.h>
|
||||
#include <linux/page_cgroup.h>
|
||||
|
||||
static DEFINE_SPINLOCK(swap_lock);
|
||||
static unsigned int nr_swapfiles;
|
||||
@ -1494,6 +1495,9 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
|
||||
spin_unlock(&swap_lock);
|
||||
mutex_unlock(&swapon_mutex);
|
||||
vfree(swap_map);
|
||||
/* Destroy swap account informatin */
|
||||
swap_cgroup_swapoff(type);
|
||||
|
||||
inode = mapping->host;
|
||||
if (S_ISBLK(inode->i_mode)) {
|
||||
struct block_device *bdev = I_BDEV(inode);
|
||||
@ -1811,6 +1815,11 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
|
||||
}
|
||||
swap_map[page_nr] = SWAP_MAP_BAD;
|
||||
}
|
||||
|
||||
error = swap_cgroup_swapon(type, maxpages);
|
||||
if (error)
|
||||
goto bad_swap;
|
||||
|
||||
nr_good_pages = swap_header->info.last_page -
|
||||
swap_header->info.nr_badpages -
|
||||
1 /* header page */;
|
||||
@ -1882,6 +1891,7 @@ bad_swap:
|
||||
bd_release(bdev);
|
||||
}
|
||||
destroy_swap_extents(p);
|
||||
swap_cgroup_swapoff(type);
|
||||
bad_swap_2:
|
||||
spin_lock(&swap_lock);
|
||||
p->swap_file = NULL;
|
||||
|
Reference in New Issue
Block a user