Le 08/04/2019 à 21:55, Brice Goglin a écrit :
> Le 08/04/2019 à 16:56, Dan Williams a écrit :
>> Yes, I agree with all of the above, but I think we need a way to fix
>> this independent of the HMAT data being present. The SLIT already
>> tells the kernel enough to let tooling figure out equidistant "local"
>> nodes. While the numa_node attribute will remain a singleton the
>> tooling needs to handle this case and can't assume the HMAT data will
>> be present.
> So you want to export the part of SLIT that is currently hidden to
> userspace because the corresponding nodes aren't registered?
>
> With the patch below, I get 17 17 28 28 in dax0.0/node_distance which
> means it's close to node0 and node1.
>
> The code is pretty much a duplicate of read_node_distance() in
> drivers/base/node.c. Not sure it's worth factorizing such small functions?
>
> The name "node_distance" (instead of "distance" for NUMA nodes) is also
> subject to discussion.

Here's a better patch that exports the existing routine for showing
node distances, and reuses it in dax/bus.c and nvdimm/pfn_devs.c:

# cat /sys/class/block/pmem1/device/node_distance 
28 28 17 17
# cat /sys/bus/dax/devices/dax0.0/node_distance 
17 17 28 28

By the way, it also handles the case where the nd_region has no
valid target_node (idea stolen from kmem.c).

Are there other places where it'd be useful to export that attribute?

Ideally we could just export it in the region sysfs directory,
but I can't find backlinks going from daxX.Y or pmemZ to that
region directory :/

Signed-off-by: Brice Goglin <[email protected]>

diff --git a/drivers/base/node.c b/drivers/base/node.c
index 8598fcb..5c6bce1 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -509,10 +509,9 @@ static ssize_t node_read_vmstat(struct device *dev,
 }
 static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
 
-static ssize_t node_read_distance(struct device *dev,
+ssize_t generic_node_distance_show(int nid,
                        struct device_attribute *attr, char *buf)
 {
-       int nid = dev->id;
        int len = 0;
        int i;
 
@@ -528,6 +527,13 @@ static ssize_t node_read_distance(struct device *dev,
        len += sprintf(buf + len, "\n");
        return len;
 }
+EXPORT_SYMBOL_GPL(generic_node_distance_show);
+
+static ssize_t node_read_distance(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       return generic_node_distance_show(dev->id, attr, buf);
+}
 static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
 
 static struct attribute *node_dev_attrs[] = {
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
index 2109cfe..37d750e 100644
--- a/drivers/dax/bus.c
+++ b/drivers/dax/bus.c
@@ -6,6 +6,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/dax.h>
+#include <linux/node.h>
 #include "dax-private.h"
 #include "bus.h"
 
@@ -295,6 +296,18 @@ static ssize_t target_node_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(target_node);
 
+static ssize_t node_distance_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct dev_dax *dev_dax = to_dev_dax(dev);
+       int nid = dev_dax_target_node(dev_dax);
+
+       if (nid < 0)
+               return 0;
+       return generic_node_distance_show(nid, attr, buf);
+}
+static DEVICE_ATTR(node_distance, S_IRUGO, node_distance_show, NULL);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
                char *buf)
 {
@@ -320,6 +333,7 @@ static umode_t dev_dax_visible(struct kobject *kobj, struct 
attribute *a, int n)
        &dev_attr_modalias.attr,
        &dev_attr_size.attr,
        &dev_attr_target_node.attr,
+       &dev_attr_node_distance.attr,
        NULL,
 };
 
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index d271bd73..5a0f55c 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/node.h>
 #include "nd-core.h"
 #include "pfn.h"
 #include "nd.h"
@@ -271,6 +272,18 @@ static ssize_t supported_alignments_show(struct device 
*dev,
 }
 static DEVICE_ATTR_RO(supported_alignments);
 
+static ssize_t node_distance_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct nd_region *nd_region = to_nd_region(dev->parent);
+       int nid = nd_region->target_node;
+
+       if (nid < 0)
+               return 0;
+       return generic_node_distance_show(nid, attr, buf);
+}
+static DEVICE_ATTR(node_distance, S_IRUGO, node_distance_show, NULL);
+
 static struct attribute *nd_pfn_attributes[] = {
        &dev_attr_mode.attr,
        &dev_attr_namespace.attr,
@@ -279,6 +292,7 @@ static ssize_t supported_alignments_show(struct device *dev,
        &dev_attr_resource.attr,
        &dev_attr_size.attr,
        &dev_attr_supported_alignments.attr,
+       &dev_attr_node_distance.attr,
        NULL,
 };
 
diff --git a/include/linux/node.h b/include/linux/node.h
index 1a557c5..949e7ed 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -150,6 +150,11 @@ extern int 
register_memory_node_under_compute_node(unsigned int mem_nid,
 extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
                                         node_registration_func_t unregister);
 #endif
+
+extern ssize_t generic_node_distance_show(int nid,
+                                         struct device_attribute *attr,
+                                         char *buf);
+
 #else
 static inline int __register_one_node(int nid)
 {
@@ -186,6 +191,13 @@ static inline void 
register_hugetlbfs_with_node(node_registration_func_t reg,
                                                node_registration_func_t unreg)
 {
 }
+
+static inline ssize_t generic_node_distance_show(int nid,
+                                                struct device_attribute *attr,
+                                                char *buf)
+{
+       return 0;
+}
 #endif
 
 #define to_node(device) container_of(device, struct node, dev)


_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to