提交 88da6696 编写于 作者: F Fan Du 提交者: Zheng Zengkai

mm: introduce and export pgdat peer_node

euleros inclusion
category: feature
feature: etmem
bugzilla: 48246

-------------------------------------------------

Each CPU socket can have 1 DRAM and 1 PMEM node, we call them "peer nodes".
Migration between DRAM and PMEM will by default happen between peer nodes.

It's a temp solution. In multiple memory layers, a node can have both
promotion and demotion targets instead of a single peer node. User space
may also be able to infer promotion/demotion targets based on future
HMAT info.
Signed-off-by: NFan Du <fan.du@intel.com>
Signed-off-by: NFengguang Wu <fengguang.wu@intel.com>
Signed-off-by: NShijie Luo <luoshijie1@huawei.com>
Signed-off-by: NKemeng Shi <shikemeng@huawei.com>
Reviewed-by: Nlouhongxiang <louhongxiang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 ca25518c
...@@ -558,6 +558,16 @@ static ssize_t type_show(struct device *dev, ...@@ -558,6 +558,16 @@ static ssize_t type_show(struct device *dev,
} }
static DEVICE_ATTR_RO(type); static DEVICE_ATTR_RO(type);
static ssize_t peer_node_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nid = dev->id;
struct pglist_data *pgdat = NODE_DATA(nid);
return sprintf(buf, "%d\n", pgdat->peer_node);
}
static DEVICE_ATTR_RO(peer_node);
static struct attribute *node_dev_attrs[] = { static struct attribute *node_dev_attrs[] = {
&dev_attr_cpumap.attr, &dev_attr_cpumap.attr,
&dev_attr_cpulist.attr, &dev_attr_cpulist.attr,
...@@ -566,6 +576,7 @@ static struct attribute *node_dev_attrs[] = { ...@@ -566,6 +576,7 @@ static struct attribute *node_dev_attrs[] = {
&dev_attr_distance.attr, &dev_attr_distance.attr,
&dev_attr_vmstat.attr, &dev_attr_vmstat.attr,
&dev_attr_type.attr, &dev_attr_type.attr,
&dev_attr_peer_node.attr,
NULL NULL
}; };
ATTRIBUTE_GROUPS(node_dev); ATTRIBUTE_GROUPS(node_dev);
......
...@@ -2414,6 +2414,7 @@ static inline unsigned long get_num_physpages(void) ...@@ -2414,6 +2414,7 @@ static inline unsigned long get_num_physpages(void)
return phys_pages; return phys_pages;
} }
int find_best_peer_node(int nid);
/* /*
* Using memblock node mappings, an architecture may initialise its * Using memblock node mappings, an architecture may initialise its
* zones, allocate the backing mem_map and account for memory holes in an * zones, allocate the backing mem_map and account for memory holes in an
......
...@@ -806,6 +806,7 @@ typedef struct pglist_data { ...@@ -806,6 +806,7 @@ typedef struct pglist_data {
/* Per-node vmstats */ /* Per-node vmstats */
struct per_cpu_nodestat __percpu *per_cpu_nodestats; struct per_cpu_nodestat __percpu *per_cpu_nodestats;
atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS]; atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];
int peer_node;
} pg_data_t; } pg_data_t;
#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
......
...@@ -7400,6 +7400,34 @@ static void check_for_memory(pg_data_t *pgdat, int nid) ...@@ -7400,6 +7400,34 @@ static void check_for_memory(pg_data_t *pgdat, int nid)
} }
} }
/*
* Return the nearest peer node in terms of *locality*
* E.g. peer of node 0 is node 2 per SLIT
* node distances:
* node 0 1 2 3
* 0: 10 21 17 28
* 1: 21 10 28 17
* 2: 17 28 10 28
* 3: 28 17 28 10
*/
int find_best_peer_node(int nid)
{
int n, val;
int min_val = INT_MAX;
int peer = NUMA_NO_NODE;
for_each_online_node(n) {
if (n == nid)
continue;
val = node_distance(nid, n);
if (val < min_val) {
min_val = val;
peer = n;
}
}
return peer;
}
/* /*
* Some architecturs, e.g. ARC may have ZONE_HIGHMEM below ZONE_NORMAL. For * Some architecturs, e.g. ARC may have ZONE_HIGHMEM below ZONE_NORMAL. For
* such cases we allow max_zone_pfn sorted in the descending order * such cases we allow max_zone_pfn sorted in the descending order
...@@ -7506,6 +7534,7 @@ void __init free_area_init(unsigned long *max_zone_pfn) ...@@ -7506,6 +7534,7 @@ void __init free_area_init(unsigned long *max_zone_pfn)
if (pgdat->node_present_pages) if (pgdat->node_present_pages)
node_set_state(nid, N_MEMORY); node_set_state(nid, N_MEMORY);
check_for_memory(pgdat, nid); check_for_memory(pgdat, nid);
pgdat->peer_node = find_best_peer_node(nid);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册