[PATCH v3 6/7] mm: demotion: expose per-node demotion targets via sysfs

Jagdish Gediya
2022-04-22T21:59:04Z

Kernel prepares per-node demotion target list based on
node_states[N_DEMOTION_TARGETS], If enabled through sysfs,
demotion kicks in during reclaim, and pages get migrated
according to demotion target list prepared by kernel.

It is helpful to know demotion target list prepared by
kernel to understand the demotion behaviour, so add
interface /sys/devices/system/node/nodeX/demotion_targets
to view per-node demotion targets via sysfs.

Signed-off-by: Jagdish Gediya <jvgediya@linux.ibm.com>
---
drivers/base/node.c | 10 ++++++++++
include/linux/migrate.h | 1 +
mm/migrate.c | 17 +++++++++++++++++
3 files changed, 28 insertions(+)

diff --git a/drivers/base/node.c b/drivers/base/node.c
index e03eedbc421b..92326219aac2 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -561,11 +561,21 @@ static ssize_t node_read_distance(struct device *dev,
}
static DEVICE_ATTR(distance, 0444, node_read_distance, NULL);

+static ssize_t demotion_targets_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ nodemask_t demotion_targets = node_get_demotion_targets(dev->id);
+
+ return sysfs_emit(buf, "%*pbl\n", nodemask_pr_args(&demotion_targets));
+}
+static DEVICE_ATTR_RO(demotion_targets);
+
static struct attribute *node_dev_attrs[] = {
&dev_attr_meminfo.attr,
&dev_attr_numastat.attr,
&dev_attr_distance.attr,
&dev_attr_vmstat.attr,
+ &dev_attr_demotion_targets.attr,
NULL
};

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 90e75d5a54d6..072019441a24 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -173,6 +173,7 @@ int migrate_vma_setup(struct migrate_vma *args);
void migrate_vma_pages(struct migrate_vma *migrate);
void migrate_vma_finalize(struct migrate_vma *migrate);
int next_demotion_node(int node);
+nodemask_t node_get_demotion_targets(int node);

#else /* CONFIG_MIGRATION disabled: */

diff --git a/mm/migrate.c b/mm/migrate.c
index 5b92a09fbe4a..da864831bc0c 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2187,6 +2187,23 @@ struct demotion_nodes {

static struct demotion_nodes *node_demotion __read_mostly;

+nodemask_t node_get_demotion_targets(int node)
+{
+ nodemask_t demotion_targets = NODE_MASK_NONE;
+ unsigned short target_nr;
+
+ if (!node_demotion)
+ return NODE_MASK_NONE;
+
+ rcu_read_lock();
+ target_nr = READ_ONCE(node_demotion[node].nr);
+ for (int i = 0; i < target_nr; i++)
+ node_set(READ_ONCE(node_demotion[node].nodes[i]), demotion_targets);
+ rcu_read_unlock();
+
+ return demotion_targets;
+}
+
/**
* next_demotion_node() - Get the next node in the demotion path
* @node: The starting node to lookup the next node
--
2.35.1