Skip to content

Commit

Permalink
memcg: add per-memcg vmalloc stat
Browse files Browse the repository at this point in the history
The kvmalloc* allocation functions can fallback to vmalloc allocations
and more often on long running machines.  In addition the kernel does
have __GFP_ACCOUNT kvmalloc* calls.  So, often on long running machines,
the memory.stat does not tell the complete picture which type of memory
is charged to the memcg.  So add a per-memcg vmalloc stat.

[shakeelb@google.com: page_memcg() within rcu lock, per Muchun]
  Link: https://lkml.kernel.org/r/20211222052457.1960701-1-shakeelb@google.com
[akpm@linux-foundation.org: remove cast, per Muchun]
[shakeelb@google.com: remove area->page[0] checks and move to page by page accounting per Michal]
  Link: https://lkml.kernel.org/r/20220104222341.3972772-1-shakeelb@google.com

Link: https://lkml.kernel.org/r/20211221215336.1922823-1-shakeelb@google.com
Signed-off-by: Shakeel Butt <shakeelb@google.com>
Acked-by: Roman Gushchin <guro@fb.com>
Reviewed-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Shakeel Butt authored and Linus Torvalds committed Jan 15, 2022
1 parent 06b2c3b commit 4e5aa1f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Documentation/admin-guide/cgroup-v2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,9 @@ PAGE_SIZE multiple when read back.
sock (npn)
Amount of memory used in network transmission buffers

vmalloc (npn)
Amount of memory used for vmap backed memory.

shmem
Amount of cached filesystem data that is swap-backed,
such as tmpfs, shm segments, shared anonymous mmap()s
Expand Down
21 changes: 21 additions & 0 deletions include/linux/memcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum memcg_stat_item {
MEMCG_SWAP = NR_VM_NODE_STAT_ITEMS,
MEMCG_SOCK,
MEMCG_PERCPU_B,
MEMCG_VMALLOC,
MEMCG_NR_STAT,
};

Expand Down Expand Up @@ -992,6 +993,21 @@ static inline void mod_memcg_state(struct mem_cgroup *memcg,
local_irq_restore(flags);
}

static inline void mod_memcg_page_state(struct page *page,
int idx, int val)
{
struct mem_cgroup *memcg;

if (mem_cgroup_disabled())
return;

rcu_read_lock();
memcg = page_memcg(page);
if (memcg)
mod_memcg_state(memcg, idx, val);
rcu_read_unlock();
}

static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx)
{
return READ_ONCE(memcg->vmstats.state[idx]);
Expand Down Expand Up @@ -1447,6 +1463,11 @@ static inline void mod_memcg_state(struct mem_cgroup *memcg,
{
}

static inline void mod_memcg_page_state(struct page *page,
int idx, int val)
{
}

static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx)
{
return 0;
Expand Down
1 change: 1 addition & 0 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,7 @@ static const struct memory_stat memory_stats[] = {
{ "pagetables", NR_PAGETABLE },
{ "percpu", MEMCG_PERCPU_B },
{ "sock", MEMCG_SOCK },
{ "vmalloc", MEMCG_VMALLOC },
{ "shmem", NR_SHMEM },
{ "file_mapped", NR_FILE_MAPPED },
{ "file_dirty", NR_FILE_DIRTY },
Expand Down
13 changes: 11 additions & 2 deletions mm/vmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/kmemleak.h>
#include <linux/atomic.h>
#include <linux/compiler.h>
#include <linux/memcontrol.h>
#include <linux/llist.h>
#include <linux/bitops.h>
#include <linux/rbtree_augmented.h>
Expand Down Expand Up @@ -2623,12 +2624,13 @@ static void __vunmap(const void *addr, int deallocate_pages)

if (deallocate_pages) {
unsigned int page_order = vm_area_page_order(area);
int i;
int i, step = 1U << page_order;

for (i = 0; i < area->nr_pages; i += 1U << page_order) {
for (i = 0; i < area->nr_pages; i += step) {
struct page *page = area->pages[i];

BUG_ON(!page);
mod_memcg_page_state(page, MEMCG_VMALLOC, -step);
__free_pages(page, page_order);
cond_resched();
}
Expand Down Expand Up @@ -2955,6 +2957,13 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
page_order, nr_small_pages, area->pages);

atomic_long_add(area->nr_pages, &nr_vmalloc_pages);
if (gfp_mask & __GFP_ACCOUNT) {
int i, step = 1U << page_order;

for (i = 0; i < area->nr_pages; i += step)
mod_memcg_page_state(area->pages[i], MEMCG_VMALLOC,
step);
}

/*
* If not enough pages were obtained to accomplish an
Expand Down

0 comments on commit 4e5aa1f

Please sign in to comment.