mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
mm: memcontrol: account kernel stack per node
Currently the kernel stack is being accounted per-zone. There is no need to do that. In addition due to being per-zone, memcg has to keep a separate MEMCG_KERNEL_STACK_KB. Make the stat per-node and deprecate MEMCG_KERNEL_STACK_KB as memcg_stat_item is an extension of node_stat_item. In addition localize the kernel stack stats updates to account_kernel_stack(). Signed-off-by: Shakeel Butt <shakeelb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Roman Gushchin <guro@fb.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Link: http://lkml.kernel.org/r/20200630161539.1759185-1-shakeelb@google.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
fbc1ac9d09
commit
991e767385
@@ -276,13 +276,8 @@ static inline void free_thread_stack(struct task_struct *tsk)
|
||||
if (vm) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {
|
||||
mod_memcg_page_state(vm->pages[i],
|
||||
MEMCG_KERNEL_STACK_KB,
|
||||
-(int)(PAGE_SIZE / 1024));
|
||||
|
||||
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++)
|
||||
memcg_kmem_uncharge_page(vm->pages[i], 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_CACHED_STACKS; i++) {
|
||||
if (this_cpu_cmpxchg(cached_stacks[i],
|
||||
@@ -382,31 +377,14 @@ static void account_kernel_stack(struct task_struct *tsk, int account)
|
||||
void *stack = task_stack_page(tsk);
|
||||
struct vm_struct *vm = task_stack_vm_area(tsk);
|
||||
|
||||
BUILD_BUG_ON(IS_ENABLED(CONFIG_VMAP_STACK) && PAGE_SIZE % 1024 != 0);
|
||||
|
||||
if (vm) {
|
||||
int i;
|
||||
|
||||
BUG_ON(vm->nr_pages != THREAD_SIZE / PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {
|
||||
mod_zone_page_state(page_zone(vm->pages[i]),
|
||||
NR_KERNEL_STACK_KB,
|
||||
PAGE_SIZE / 1024 * account);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* All stack pages are in the same zone and belong to the
|
||||
* same memcg.
|
||||
*/
|
||||
struct page *first_page = virt_to_page(stack);
|
||||
|
||||
mod_zone_page_state(page_zone(first_page), NR_KERNEL_STACK_KB,
|
||||
THREAD_SIZE / 1024 * account);
|
||||
|
||||
mod_memcg_obj_state(stack, MEMCG_KERNEL_STACK_KB,
|
||||
account * (THREAD_SIZE / 1024));
|
||||
}
|
||||
/* All stack pages are in the same node. */
|
||||
if (vm)
|
||||
mod_lruvec_page_state(vm->pages[0], NR_KERNEL_STACK_KB,
|
||||
account * (THREAD_SIZE / 1024));
|
||||
else
|
||||
mod_lruvec_slab_state(stack, NR_KERNEL_STACK_KB,
|
||||
account * (THREAD_SIZE / 1024));
|
||||
}
|
||||
|
||||
static int memcg_charge_kernel_stack(struct task_struct *tsk)
|
||||
@@ -415,24 +393,23 @@ static int memcg_charge_kernel_stack(struct task_struct *tsk)
|
||||
struct vm_struct *vm = task_stack_vm_area(tsk);
|
||||
int ret;
|
||||
|
||||
BUILD_BUG_ON(IS_ENABLED(CONFIG_VMAP_STACK) && PAGE_SIZE % 1024 != 0);
|
||||
|
||||
if (vm) {
|
||||
int i;
|
||||
|
||||
BUG_ON(vm->nr_pages != THREAD_SIZE / PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {
|
||||
/*
|
||||
* If memcg_kmem_charge_page() fails, page->mem_cgroup
|
||||
* pointer is NULL, and both memcg_kmem_uncharge_page()
|
||||
* and mod_memcg_page_state() in free_thread_stack()
|
||||
* will ignore this page. So it's safe.
|
||||
* pointer is NULL, and memcg_kmem_uncharge_page() in
|
||||
* free_thread_stack() will ignore this page.
|
||||
*/
|
||||
ret = memcg_kmem_charge_page(vm->pages[i], GFP_KERNEL,
|
||||
0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mod_memcg_page_state(vm->pages[i],
|
||||
MEMCG_KERNEL_STACK_KB,
|
||||
PAGE_SIZE / 1024);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user