mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
memcg: move charge of file pages
This patch adds support for moving charge of file pages, which include normal file, tmpfs file and swaps of tmpfs file. It's enabled by setting bit 1 of <target cgroup>/memory.move_charge_at_immigrate. Unlike the case of anonymous pages, file pages(and swaps) in the range mmapped by the task will be moved even if the task hasn't done page fault, i.e. they might not be the task's "RSS", but other task's "RSS" that maps the same file. And mapcount of the page is ignored(the page can be moved even if page_mapcount(page) > 1). So, conditions that the page/swap should be met to be moved is that it must be in the range mmapped by the target task and it must be charged to the old cgroup. [[email protected]: coding-style fixes] [[email protected]: fix warning] Signed-off-by: Daisuke Nishimura <[email protected]> Acked-by: KAMEZAWA Hiroyuki <[email protected]> Cc: Balbir Singh <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
90254a6583
commit
87946a7228
4 changed files with 125 additions and 18 deletions
64
mm/shmem.c
64
mm/shmem.c
|
|
@ -2559,6 +2559,45 @@ out4:
|
|||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
|
||||
/**
|
||||
* mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
|
||||
* @inode: the inode to be searched
|
||||
* @pgoff: the offset to be searched
|
||||
* @pagep: the pointer for the found page to be stored
|
||||
* @ent: the pointer for the found swap entry to be stored
|
||||
*
|
||||
* If a page is found, refcount of it is incremented. Callers should handle
|
||||
* these refcount.
|
||||
*/
|
||||
void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
|
||||
struct page **pagep, swp_entry_t *ent)
|
||||
{
|
||||
swp_entry_t entry = { .val = 0 }, *ptr;
|
||||
struct page *page = NULL;
|
||||
struct shmem_inode_info *info = SHMEM_I(inode);
|
||||
|
||||
if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
|
||||
goto out;
|
||||
|
||||
spin_lock(&info->lock);
|
||||
ptr = shmem_swp_entry(info, pgoff, NULL);
|
||||
#ifdef CONFIG_SWAP
|
||||
if (ptr && ptr->val) {
|
||||
entry.val = ptr->val;
|
||||
page = find_get_page(&swapper_space, entry.val);
|
||||
} else
|
||||
#endif
|
||||
page = find_get_page(inode->i_mapping, pgoff);
|
||||
if (ptr)
|
||||
shmem_swp_unmap(ptr);
|
||||
spin_unlock(&info->lock);
|
||||
out:
|
||||
*pagep = page;
|
||||
*ent = entry;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_SHMEM */
|
||||
|
||||
/*
|
||||
|
|
@ -2598,6 +2637,31 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
|
||||
/**
|
||||
* mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
|
||||
* @inode: the inode to be searched
|
||||
* @pgoff: the offset to be searched
|
||||
* @pagep: the pointer for the found page to be stored
|
||||
* @ent: the pointer for the found swap entry to be stored
|
||||
*
|
||||
* If a page is found, refcount of it is incremented. Callers should handle
|
||||
* these refcount.
|
||||
*/
|
||||
void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
|
||||
struct page **pagep, swp_entry_t *ent)
|
||||
{
|
||||
struct page *page = NULL;
|
||||
|
||||
if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
|
||||
goto out;
|
||||
page = find_get_page(inode->i_mapping, pgoff);
|
||||
out:
|
||||
*pagep = page;
|
||||
*ent = (swp_entry_t){ .val = 0 };
|
||||
}
|
||||
#endif
|
||||
|
||||
#define shmem_vm_ops generic_file_vm_ops
|
||||
#define shmem_file_operations ramfs_file_operations
|
||||
#define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev)
|
||||
|
|
|
|||
Loading…
Reference in a new issue