aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dax
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dax')
-rw-r--r--drivers/dax/device-dax.h2
-rw-r--r--drivers/dax/device.c33
-rw-r--r--drivers/dax/pmem.c12
3 files changed, 31 insertions, 16 deletions
diff --git a/drivers/dax/device-dax.h b/drivers/dax/device-dax.h
index fdcd9769ffde..688b051750bd 100644
--- a/drivers/dax/device-dax.h
+++ b/drivers/dax/device-dax.h
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(struct device *parent,
21 int region_id, struct resource *res, unsigned int align, 21 int region_id, struct resource *res, unsigned int align,
22 void *addr, unsigned long flags); 22 void *addr, unsigned long flags);
23struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, 23struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
24 struct resource *res, int count); 24 int id, struct resource *res, int count);
25#endif /* __DEVICE_DAX_H__ */ 25#endif /* __DEVICE_DAX_H__ */
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index 12943d19bfc4..e9f3b3e4bbf4 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -529,7 +529,8 @@ static void dev_dax_release(struct device *dev)
529 struct dax_region *dax_region = dev_dax->region; 529 struct dax_region *dax_region = dev_dax->region;
530 struct dax_device *dax_dev = dev_dax->dax_dev; 530 struct dax_device *dax_dev = dev_dax->dax_dev;
531 531
532 ida_simple_remove(&dax_region->ida, dev_dax->id); 532 if (dev_dax->id >= 0)
533 ida_simple_remove(&dax_region->ida, dev_dax->id);
533 dax_region_put(dax_region); 534 dax_region_put(dax_region);
534 put_dax(dax_dev); 535 put_dax(dax_dev);
535 kfree(dev_dax); 536 kfree(dev_dax);
@@ -559,7 +560,7 @@ static void unregister_dev_dax(void *dev)
559} 560}
560 561
561struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, 562struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
562 struct resource *res, int count) 563 int id, struct resource *res, int count)
563{ 564{
564 struct device *parent = dax_region->dev; 565 struct device *parent = dax_region->dev;
565 struct dax_device *dax_dev; 566 struct dax_device *dax_dev;
@@ -567,7 +568,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
567 struct inode *inode; 568 struct inode *inode;
568 struct device *dev; 569 struct device *dev;
569 struct cdev *cdev; 570 struct cdev *cdev;
570 int rc = 0, i; 571 int rc, i;
572
573 if (!count)
574 return ERR_PTR(-EINVAL);
571 575
572 dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL); 576 dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);
573 if (!dev_dax) 577 if (!dev_dax)
@@ -587,10 +591,16 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
587 if (i < count) 591 if (i < count)
588 goto err_id; 592 goto err_id;
589 593
590 dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); 594 if (id < 0) {
591 if (dev_dax->id < 0) { 595 id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
592 rc = dev_dax->id; 596 dev_dax->id = id;
593 goto err_id; 597 if (id < 0) {
598 rc = id;
599 goto err_id;
600 }
601 } else {
602 /* region provider owns @id lifetime */
603 dev_dax->id = -1;
594 } 604 }
595 605
596 /* 606 /*
@@ -598,8 +608,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
598 * device outside of mmap of the resulting character device. 608 * device outside of mmap of the resulting character device.
599 */ 609 */
600 dax_dev = alloc_dax(dev_dax, NULL, NULL); 610 dax_dev = alloc_dax(dev_dax, NULL, NULL);
601 if (!dax_dev) 611 if (!dax_dev) {
612 rc = -ENOMEM;
602 goto err_dax; 613 goto err_dax;
614 }
603 615
604 /* from here on we're committed to teardown via dax_dev_release() */ 616 /* from here on we're committed to teardown via dax_dev_release() */
605 dev = &dev_dax->dev; 617 dev = &dev_dax->dev;
@@ -620,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
620 dev->parent = parent; 632 dev->parent = parent;
621 dev->groups = dax_attribute_groups; 633 dev->groups = dax_attribute_groups;
622 dev->release = dev_dax_release; 634 dev->release = dev_dax_release;
623 dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id); 635 dev_set_name(dev, "dax%d.%d", dax_region->id, id);
624 636
625 rc = cdev_device_add(cdev, dev); 637 rc = cdev_device_add(cdev, dev);
626 if (rc) { 638 if (rc) {
@@ -636,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
636 return dev_dax; 648 return dev_dax;
637 649
638 err_dax: 650 err_dax:
639 ida_simple_remove(&dax_region->ida, dev_dax->id); 651 if (dev_dax->id >= 0)
652 ida_simple_remove(&dax_region->ida, dev_dax->id);
640 err_id: 653 err_id:
641 kfree(dev_dax); 654 kfree(dev_dax);
642 655
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index 9f2a0b4fd801..8d8c852ba8f2 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *data)
58 58
59static int dax_pmem_probe(struct device *dev) 59static int dax_pmem_probe(struct device *dev)
60{ 60{
61 int rc;
62 void *addr; 61 void *addr;
63 struct resource res; 62 struct resource res;
63 int rc, id, region_id;
64 struct nd_pfn_sb *pfn_sb; 64 struct nd_pfn_sb *pfn_sb;
65 struct dev_dax *dev_dax; 65 struct dev_dax *dev_dax;
66 struct dax_pmem *dax_pmem; 66 struct dax_pmem *dax_pmem;
67 struct nd_region *nd_region;
68 struct nd_namespace_io *nsio; 67 struct nd_namespace_io *nsio;
69 struct dax_region *dax_region; 68 struct dax_region *dax_region;
70 struct nd_namespace_common *ndns; 69 struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device *dev)
123 /* adjust the dax_region resource to the start of data */ 122 /* adjust the dax_region resource to the start of data */
124 res.start += le64_to_cpu(pfn_sb->dataoff); 123 res.start += le64_to_cpu(pfn_sb->dataoff);
125 124
126 nd_region = to_nd_region(dev->parent); 125 rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
127 dax_region = alloc_dax_region(dev, nd_region->id, &res, 126 if (rc != 2)
127 return -EINVAL;
128
129 dax_region = alloc_dax_region(dev, region_id, &res,
128 le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP); 130 le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
129 if (!dax_region) 131 if (!dax_region)
130 return -ENOMEM; 132 return -ENOMEM;
131 133
132 /* TODO: support for subdividing a dax region... */ 134 /* TODO: support for subdividing a dax region... */
133 dev_dax = devm_create_dev_dax(dax_region, &res, 1); 135 dev_dax = devm_create_dev_dax(dax_region, id, &res, 1);
134 136
135 /* child dev_dax instances now own the lifetime of the dax_region */ 137 /* child dev_dax instances now own the lifetime of the dax_region */
136 dax_region_put(dax_region); 138 dax_region_put(dax_region);