Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2262185c authored by Roman Gushchin's avatar Roman Gushchin Committed by Linus Torvalds
Browse files

mm: per-cgroup memory reclaim stats

Track the following reclaim counters for every memory cgroup: PGREFILL,
PGSCAN, PGSTEAL, PGACTIVATE, PGDEACTIVATE, PGLAZYFREE and PGLAZYFREED.

These values are exposed using the memory.stats interface of cgroup v2.

The meaning of each value is the same as for global counters, available
using /proc/vmstat.

Also, for consistency, rename mem_cgroup_count_vm_event() to
count_memcg_event_mm().

Link: http://lkml.kernel.org/r/1494530183-30808-1-git-send-email-guro@fb.com


Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
Suggested-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Acked-by: default avatarVladimir Davydov <vdavydov.dev@gmail.com>
Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Balbir Singh <bsingharora@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 94f4a161
Loading
Loading
Loading
Loading
+28 −0
Original line number Original line Diff line number Diff line
@@ -956,6 +956,34 @@ PAGE_SIZE multiple when read back.


		Number of times a shadow node has been reclaimed
		Number of times a shadow node has been reclaimed


	  pgrefill

		Amount of scanned pages (in an active LRU list)

	  pgscan

		Amount of scanned pages (in an inactive LRU list)

	  pgsteal

		Amount of reclaimed pages

	  pgactivate

		Amount of pages moved to the active LRU list

	  pgdeactivate

		Amount of pages moved to the inactive LRU lis

	  pglazyfree

		Amount of pages postponed to be freed under memory pressure

	  pglazyfreed

		Amount of reclaimed lazyfree pages

  memory.swap.current
  memory.swap.current


	A read-only single value file which exists on non-root
	A read-only single value file which exists on non-root
+1 −1
Original line number Original line Diff line number Diff line
@@ -1213,7 +1213,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
	case IOMAP_MAPPED:
	case IOMAP_MAPPED:
		if (iomap.flags & IOMAP_F_NEW) {
		if (iomap.flags & IOMAP_F_NEW) {
			count_vm_event(PGMAJFAULT);
			count_vm_event(PGMAJFAULT);
			mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
			count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
			major = VM_FAULT_MAJOR;
			major = VM_FAULT_MAJOR;
		}
		}
		error = dax_insert_mapping(mapping, iomap.bdev, iomap.dax_dev,
		error = dax_insert_mapping(mapping, iomap.bdev, iomap.dax_dev,
+1 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,7 @@ static int ncp_file_mmap_fault(struct vm_fault *vmf)
	 * -- nyc
	 * -- nyc
	 */
	 */
	count_vm_event(PGMAJFAULT);
	count_vm_event(PGMAJFAULT);
	mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
	count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
	return VM_FAULT_MAJOR;
	return VM_FAULT_MAJOR;
}
}


+45 −3
Original line number Original line Diff line number Diff line
@@ -357,6 +357,17 @@ static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
}
}
struct mem_cgroup *mem_cgroup_from_id(unsigned short id);
struct mem_cgroup *mem_cgroup_from_id(unsigned short id);


static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
{
	struct mem_cgroup_per_node *mz;

	if (mem_cgroup_disabled())
		return NULL;

	mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
	return mz->memcg;
}

/**
/**
 * parent_mem_cgroup - find the accounting parent of a memcg
 * parent_mem_cgroup - find the accounting parent of a memcg
 * @memcg: memcg whose parent to find
 * @memcg: memcg whose parent to find
@@ -546,7 +557,22 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
						gfp_t gfp_mask,
						gfp_t gfp_mask,
						unsigned long *total_scanned);
						unsigned long *total_scanned);


static inline void mem_cgroup_count_vm_event(struct mm_struct *mm,
static inline void count_memcg_events(struct mem_cgroup *memcg,
				      enum vm_event_item idx,
				      unsigned long count)
{
	if (!mem_cgroup_disabled())
		this_cpu_add(memcg->stat->events[idx], count);
}

static inline void count_memcg_page_event(struct page *page,
					  enum memcg_stat_item idx)
{
	if (page->mem_cgroup)
		count_memcg_events(page->mem_cgroup, idx, 1);
}

static inline void count_memcg_event_mm(struct mm_struct *mm,
					enum vm_event_item idx)
					enum vm_event_item idx)
{
{
	struct mem_cgroup *memcg;
	struct mem_cgroup *memcg;
@@ -675,6 +701,11 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
	return NULL;
	return NULL;
}
}


static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
{
	return NULL;
}

static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
{
{
	return true;
	return true;
@@ -789,8 +820,19 @@ static inline void mem_cgroup_split_huge_fixup(struct page *head)
{
{
}
}


static inline void count_memcg_events(struct mem_cgroup *memcg,
				      enum vm_event_item idx,
				      unsigned long count)
{
}

static inline void count_memcg_page_event(struct page *page,
					  enum memcg_stat_item idx)
{
}

static inline
static inline
void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
void count_memcg_event_mm(struct mm_struct *mm, enum vm_event_item idx)
{
{
}
}
#endif /* CONFIG_MEMCG */
#endif /* CONFIG_MEMCG */
+1 −1
Original line number Original line Diff line number Diff line
@@ -2265,7 +2265,7 @@ int filemap_fault(struct vm_fault *vmf)
		/* No page in the page cache at all */
		/* No page in the page cache at all */
		do_sync_mmap_readahead(vmf->vma, ra, file, offset);
		do_sync_mmap_readahead(vmf->vma, ra, file, offset);
		count_vm_event(PGMAJFAULT);
		count_vm_event(PGMAJFAULT);
		mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
		count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
		ret = VM_FAULT_MAJOR;
		ret = VM_FAULT_MAJOR;
retry_find:
retry_find:
		page = find_get_page(mapping, offset);
		page = find_get_page(mapping, offset);
Loading