mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
memcg: move charges of anonymous swap
This patch is another core part of this move-charge-at-task-migration feature. It enables moving charges of anonymous swaps. To move the charge of swap, we need to exchange swap_cgroup's record. In current implementation, swap_cgroup's record is protected by: - page lock: if the entry is on swap cache. - swap_lock: if the entry is not on swap cache. This works well in usual swap-in/out activity. But this behavior make the feature of moving swap charge check many conditions to exchange swap_cgroup's record safely. So I changed modification of swap_cgroup's recored(swap_cgroup_record()) to use xchg, and define a new function to cmpxchg swap_cgroup's record. This patch also enables moving charge of non pte_present but not uncharged swap caches, which can be exist on swap-out path, by getting the target pages via find_get_page() as do_mincore() does. [[email protected]: fix ia64 build] [[email protected]: fix typos] Signed-off-by: Daisuke Nishimura <[email protected]> Cc: Balbir Singh <[email protected]> Acked-by: KAMEZAWA Hiroyuki <[email protected]> Cc: Li Zefan <[email protected]> Cc: Paul Menage <[email protected]> Cc: Daisuke Nishimura <[email protected]> Signed-off-by: KOSAKI Motohiro <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
8033b97c9b
commit
024914477e
6 changed files with 223 additions and 38 deletions
|
|
@ -723,6 +723,37 @@ int free_swap_and_cache(swp_entry_t entry)
|
|||
return p != NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
|
||||
/**
|
||||
* mem_cgroup_count_swap_user - count the user of a swap entry
|
||||
* @ent: the swap entry to be checked
|
||||
* @pagep: the pointer for the swap cache page of the entry to be stored
|
||||
*
|
||||
* Returns the number of the user of the swap entry. The number is valid only
|
||||
* for swaps of anonymous pages.
|
||||
* If the entry is found on swap cache, the page is stored to pagep with
|
||||
* refcount of it being incremented.
|
||||
*/
|
||||
int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep)
|
||||
{
|
||||
struct page *page;
|
||||
struct swap_info_struct *p;
|
||||
int count = 0;
|
||||
|
||||
page = find_get_page(&swapper_space, ent.val);
|
||||
if (page)
|
||||
count += page_mapcount(page);
|
||||
p = swap_info_get(ent);
|
||||
if (p) {
|
||||
count += swap_count(p->swap_map[swp_offset(ent)]);
|
||||
spin_unlock(&swap_lock);
|
||||
}
|
||||
|
||||
*pagep = page;
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
/*
|
||||
* Find the swap type that corresponds to given device (if any).
|
||||
|
|
|
|||
Loading…
Reference in a new issue