libnvdimm: Add of_node to region and bus descriptors
Subsystems (3)
PATCH 1/3 libnvdimm: Add of_node to region and bus descriptors
We want to be able to cross reference the region and bus devices with the device tree node that they were spawned from. libNVDIMM handles creating the actual devices for these internally, so we need to pass in a pointer to the relevant node in the descriptor.
--- drivers/nvdimm/bus.c | 1 + drivers/nvdimm/region_devs.c | 1 + include/linux/libnvdimm.h | 3 +++ 3 files changed, 5 insertions(+)
drivers/nvdimm/bus.c +1 -0
@@ -358,6 +358,7 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent, nvdimm_bus->dev.release = nvdimm_bus_release; nvdimm_bus->dev.groups = nd_desc->attr_groups; nvdimm_bus->dev.bus = &nvdimm_bus_type; + nvdimm_bus->dev.of_node = nd_desc->of_node;dev_set_name (&nvdimm_bus->dev,"ndbus%d" , nvdimm_bus->id); rc =device_register (&nvdimm_bus->dev);if (rc) {
drivers/nvdimm/region_devs.c +1 -0
@@ -992,6 +992,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, dev->parent = &nvdimm_bus->dev; dev->type = dev_type; dev->groups = ndr_desc->attr_groups; + dev->of_node = ndr_desc->of_node; nd_region->ndr_size =resource_size (ndr_desc->res); nd_region->ndr_start = ndr_desc->res->start;nd_device_register (dev);
include/linux/libnvdimm.h +3 -0
@@ -65,12 +65,14 @@ typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc); +struct device_node ;struct nvdimm_bus_descriptor {const struct attribute_group **attr_groups;unsigned long bus_dsm_mask;unsigned long cmd_mask;struct module *module;char *provider_name; +struct device_node *of_node;ndctl_fn ndctl;int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc); int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,
@@ -112,6 +114,7 @@ struct nd_region_desc {int num_lanes;int numa_node;unsigned long flags; +struct device_node *of_node; };struct device ;
Signature · 6 lines
2.9.5 _______________________________________________ Linux-nvdimm mailing list [email protected] https://lists.01.org/mailman/listinfo/linux-nvdimm
A message that is not in the archive (sent off-list or not yet received): 20171115175131.23631-1-oohall-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
PATCH 2/3 libnvdimm: Add a device-tree interface
A fairly bare-bones set of device-tree bindings so libnvdimm can be used on powerpc and other device-tree based platforms.
--- .../devicetree/bindings/nvdimm/nvdimm-bus.txt | 69 +++++++ MAINTAINERS | 8 + drivers/nvdimm/Kconfig | 10 + drivers/nvdimm/Makefile | 1 + drivers/nvdimm/of_nvdimm.c | 202 +++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt create mode 100644 drivers/nvdimm/of_nvdimm.c
Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt new file +69 -0
@@ -0,0 +1,69 @@ +Device-tree bindings for nonvolatile-memory / NVDIMMs +----------------------------------------------------- + +Non-volatile DIMMs are memory modules used to provide (cacheable) main memory that +retains its contents across power cycles. In more practical terms, they are kind +of storage device where the contents can be accessed by the CPU directly, +rather than indirectly via a storage controller or similar. This can provide +substantial performance improvements for applications designed to take +advantage of in-memory storage. + +This binding provides a way to describe memory regions that should be managed +by an NVDIMM storage driver (libNVDIMM in Linux) and some of the associated +metadata. The binding itself is split into two main parts: A container bus and +its sub-nodes which describe which memory address ranges corresponding to +NVDIMM backed memory. + +Bindings for the container bus: +------------------------------ + +Required properties: + - compatible = "nvdimm-bus"; + - ranges; + A blank ranges property is required because the sub-nodes have + addresses in the system's physical address space. + +The use of a container bus is mainly to handle future expansion of the binding. For +comparison the ACPI equivalent of this binding (NFIT) describes: Memory regions, DIMM +control structures, Block mode DIMM control structures, interleave sets, and more. Some +of these structures cross reference each other so everyone should be happier if we keep +it relatively self contained. + +Bindings for the region nodes: +----------------------------- + +Required properties: + - compatible = "nvdimm-persistent" or "nvdimm-volatile" + + The "nvdimm-persistent" region type indicates that this memory region + is actually a persistent region. The volatile type is mainly useful + for testing and RAM disks that can persist across kexec. + + - reg = <base, size>; + The reg property should only contain one address range. + +Optional properties: + - Any relevant NUMA assocativity properties for the target platform. + +A complete example: +-------------------- + +/ { + #size-cells = <1>; + #address-cells = <1>; + + nonvolatile-memory { + compatible = "nonvolatile-memory"; + ranges; + + region@5000 { + compatible = "nvdimm-persistent"; + reg = <0x5000 0x1000>; + }; + + region@6000 { + compatible = "nvdimm-volatile"; + reg = <0x6000 0x1000>; + }; + }; +};
MAINTAINERS +8 -0
@@ -7875,6 +7875,14 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ S: Supported F: drivers/nvdimm/pmem* +LIBNVDIMM: DEVICETREE BINDINGS +M: Oliver O'Halloran <[email protected]> +L: [email protected] +Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ +S: Supported +F: drivers/nvdimm/of_nvdimm.c +F: Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt + LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM M: Dan Williams <[email protected]> L: [email protected]
drivers/nvdimm/Kconfig +10 -0
@@ -102,4 +102,14 @@ config NVDIMM_DAX Select Y if unsure +config OF_NVDIMM + tristate "Device-tree support for NVDIMMs" + depends on OF + default LIBNVDIMM + help + Allows byte addressable persistent memory regions to be described in the + device-tree. + + Select Y if unsure. + endif
drivers/nvdimm/Makefile +1 -0
@@ -3,6 +3,7 @@ obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o obj-$(CONFIG_ND_BTT) += nd_btt.o obj-$(CONFIG_ND_BLK) += nd_blk.o obj-$(CONFIG_X86_PMEM_LEGACY) += nd_e820.o +obj-$(CONFIG_OF_NVDIMM) += of_nvdimm.o nd_pmem-y := pmem.o
drivers/nvdimm/of_nvdimm.c new file +202 -0
202 lines not on this page · raw message
Signature · 6 lines
2.9.5 _______________________________________________ Linux-nvdimm mailing list [email protected] https://lists.01.org/mailman/listinfo/linux-nvdimm
A message that is not in the archive (sent off-list or not yet received): 20171115175131.23631-2-oohall-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH 2/3] libnvdimm: Add a device-tree interface
Quoted 41 lines · Oliver O'Halloran
A fairly bare-bones set of device-tree bindings so libnvdimm can be used on powerpc and other device-tree based platforms.
Signed-off-by Oliver O'Halloran <[email protected]>--- .../devicetree/bindings/nvdimm/nvdimm-bus.txt | 69 +++++++ MAINTAINERS | 8 + drivers/nvdimm/Kconfig | 10 + drivers/nvdimm/Makefile | 1 + drivers/nvdimm/of_nvdimm.c | 202 +++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt create mode 100644 drivers/nvdimm/of_nvdimm.cDocumentation/devicetree/bindings/nvdimm/nvdimm-bus.txt new file +20
-0@@ -0,0 +1,69 @@ +Device-tree bindings for nonvolatile-memory / NVDIMMs +----------------------------------------------------- + +Non-volatile DIMMs are memory modules used to provide (cacheable) main memory that +retains its contents across power cycles. In more practical terms, they are kind +of storage device where the contents can be accessed by the CPU directly, +rather than indirectly via a storage controller or similar. This can provide +substantial performance improvements for applications designed to take +advantage of in-memory storage. + +This binding provides a way to describe memory regions that should be managed +by an NVDIMM storage driver (libNVDIMM in Linux) and some of the associated +metadata. The binding itself is split into two main parts: A container bus and +its sub-nodes which describe which memory address ranges corresponding to +NVDIMM backed memory. + +Bindings for the container bus: +------------------------------ + +Required properties:
Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt line 30
Quoted 10 lines
Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt new file +10
-0+ - compatible = "nvdimm-bus"; + - ranges; + A blank ranges property is required because the sub-nodes have + addresses in the system's physical address space. + +The use of a container bus is mainly to handle future expansion of the binding. For +comparison the ACPI equivalent of this binding (NFIT) describes: Memory regions, DIMM +control structures, Block mode DIMM control structures, interleave sets, and more. Some +of these structures cross reference each other so everyone should be happier if we keep +it relatively self contained.
Will adding any of these things need unit addresses and colide with the existing nodes below? IOW, at one level there's only 1 number space.
Quoted 101 lines
Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt new file +39
-0+ +Bindings for the region nodes: +----------------------------- + +Required properties: + - compatible = "nvdimm-persistent" or "nvdimm-volatile" + + The "nvdimm-persistent" region type indicates that this memory region + is actually a persistent region. The volatile type is mainly useful + for testing and RAM disks that can persist across kexec. + + - reg = <base, size>; + The reg property should only contain one address range. + +Optional properties: + - Any relevant NUMA assocativity properties for the target platform. + +A complete example: +-------------------- + +/ { + #size-cells = <1>; + #address-cells = <1>; + + nonvolatile-memory { + compatible = "nonvolatile-memory"; + ranges; + + region@5000 { + compatible = "nvdimm-persistent"; + reg = <0x5000 0x1000>; + }; + + region@6000 { + compatible = "nvdimm-volatile"; + reg = <0x6000 0x1000>; + }; + }; +};MAINTAINERS +8
-0@@ -7875,6 +7875,14 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ S: Supported F: drivers/nvdimm/pmem* +LIBNVDIMM: DEVICETREE BINDINGS +M: Oliver O'Halloran <[email protected]> +L: [email protected] +Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ +S: Supported +F: drivers/nvdimm/of_nvdimm.c +F: Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt + LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM M: Dan Williams <[email protected]> L: [email protected]drivers/nvdimm/Kconfig +10
-0@@ -102,4 +102,14 @@ config NVDIMM_DAX Select Y if unsure +config OF_NVDIMM + tristate "Device-tree support for NVDIMMs" + depends on OF + default LIBNVDIMM + help + Allows byte addressable persistent memory regions to be described in the + device-tree. + + Select Y if unsure. + endifdrivers/nvdimm/Makefile +1
-0@@ -3,6 +3,7 @@ obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o obj-$(CONFIG_ND_BTT) += nd_btt.o obj-$(CONFIG_ND_BLK) += nd_blk.o obj-$(CONFIG_X86_PMEM_LEGACY) += nd_e820.o +obj-$(CONFIG_OF_NVDIMM) += of_nvdimm.o nd_pmem-y := pmem.odrivers/nvdimm/of_nvdimm.c new file +6
-0@@ -0,0 +1,202 @@ +/* +* Copyright 2017, IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or
drivers/nvdimm/of_nvdimm.c line 16
Quoted 10 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0+* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, you can access it online at +* http://www.gnu.org/licenses/gpl-2.0.html.
This can be SPDX tag.
Quoted 8 lines
drivers/nvdimm/of_nvdimm.c new file +8
-0+*/ + +#define pr_fmt (fmt) "of_nvdimm: " fmt + +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/libnvdimm.h> +#include <linux/module.h>
drivers/nvdimm/of_nvdimm.c line 34
Quoted 10 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0+#include <linux/ioport.h> +#include <linux/slab.h> + +static const struct attribute_group *region_attr_groups[] = { + &nd_region_attribute_group, + &nd_device_attribute_group, +NULL , +}; + +static int of_nvdimm_add_byte (struct nvdimm_bus *bus,struct device_node *np)
_add_byte_region() would be more clear.
Quoted 10 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0+{ +struct nd_region_desc ndr_desc; +struct resource temp_res; +struct nd_region *region; + +/* +* byte regions should only have one address range +*/ +if (of_address_to_resource (np,0 , &temp_res)) { +pr_warn ("Unable to parse reg[0] for %pOF\n" , np);
drivers/nvdimm/of_nvdimm.c line 54
Quoted 10 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0+return -ENXIO ; + } + +pr_debug ("Found %pR for %pOF\n" , &temp_res, np); + +memset (&ndr_desc,0 ,sizeof (ndr_desc)); + ndr_desc.res = &temp_res; + ndr_desc.of_node = np; + ndr_desc.attr_groups = region_attr_groups; +#ifdef CONFIG_NUMA
I believe of_node_to_nid will do the right thing for !CONFIG_NUMA and this can be dropped.
drivers/nvdimm/of_nvdimm.c line 59
Quoted 5 lines
drivers/nvdimm/of_nvdimm.c new file +5
-0+ ndr_desc.numa_node =of_node_to_nid (np); +#endif +set_bit (ND_REGION_PAGEMAP , &ndr_desc.flags); + +if (of_device_is_compatible (np,"nvdimm-volatile" ))
You've already matched the node once with of_match_node, don't do it again.
Quoted 14 lines
drivers/nvdimm/of_nvdimm.c new file +14
-0+ region =nvdimm_volatile_region_create (bus, &ndr_desc); + else + region =nvdimm_pmem_region_create (bus, &ndr_desc); + +if (!region) +return -ENXIO ; + +return 0 ; +} + +static const struct of_device_id of_nvdimm_dev_types[] = { + { .compatible ="nvdimm-persistent" , .data = of_nvdimm_add_byte }, + { .compatible ="nvdimm-volatile" , .data = of_nvdimm_add_byte }, + { },
drivers/nvdimm/of_nvdimm.c line 83
Quoted 10 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0+}; + +static void of_nvdimm_parse_one (struct nvdimm_bus *bus, +struct device_node *node) +{ +int (*parse_node)(struct nvdimm_bus *,struct device_node *); +const struct of_device_id *match; +int rc; + +if (of_node_test_and_set_flag (node,OF_POPULATED )) {
Why not make the regions platform devices too? Then you don't need your own populate code.
drivers/nvdimm/of_nvdimm.c line 96
Quoted 13 lines
drivers/nvdimm/of_nvdimm.c new file +13
-0+pr_debug ("%pOF already parsed, skipping\n" , node); +return ; + } + + match =of_match_node (of_nvdimm_dev_types, node); +if (!match) { +pr_info ("No compatible match for '%pOF'\n" , node); +of_node_clear_flag (node,OF_POPULATED ); +return ; + } + +of_node_get (node); + parse_node = match->data;
This makes no sense. I assume you plan to add some other region type later?
Quoted 113 lines
drivers/nvdimm/of_nvdimm.c new file +106
-0+ rc =parse_node (bus, node); + +if (rc) { +of_node_clear_flag (node,OF_POPULATED ); +of_node_put (node); + } + +pr_debug ("Parsed %pOF, rc = %d\n" , node, rc); + +return ; +} + +/* +* The nvdimm core refers to the bus descriptor structure at runtime +* so we need to keep it around. Note that that this is different to +* the other nd_*_desc types which are essentially containers for extra +* function parameters. +*/ +struct of_nd_private { +struct nvdimm_bus_descriptor desc; +struct nvdimm_bus *bus; +}; + +static const struct attribute_group *bus_attr_groups[] = { + &nvdimm_bus_attribute_group, +NULL , +}; + +static int of_nvdimm_probe (struct platform_device *pdev) +{ +struct device_node *node, *child; +struct of_nd_private *priv; + + node =dev_of_node (&pdev->dev); +if (!node) +return -ENXIO ; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->desc.attr_groups = bus_attr_groups; + priv->desc.provider_name ="of_nvdimm" ; + priv->desc.module =THIS_MODULE ; + priv->desc.of_node = node; + + priv->bus =nvdimm_bus_register (&pdev->dev, &priv->desc); +if (!priv->bus) + goto err; + +platform_set_drvdata (pdev, priv); + +/* now walk the node bus and setup regions, etc */ +for_each_available_child_of_node (node, child) +of_nvdimm_parse_one (priv->bus, child); + +return 0 ; + +err: +nvdimm_bus_unregister (priv->bus); +kfree (priv); +return -ENXIO ; +} + +static int of_nvdimm_remove (struct platform_device *pdev) +{ +struct of_nd_private *priv =platform_get_drvdata (pdev); +struct device_node *node; + +if (!priv) +return 0 ;/* possible? */ + +for_each_available_child_of_node (pdev->dev.of_node, node) { +if (!of_node_check_flag (node,OF_POPULATED )) +continue ; + +of_node_clear_flag (node,OF_POPULATED ); +of_node_put (node); +pr_debug ("de-populating %s\n" , node->full_name); + } + +nvdimm_bus_unregister (priv->bus); +kfree (priv); + +return 0 ; +} + +static const struct of_device_id of_nvdimm_bus_match[] = { + { .compatible ="nvdimm-bus" }, + { }, +}; + +static const struct platform_driver of_nvdimm_driver = { + .probe = of_nvdimm_probe, + .remove = of_nvdimm_remove, + .driver = { + .name ="of_nvdimm" , + .owner =THIS_MODULE , + .of_match_table = of_nvdimm_bus_match, + }, +}; + +module_platform_driver (of_nvdimm_driver); +MODULE_DEVICE_TABLE (of, of_nvdimm_bus_match); +MODULE_LICENSE ("GPL v2" ); +MODULE_AUTHOR ("IBM Corporation" );Signature · 6 lines
2.9.5 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm
Re: [PATCH 2/3] libnvdimm: Add a device-tree interface
Quoted 1 line · Rob Herring
On Thu, Nov 16, 2017 at 04:51:30AM +1100, Oliver O'Halloran wrote:
...
Quoted 16 lines
Quoted 16 lines
drivers/nvdimm/of_nvdimm.c new file +10
-0@@ -0,0 +1,202 @@ +/* +* Copyright 2017, IBM Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of
Quoted 8 lines
drivers/nvdimm/of_nvdimm.c line 16
Quoted 6 lines
drivers/nvdimm/of_nvdimm.c new file +6
-0+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, you can access it online at +* http://www.gnu.org/licenses/gpl-2.0.html. This can be SPDX tag.
Specifically:
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017, IBM Corporation
*/
...
cheers
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm
Re: [PATCH 2/3] libnvdimm: Add a device-tree interface
In reply to a message not in the archiveQuoted 7 lines · Oliver O'Halloran
A fairly bare-bones set of device-tree bindings so libnvdimm can be used on powerpc and other device-tree based platforms.
Signed-off-by Oliver O'Halloran <[email protected]>--- .../devicetree/bindings/nvdimm/nvdimm-bus.txt | 69 +++++++
Also, please split bindings to a separate patch.
Quoted 7 lines
MAINTAINERS | 8 + drivers/nvdimm/Kconfig | 10 + drivers/nvdimm/Makefile | 1 + drivers/nvdimm/of_nvdimm.c | 202 +++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvdimm/nvdimm-bus.txt create mode 100644 drivers/nvdimm/of_nvdimm.c
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm
PATCH 3/3 powerpc/powernv: Create platform devs for nvdimm buses
In reply to Oliver O'HalloranScan the devicetree for an nvdimm-bus compatible and create a platform device for them.
--- arch/powerpc/platforms/powernv/opal.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/platforms/powernv/opal.c +3 -0
@@ -831,6 +831,9 @@ static int __init opal_init(void)/* Create i2c platform devices */ opal_pdev_init ("ibm,opal-i2c" ); +/* Handle non-volatile memory devices */ +opal_pdev_init ("nvdimm-bus" ); +/* Setup a heatbeat thread if requested by OPAL */ opal_init_heartbeat ();
Signature · 6 lines
2.9.5 _______________________________________________ Linux-nvdimm mailing list [email protected] https://lists.01.org/mailman/listinfo/linux-nvdimm
Quoted 6 lines · Oliver O'Halloran
We want to be able to cross reference the region and bus devices with the device tree node that they were spawned from. libNVDIMM handles creating the actual devices for these internally, so we need to pass in a pointer to the relevant node in the descriptor.
Signed-off-by Oliver O'Halloran <[email protected]>
Looks ok to me,
...this is late if you were expecting a 4.15 merge.
_______________________________________________
Linux-nvdimm mailing list [email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm
Quoted 6 lines · Dan Williams
Quoted 5 lines · Oliver O'Halloran
We want to be able to cross reference the region and bus devices with the device tree node that they were spawned from. libNVDIMM handles creating the actual devices for these internally, so we need to pass in a pointer to the relevant node in the descriptor.
Quoted 7 lines
Quoted 1 line
Signed-off-by Oliver O'Halloran <[email protected]>Looks ok to me,
Acked-by Dan Williams <[email protected]>...this is late if you were expecting a 4.15 merge.
I'm not that optimistic, but I wouldn't complain.
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm