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
