Skip to content

Commit 98a29c3

Browse files
committed
libnvdimm, namespace: allow creation of multiple pmem-namespaces per region
Similar to BLK regions, publish new seed namespace devices to allow unused PMEM region capacity to be consumed by additional namespaces. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 991d902 commit 98a29c3

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

drivers/nvdimm/namespace_devs.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,16 +1860,58 @@ static struct device *nd_namespace_blk_create(struct nd_region *nd_region)
18601860
return &nsblk->common.dev;
18611861
}
18621862

1863-
void nd_region_create_blk_seed(struct nd_region *nd_region)
1863+
static struct device *nd_namespace_pmem_create(struct nd_region *nd_region)
1864+
{
1865+
struct nd_namespace_pmem *nspm;
1866+
struct resource *res;
1867+
struct device *dev;
1868+
1869+
if (!is_nd_pmem(&nd_region->dev))
1870+
return NULL;
1871+
1872+
nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
1873+
if (!nspm)
1874+
return NULL;
1875+
1876+
dev = &nspm->nsio.common.dev;
1877+
dev->type = &namespace_pmem_device_type;
1878+
dev->parent = &nd_region->dev;
1879+
res = &nspm->nsio.res;
1880+
res->name = dev_name(&nd_region->dev);
1881+
res->flags = IORESOURCE_MEM;
1882+
1883+
nspm->id = ida_simple_get(&nd_region->ns_ida, 0, 0, GFP_KERNEL);
1884+
if (nspm->id < 0) {
1885+
kfree(nspm);
1886+
return NULL;
1887+
}
1888+
dev_set_name(dev, "namespace%d.%d", nd_region->id, nspm->id);
1889+
dev->parent = &nd_region->dev;
1890+
dev->groups = nd_namespace_attribute_groups;
1891+
nd_namespace_pmem_set_resource(nd_region, nspm, 0);
1892+
1893+
return dev;
1894+
}
1895+
1896+
void nd_region_create_ns_seed(struct nd_region *nd_region)
18641897
{
18651898
WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev));
1866-
nd_region->ns_seed = nd_namespace_blk_create(nd_region);
1899+
1900+
if (nd_region_to_nstype(nd_region) == ND_DEVICE_NAMESPACE_IO)
1901+
return;
1902+
1903+
if (is_nd_blk(&nd_region->dev))
1904+
nd_region->ns_seed = nd_namespace_blk_create(nd_region);
1905+
else
1906+
nd_region->ns_seed = nd_namespace_pmem_create(nd_region);
1907+
18671908
/*
18681909
* Seed creation failures are not fatal, provisioning is simply
18691910
* disabled until memory becomes available
18701911
*/
18711912
if (!nd_region->ns_seed)
1872-
dev_err(&nd_region->dev, "failed to create blk namespace\n");
1913+
dev_err(&nd_region->dev, "failed to create %s namespace\n",
1914+
is_nd_blk(&nd_region->dev) ? "blk" : "pmem");
18731915
else
18741916
nd_device_register(nd_region->ns_seed);
18751917
}

drivers/nvdimm/nd-core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void nvdimm_devs_exit(void);
7171
void nd_region_devs_exit(void);
7272
void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev);
7373
struct nd_region;
74-
void nd_region_create_blk_seed(struct nd_region *nd_region);
74+
void nd_region_create_ns_seed(struct nd_region *nd_region);
7575
void nd_region_create_btt_seed(struct nd_region *nd_region);
7676
void nd_region_create_pfn_seed(struct nd_region *nd_region);
7777
void nd_region_create_dax_seed(struct nd_region *nd_region);

drivers/nvdimm/region_devs.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -530,11 +530,12 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
530530
if (is_nd_pmem(dev))
531531
return;
532532
}
533-
if (dev->parent && is_nd_blk(dev->parent) && probe) {
533+
if (dev->parent && (is_nd_blk(dev->parent) || is_nd_pmem(dev->parent))
534+
&& probe) {
534535
nd_region = to_nd_region(dev->parent);
535536
nvdimm_bus_lock(dev);
536537
if (nd_region->ns_seed == dev)
537-
nd_region_create_blk_seed(nd_region);
538+
nd_region_create_ns_seed(nd_region);
538539
nvdimm_bus_unlock(dev);
539540
}
540541
if (is_nd_btt(dev) && probe) {
@@ -544,23 +545,30 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
544545
nvdimm_bus_lock(dev);
545546
if (nd_region->btt_seed == dev)
546547
nd_region_create_btt_seed(nd_region);
547-
if (nd_region->ns_seed == &nd_btt->ndns->dev &&
548-
is_nd_blk(dev->parent))
549-
nd_region_create_blk_seed(nd_region);
548+
if (nd_region->ns_seed == &nd_btt->ndns->dev)
549+
nd_region_create_ns_seed(nd_region);
550550
nvdimm_bus_unlock(dev);
551551
}
552552
if (is_nd_pfn(dev) && probe) {
553+
struct nd_pfn *nd_pfn = to_nd_pfn(dev);
554+
553555
nd_region = to_nd_region(dev->parent);
554556
nvdimm_bus_lock(dev);
555557
if (nd_region->pfn_seed == dev)
556558
nd_region_create_pfn_seed(nd_region);
559+
if (nd_region->ns_seed == &nd_pfn->ndns->dev)
560+
nd_region_create_ns_seed(nd_region);
557561
nvdimm_bus_unlock(dev);
558562
}
559563
if (is_nd_dax(dev) && probe) {
564+
struct nd_dax *nd_dax = to_nd_dax(dev);
565+
560566
nd_region = to_nd_region(dev->parent);
561567
nvdimm_bus_lock(dev);
562568
if (nd_region->dax_seed == dev)
563569
nd_region_create_dax_seed(nd_region);
570+
if (nd_region->ns_seed == &nd_dax->nd_pfn.ndns->dev)
571+
nd_region_create_ns_seed(nd_region);
564572
nvdimm_bus_unlock(dev);
565573
}
566574
}

0 commit comments

Comments
 (0)