aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-09-30 18:28:27 -0400
committerDan Williams <dan.j.williams@intel.com>2016-10-07 12:22:53 -0400
commit98a29c39dc689298d2f834f40102cba752eb49c0 (patch)
treee1b3551216f9181641c35bbf4cd76f0562f45030
parent991d9020f3e0447ea00c7c7f11fed364d977320a (diff)
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>
-rw-r--r--drivers/nvdimm/namespace_devs.c48
-rw-r--r--drivers/nvdimm/nd-core.h2
-rw-r--r--drivers/nvdimm/region_devs.c18
3 files changed, 59 insertions, 9 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index fa51d751ccf7..3509cff68ef9 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1860,16 +1860,58 @@ static struct device *nd_namespace_blk_create(struct nd_region *nd_region)
1860 return &nsblk->common.dev; 1860 return &nsblk->common.dev;
1861} 1861}
1862 1862
1863void nd_region_create_blk_seed(struct nd_region *nd_region) 1863static 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
1896void nd_region_create_ns_seed(struct nd_region *nd_region)
1864{ 1897{
1865 WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); 1898 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
1867 /* 1908 /*
1868 * Seed creation failures are not fatal, provisioning is simply 1909 * Seed creation failures are not fatal, provisioning is simply
1869 * disabled until memory becomes available 1910 * disabled until memory becomes available
1870 */ 1911 */
1871 if (!nd_region->ns_seed) 1912 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");
1873 else 1915 else
1874 nd_device_register(nd_region->ns_seed); 1916 nd_device_register(nd_region->ns_seed);
1875} 1917}
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index 3ba0b96ce7de..8623e57c2ce3 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -71,7 +71,7 @@ void nvdimm_devs_exit(void);
71void nd_region_devs_exit(void); 71void nd_region_devs_exit(void);
72void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev); 72void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev);
73struct nd_region; 73struct nd_region;
74void nd_region_create_blk_seed(struct nd_region *nd_region); 74void nd_region_create_ns_seed(struct nd_region *nd_region);
75void nd_region_create_btt_seed(struct nd_region *nd_region); 75void nd_region_create_btt_seed(struct nd_region *nd_region);
76void nd_region_create_pfn_seed(struct nd_region *nd_region); 76void nd_region_create_pfn_seed(struct nd_region *nd_region);
77void nd_region_create_dax_seed(struct nd_region *nd_region); 77void nd_region_create_dax_seed(struct nd_region *nd_region);
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 3ac534aec60c..4f74e009b135 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -530,11 +530,12 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
530 if (is_nd_pmem(dev)) 530 if (is_nd_pmem(dev))
531 return; 531 return;
532 } 532 }
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) {
534 nd_region = to_nd_region(dev->parent); 535 nd_region = to_nd_region(dev->parent);
535 nvdimm_bus_lock(dev); 536 nvdimm_bus_lock(dev);
536 if (nd_region->ns_seed == dev) 537 if (nd_region->ns_seed == dev)
537 nd_region_create_blk_seed(nd_region); 538 nd_region_create_ns_seed(nd_region);
538 nvdimm_bus_unlock(dev); 539 nvdimm_bus_unlock(dev);
539 } 540 }
540 if (is_nd_btt(dev) && probe) { 541 if (is_nd_btt(dev) && probe) {
@@ -544,23 +545,30 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
544 nvdimm_bus_lock(dev); 545 nvdimm_bus_lock(dev);
545 if (nd_region->btt_seed == dev) 546 if (nd_region->btt_seed == dev)
546 nd_region_create_btt_seed(nd_region); 547 nd_region_create_btt_seed(nd_region);
547 if (nd_region->ns_seed == &nd_btt->ndns->dev && 548 if (nd_region->ns_seed == &nd_btt->ndns->dev)
548 is_nd_blk(dev->parent)) 549 nd_region_create_ns_seed(nd_region);
549 nd_region_create_blk_seed(nd_region);
550 nvdimm_bus_unlock(dev); 550 nvdimm_bus_unlock(dev);
551 } 551 }
552 if (is_nd_pfn(dev) && probe) { 552 if (is_nd_pfn(dev) && probe) {
553 struct nd_pfn *nd_pfn = to_nd_pfn(dev);
554
553 nd_region = to_nd_region(dev->parent); 555 nd_region = to_nd_region(dev->parent);
554 nvdimm_bus_lock(dev); 556 nvdimm_bus_lock(dev);
555 if (nd_region->pfn_seed == dev) 557 if (nd_region->pfn_seed == dev)
556 nd_region_create_pfn_seed(nd_region); 558 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);
557 nvdimm_bus_unlock(dev); 561 nvdimm_bus_unlock(dev);
558 } 562 }
559 if (is_nd_dax(dev) && probe) { 563 if (is_nd_dax(dev) && probe) {
564 struct nd_dax *nd_dax = to_nd_dax(dev);
565
560 nd_region = to_nd_region(dev->parent); 566 nd_region = to_nd_region(dev->parent);
561 nvdimm_bus_lock(dev); 567 nvdimm_bus_lock(dev);
562 if (nd_region->dax_seed == dev) 568 if (nd_region->dax_seed == dev)
563 nd_region_create_dax_seed(nd_region); 569 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);
564 nvdimm_bus_unlock(dev); 572 nvdimm_bus_unlock(dev);
565 } 573 }
566} 574}