From 0e3b0d123c8fd5c42f364aea3ab663b1f18dad39 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Oct 2016 23:13:15 -0700 Subject: libnvdimm, namespace: allow multiple pmem-namespaces per region at scan time If label scanning finds multiple valid pmem namespaces allow them to be surfaced rather than fail namespace scanning. Support for creating multiple namespaces per region is saved for a later patch. Note that this adds some new error messages to clarify which of the pmem namespaces in the set are potentially impacted by invalid labels. Signed-off-by: Dan Williams --- include/linux/nd.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/nd.h') diff --git a/include/linux/nd.h b/include/linux/nd.h index f1ea426d6a5e..ddcc7788305c 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -77,11 +77,13 @@ struct nd_namespace_io { * @nsio: device and system physical address range to drive * @alt_name: namespace name supplied in the dimm label * @uuid: namespace name supplied in the dimm label + * @id: ida allocated id */ struct nd_namespace_pmem { struct nd_namespace_io nsio; char *alt_name; u8 *uuid; + int id; }; /** -- cgit v1.2.3 From 6ff3e912d32ece4e9cf8708da796e9e2e7979ffe Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Oct 2016 14:04:15 -0700 Subject: libnvdimm, namespace: sort namespaces by dpa at init Add more determinism to initial namespace device-name assignments by sorting the namespaces by starting dpa. Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 35 ++++++++++++++++++++++++++++++++--- include/linux/nd.h | 6 +++--- 2 files changed, 35 insertions(+), 6 deletions(-) (limited to 'include/linux/nd.h') diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 47d29632b937..f0536c2789e9 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -66,17 +67,17 @@ static struct device_type namespace_blk_device_type = { .release = namespace_blk_release, }; -static bool is_namespace_pmem(struct device *dev) +static bool is_namespace_pmem(const struct device *dev) { return dev ? dev->type == &namespace_pmem_device_type : false; } -static bool is_namespace_blk(struct device *dev) +static bool is_namespace_blk(const struct device *dev) { return dev ? dev->type == &namespace_blk_device_type : false; } -static bool is_namespace_io(struct device *dev) +static bool is_namespace_io(const struct device *dev) { return dev ? dev->type == &namespace_io_device_type : false; } @@ -1919,6 +1920,31 @@ struct device *create_namespace_blk(struct nd_region *nd_region, return ERR_PTR(-ENXIO); } +static int cmp_dpa(const void *a, const void *b) +{ + const struct device *dev_a = *(const struct device **) a; + const struct device *dev_b = *(const struct device **) b; + struct nd_namespace_blk *nsblk_a, *nsblk_b; + struct nd_namespace_pmem *nspm_a, *nspm_b; + + if (is_namespace_io(dev_a)) + return 0; + + if (is_namespace_blk(dev_a)) { + nsblk_a = to_nd_namespace_blk(dev_a); + nsblk_b = to_nd_namespace_blk(dev_b); + + return memcmp(&nsblk_a->res[0]->start, &nsblk_b->res[0]->start, + sizeof(resource_size_t)); + } + + nspm_a = to_nd_namespace_pmem(dev_a); + nspm_b = to_nd_namespace_pmem(dev_b); + + return memcmp(&nspm_a->nsio.res.start, &nspm_b->nsio.res.start, + sizeof(resource_size_t)); +} + static struct device **scan_labels(struct nd_region *nd_region) { struct nd_mapping *nd_mapping = &nd_region->mapping[0]; @@ -2034,6 +2060,9 @@ static struct device **scan_labels(struct nd_region *nd_region) } } + if (count > 1) + sort(devs, count, sizeof(struct device *), cmp_dpa, NULL); + return devs; err: diff --git a/include/linux/nd.h b/include/linux/nd.h index ddcc7788305c..fa66aeed441a 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -107,19 +107,19 @@ struct nd_namespace_blk { struct resource **res; }; -static inline struct nd_namespace_io *to_nd_namespace_io(struct device *dev) +static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev) { return container_of(dev, struct nd_namespace_io, common.dev); } -static inline struct nd_namespace_pmem *to_nd_namespace_pmem(struct device *dev) +static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev) { struct nd_namespace_io *nsio = to_nd_namespace_io(dev); return container_of(nsio, struct nd_namespace_pmem, nsio); } -static inline struct nd_namespace_blk *to_nd_namespace_blk(struct device *dev) +static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev) { return container_of(dev, struct nd_namespace_blk, common.dev); } -- cgit v1.2.3