diff mbox series

[v2,13/18] libnvdimm: Export the target_node attribute for regions and namespaces

Message ID 157401274500.43284.2369509941678577768.stgit@dwillia2-desk3.amr.corp.intel.com (mailing list archive)
State Not Applicable, archived
Headers show
Series Memory Hierarchy: Enable target node lookups for reserved memory | expand

Commit Message

Dan Williams Nov. 17, 2019, 5:45 p.m. UTC
Aneesh points out that some platforms may have "local" attached
persistent memory and "remote" persistent memory that map to the same
"online" node, or persistent memory devices with different performance
properties. In this case 'numa_node' is identical for the two instances,
but 'target_node' is differentiated so platform firmware can communicate
distinct performance properties per range. Expose 'target_node' by
default to allow for disambiguation of devices that share the same
numa_map_to_online_node() result.

Reported-by: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/nvdimm/bus.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Aneesh Kumar K.V Nov. 18, 2019, 9:45 a.m. UTC | #1
Dan Williams <dan.j.williams@intel.com> writes:

> Aneesh points out that some platforms may have "local" attached
> persistent memory and "remote" persistent memory that map to the same
> "online" node, or persistent memory devices with different performance
> properties. In this case 'numa_node' is identical for the two instances,
> but 'target_node' is differentiated so platform firmware can communicate
> distinct performance properties per range. Expose 'target_node' by
> default to allow for disambiguation of devices that share the same
> numa_map_to_online_node() result.
>

Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>

> Reported-by: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  drivers/nvdimm/bus.c |   29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
>
> diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
> index 1d330d46d036..f76d709426f7 100644
> --- a/drivers/nvdimm/bus.c
> +++ b/drivers/nvdimm/bus.c
> @@ -685,17 +685,46 @@ static ssize_t numa_node_show(struct device *dev,
>  }
>  static DEVICE_ATTR_RO(numa_node);
>  
> +static int nvdimm_dev_to_target_node(struct device *dev)
> +{
> +	struct device *parent = dev->parent;
> +	struct nd_region *nd_region = NULL;
> +
> +	if (is_nd_region(dev))
> +		nd_region = to_nd_region(dev);
> +	else if (parent && is_nd_region(parent))
> +		nd_region = to_nd_region(parent);
> +
> +	if (!nd_region)
> +		return NUMA_NO_NODE;
> +	return nd_region->target_node;
> +}
> +
> +static ssize_t target_node_show(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +	return sprintf(buf, "%d\n", nvdimm_dev_to_target_node(dev));
> +}
> +static DEVICE_ATTR_RO(target_node);
> +
>  static struct attribute *nd_numa_attributes[] = {
>  	&dev_attr_numa_node.attr,
> +	&dev_attr_target_node.attr,
>  	NULL,
>  };
>  
>  static umode_t nd_numa_attr_visible(struct kobject *kobj, struct attribute *a,
>  		int n)
>  {
> +	struct device *dev = container_of(kobj, typeof(*dev), kobj);
> +
>  	if (!IS_ENABLED(CONFIG_NUMA))
>  		return 0;
>  
> +	if (a == &dev_attr_target_node.attr &&
> +			nvdimm_dev_to_target_node(dev) == NUMA_NO_NODE)
> +		return 0;
> +
>  	return a->mode;
>  }
>
diff mbox series

Patch

diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 1d330d46d036..f76d709426f7 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -685,17 +685,46 @@  static ssize_t numa_node_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(numa_node);
 
+static int nvdimm_dev_to_target_node(struct device *dev)
+{
+	struct device *parent = dev->parent;
+	struct nd_region *nd_region = NULL;
+
+	if (is_nd_region(dev))
+		nd_region = to_nd_region(dev);
+	else if (parent && is_nd_region(parent))
+		nd_region = to_nd_region(parent);
+
+	if (!nd_region)
+		return NUMA_NO_NODE;
+	return nd_region->target_node;
+}
+
+static ssize_t target_node_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", nvdimm_dev_to_target_node(dev));
+}
+static DEVICE_ATTR_RO(target_node);
+
 static struct attribute *nd_numa_attributes[] = {
 	&dev_attr_numa_node.attr,
+	&dev_attr_target_node.attr,
 	NULL,
 };
 
 static umode_t nd_numa_attr_visible(struct kobject *kobj, struct attribute *a,
 		int n)
 {
+	struct device *dev = container_of(kobj, typeof(*dev), kobj);
+
 	if (!IS_ENABLED(CONFIG_NUMA))
 		return 0;
 
+	if (a == &dev_attr_target_node.attr &&
+			nvdimm_dev_to_target_node(dev) == NUMA_NO_NODE)
+		return 0;
+
 	return a->mode;
 }