ANDROID: mm: add GCMA sysfs stats
Add GCMA statistics for stored, loaded, evicted, cached and discarded pages. Bug: 236887352 Bug: 391879760 Change-Id: I7238ad6a0ab357402cda3f2357b1a731c50c597a Signed-off-by: Minchan Kim <minchan@google.com> Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
ccf872ebe4
commit
80a603a57a
@@ -998,6 +998,13 @@ config GCMA
|
||||
|
||||
If unsure, say "n".
|
||||
|
||||
config GCMA_SYSFS
|
||||
bool "GCMA information through sysfs interface"
|
||||
depends on GCMA && SYSFS
|
||||
help
|
||||
This option exposes some sysfs attributes to get information
|
||||
from GCMA.
|
||||
|
||||
config MEM_SOFT_DIRTY
|
||||
bool "Track memory changes"
|
||||
depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS
|
||||
|
||||
@@ -120,6 +120,7 @@ obj-$(CONFIG_Z3FOLD) += z3fold.o
|
||||
obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
|
||||
obj-$(CONFIG_CMA) += cma.o
|
||||
obj-$(CONFIG_GCMA) += gcma.o
|
||||
obj-$(CONFIG_GCMA_SYSFS) += gcma_sysfs.o
|
||||
obj-$(CONFIG_NUMA) += numa.o
|
||||
obj-$(CONFIG_NUMA_MEMBLKS) += numa_memblks.o
|
||||
obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xarray.h>
|
||||
#include "gcma_sysfs.h"
|
||||
|
||||
/*
|
||||
* page->page_type : area id
|
||||
@@ -360,6 +361,7 @@ static struct page *gcma_alloc_page(void)
|
||||
ClearPageGCMAFree(page);
|
||||
set_page_count(page, 1);
|
||||
spin_unlock(&area->free_pages_lock);
|
||||
gcma_stat_inc(CACHED_PAGE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -380,6 +382,7 @@ static void __gcma_free_page(struct page *page)
|
||||
static void gcma_free_page(struct page *page)
|
||||
{
|
||||
__gcma_free_page(page);
|
||||
gcma_stat_dec(CACHED_PAGE);
|
||||
}
|
||||
|
||||
static inline void gcma_get_page(struct page *page)
|
||||
@@ -473,6 +476,7 @@ static void isolate_gcma_page(struct gcma_inode *inode, struct page *page)
|
||||
page_area_lock(page);
|
||||
reset_gcma_page(page);
|
||||
page_area_unlock(page);
|
||||
gcma_stat_dec(CACHED_PAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -584,6 +588,7 @@ again:
|
||||
xa_unlock(&inode->pages);
|
||||
|
||||
isolate_gcma_page(inode, page);
|
||||
gcma_stat_inc(DISCARDED_PAGE);
|
||||
put_gcma_inode(inode);
|
||||
}
|
||||
local_irq_enable();
|
||||
@@ -708,6 +713,8 @@ static void evict_gcma_lru_pages(unsigned long nr_request)
|
||||
}
|
||||
nr_evicted += isolated;
|
||||
}
|
||||
|
||||
gcma_stat_add(EVICTED_PAGE, nr_evicted);
|
||||
}
|
||||
|
||||
static void evict_gcma_pages(struct work_struct *work)
|
||||
@@ -804,6 +811,7 @@ copy:
|
||||
else
|
||||
rotate_lru_page(g_page);
|
||||
|
||||
gcma_stat_inc(STORED_PAGE);
|
||||
out_unlock:
|
||||
/*
|
||||
* If inode was just created but failed to add gcma page,
|
||||
@@ -849,6 +857,7 @@ static int gcma_cc_load_page(int hash_id, struct cleancache_filekey key,
|
||||
xa_unlock_irq(&inode->pages);
|
||||
|
||||
put_gcma_inode(inode);
|
||||
gcma_stat_inc(LOADED_PAGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include "gcma_sysfs.h"
|
||||
|
||||
extern struct kobject *vendor_mm_kobj;
|
||||
static struct kobject gcma_kobj;
|
||||
|
||||
static atomic64_t gcma_stats[NUM_OF_GCMA_STAT];
|
||||
|
||||
void gcma_stat_inc(enum gcma_stat_type type)
|
||||
{
|
||||
atomic64_inc(&gcma_stats[type]);
|
||||
}
|
||||
|
||||
void gcma_stat_dec(enum gcma_stat_type type)
|
||||
{
|
||||
atomic64_dec(&gcma_stats[type]);
|
||||
}
|
||||
|
||||
void gcma_stat_add(enum gcma_stat_type type, unsigned long delta)
|
||||
{
|
||||
atomic64_add(delta, &gcma_stats[type]);
|
||||
}
|
||||
|
||||
/*
|
||||
* This all compiles without CONFIG_SYSFS, but is a waste of space.
|
||||
*/
|
||||
|
||||
#define GCMA_ATTR_RO(_name) \
|
||||
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
|
||||
|
||||
static ssize_t stored_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[STORED_PAGE]));
|
||||
}
|
||||
GCMA_ATTR_RO(stored);
|
||||
|
||||
static ssize_t loaded_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[LOADED_PAGE]));
|
||||
}
|
||||
GCMA_ATTR_RO(loaded);
|
||||
|
||||
static ssize_t evicted_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[EVICTED_PAGE]));
|
||||
}
|
||||
GCMA_ATTR_RO(evicted);
|
||||
|
||||
static ssize_t cached_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[CACHED_PAGE]));
|
||||
}
|
||||
GCMA_ATTR_RO(cached);
|
||||
|
||||
static ssize_t discarded_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[DISCARDED_PAGE]));
|
||||
}
|
||||
GCMA_ATTR_RO(discarded);
|
||||
|
||||
static struct attribute *gcma_attrs[] = {
|
||||
&stored_attr.attr,
|
||||
&loaded_attr.attr,
|
||||
&evicted_attr.attr,
|
||||
&cached_attr.attr,
|
||||
&discarded_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(gcma);
|
||||
|
||||
static void gcma_kobj_release(struct kobject *obj)
|
||||
{
|
||||
/* Never released the static objects */
|
||||
}
|
||||
|
||||
static struct kobj_type gcma_ktype = {
|
||||
.release = gcma_kobj_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
.default_groups = gcma_groups,
|
||||
};
|
||||
|
||||
static int __init gcma_sysfs_init(void)
|
||||
{
|
||||
return kobject_init_and_add(&gcma_kobj, &gcma_ktype, mm_kobj, "gcma");
|
||||
}
|
||||
subsys_initcall(gcma_sysfs_init);
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __GCMA_SYSFS_H__
|
||||
#define __GCMA_SYSFS_H__
|
||||
|
||||
enum gcma_stat_type {
|
||||
STORED_PAGE,
|
||||
LOADED_PAGE,
|
||||
EVICTED_PAGE,
|
||||
CACHED_PAGE,
|
||||
DISCARDED_PAGE,
|
||||
NUM_OF_GCMA_STAT,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_GCMA_SYSFS
|
||||
void gcma_stat_inc(enum gcma_stat_type type);
|
||||
void gcma_stat_dec(enum gcma_stat_type type);
|
||||
void gcma_stat_add(enum gcma_stat_type type, unsigned long delta);
|
||||
#else /* CONFIG_GCMA_SYSFS */
|
||||
static inline void gcma_stat_inc(enum gcma_stat_type type) {}
|
||||
static inline void gcma_stat_dec(enum gcma_stat_type type) {}
|
||||
static inline void gcma_stat_add(enum gcma_stat_type type,
|
||||
unsigned long delta) {}
|
||||
#endif /* CONFIG_GCMA_SYSFS */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user