Skip to content

Commit a2d1c7a

Browse files
committed
libnvdimm/region: Rewrite _probe_success() to _advance_seeds()
The nd_region_probe_success() helper collides seed management with nvdimm->busy tracking. Given the 'busy' increment is handled internal to the nd_region driver 'probe' path move the decrement to the 'remove' path. With that cleanup the routine can be renamed to the more descriptive nd_region_advance_seeds(). The change is prompted by an incoming need to optionally advance the seeds on other events besides 'probe' success. Cc: "Aneesh Kumar K.V" <[email protected]> Signed-off-by: Dan Williams <[email protected]> Signed-off-by: Aneesh Kumar K.V <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent 7b60422 commit a2d1c7a

File tree

4 files changed

+41
-71
lines changed

4 files changed

+41
-71
lines changed

drivers/nvdimm/bus.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,8 @@ static int nvdimm_bus_probe(struct device *dev)
9595
rc = nd_drv->probe(dev);
9696
debug_nvdimm_unlock(dev);
9797

98-
if (rc == 0)
99-
nd_region_probe_success(nvdimm_bus, dev);
100-
else
101-
nd_region_disable(nvdimm_bus, dev);
98+
if (rc == 0 && dev->parent && is_nd_region(dev->parent))
99+
nd_region_advance_seeds(to_nd_region(dev->parent), dev);
102100
nvdimm_bus_probe_end(nvdimm_bus);
103101

104102
dev_dbg(&nvdimm_bus->dev, "END: %s.probe(%s) = %d\n", dev->driver->name,
@@ -121,7 +119,6 @@ static int nvdimm_bus_remove(struct device *dev)
121119
rc = nd_drv->remove(dev);
122120
debug_nvdimm_unlock(dev);
123121
}
124-
nd_region_disable(nvdimm_bus, dev);
125122

126123
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name,
127124
dev_name(dev), rc);

drivers/nvdimm/namespace_devs.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,6 +2462,27 @@ static struct device **create_namespaces(struct nd_region *nd_region)
24622462
return devs;
24632463
}
24642464

2465+
static void deactivate_labels(void *region)
2466+
{
2467+
struct nd_region *nd_region = region;
2468+
int i;
2469+
2470+
for (i = 0; i < nd_region->ndr_mappings; i++) {
2471+
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
2472+
struct nvdimm_drvdata *ndd = nd_mapping->ndd;
2473+
struct nvdimm *nvdimm = nd_mapping->nvdimm;
2474+
2475+
mutex_lock(&nd_mapping->lock);
2476+
nd_mapping_free_labels(nd_mapping);
2477+
mutex_unlock(&nd_mapping->lock);
2478+
2479+
put_ndd(ndd);
2480+
nd_mapping->ndd = NULL;
2481+
if (ndd)
2482+
atomic_dec(&nvdimm->busy);
2483+
}
2484+
}
2485+
24652486
static int init_active_labels(struct nd_region *nd_region)
24662487
{
24672488
int i;
@@ -2519,16 +2540,17 @@ static int init_active_labels(struct nd_region *nd_region)
25192540
mutex_unlock(&nd_mapping->lock);
25202541
}
25212542

2522-
if (j >= count)
2523-
continue;
2543+
if (j < count)
2544+
break;
2545+
}
25242546

2525-
mutex_lock(&nd_mapping->lock);
2526-
nd_mapping_free_labels(nd_mapping);
2527-
mutex_unlock(&nd_mapping->lock);
2547+
if (i < nd_region->ndr_mappings) {
2548+
deactivate_labels(nd_region);
25282549
return -ENOMEM;
25292550
}
25302551

2531-
return 0;
2552+
return devm_add_action_or_reset(&nd_region->dev, deactivate_labels,
2553+
nd_region);
25322554
}
25332555

25342556
int nd_region_register_namespaces(struct nd_region *nd_region, int *err)

drivers/nvdimm/nd-core.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,12 @@ int __init nvdimm_bus_init(void);
115115
void nvdimm_bus_exit(void);
116116
void nvdimm_devs_exit(void);
117117
void nd_region_devs_exit(void);
118-
void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev);
119118
struct nd_region;
119+
void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev);
120120
void nd_region_create_ns_seed(struct nd_region *nd_region);
121121
void nd_region_create_btt_seed(struct nd_region *nd_region);
122122
void nd_region_create_pfn_seed(struct nd_region *nd_region);
123123
void nd_region_create_dax_seed(struct nd_region *nd_region);
124-
void nd_region_disable(struct nvdimm_bus *nvdimm_bus, struct device *dev);
125124
int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus);
126125
void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus);
127126
void nd_synchronize(void);

drivers/nvdimm/region_devs.c

Lines changed: 10 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -715,85 +715,37 @@ void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
715715
}
716716

717717
/*
718-
* Upon successful probe/remove, take/release a reference on the
719-
* associated interleave set (if present), and plant new btt + namespace
720-
* seeds. Also, on the removal of a BLK region, notify the provider to
721-
* disable the region.
718+
* When a namespace is activated create new seeds for the next
719+
* namespace, or namespace-personality to be configured.
722720
*/
723-
static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
724-
struct device *dev, bool probe)
721+
void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev)
725722
{
726-
struct nd_region *nd_region;
727-
728-
if (!probe && is_nd_region(dev)) {
729-
int i;
730-
731-
nd_region = to_nd_region(dev);
732-
for (i = 0; i < nd_region->ndr_mappings; i++) {
733-
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
734-
struct nvdimm_drvdata *ndd = nd_mapping->ndd;
735-
struct nvdimm *nvdimm = nd_mapping->nvdimm;
736-
737-
mutex_lock(&nd_mapping->lock);
738-
nd_mapping_free_labels(nd_mapping);
739-
mutex_unlock(&nd_mapping->lock);
740-
741-
put_ndd(ndd);
742-
nd_mapping->ndd = NULL;
743-
if (ndd)
744-
atomic_dec(&nvdimm->busy);
745-
}
746-
}
747-
if (dev->parent && is_nd_region(dev->parent) && probe) {
748-
nd_region = to_nd_region(dev->parent);
749-
nvdimm_bus_lock(dev);
750-
if (nd_region->ns_seed == dev)
751-
nd_region_create_ns_seed(nd_region);
752-
nvdimm_bus_unlock(dev);
753-
}
754-
if (is_nd_btt(dev) && probe) {
723+
nvdimm_bus_lock(dev);
724+
if (nd_region->ns_seed == dev) {
725+
nd_region_create_ns_seed(nd_region);
726+
} else if (is_nd_btt(dev)) {
755727
struct nd_btt *nd_btt = to_nd_btt(dev);
756728

757-
nd_region = to_nd_region(dev->parent);
758-
nvdimm_bus_lock(dev);
759729
if (nd_region->btt_seed == dev)
760730
nd_region_create_btt_seed(nd_region);
761731
if (nd_region->ns_seed == &nd_btt->ndns->dev)
762732
nd_region_create_ns_seed(nd_region);
763-
nvdimm_bus_unlock(dev);
764-
}
765-
if (is_nd_pfn(dev) && probe) {
733+
} else if (is_nd_pfn(dev)) {
766734
struct nd_pfn *nd_pfn = to_nd_pfn(dev);
767735

768-
nd_region = to_nd_region(dev->parent);
769-
nvdimm_bus_lock(dev);
770736
if (nd_region->pfn_seed == dev)
771737
nd_region_create_pfn_seed(nd_region);
772738
if (nd_region->ns_seed == &nd_pfn->ndns->dev)
773739
nd_region_create_ns_seed(nd_region);
774-
nvdimm_bus_unlock(dev);
775-
}
776-
if (is_nd_dax(dev) && probe) {
740+
} else if (is_nd_dax(dev)) {
777741
struct nd_dax *nd_dax = to_nd_dax(dev);
778742

779-
nd_region = to_nd_region(dev->parent);
780-
nvdimm_bus_lock(dev);
781743
if (nd_region->dax_seed == dev)
782744
nd_region_create_dax_seed(nd_region);
783745
if (nd_region->ns_seed == &nd_dax->nd_pfn.ndns->dev)
784746
nd_region_create_ns_seed(nd_region);
785-
nvdimm_bus_unlock(dev);
786747
}
787-
}
788-
789-
void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev)
790-
{
791-
nd_region_notify_driver_action(nvdimm_bus, dev, true);
792-
}
793-
794-
void nd_region_disable(struct nvdimm_bus *nvdimm_bus, struct device *dev)
795-
{
796-
nd_region_notify_driver_action(nvdimm_bus, dev, false);
748+
nvdimm_bus_unlock(dev);
797749
}
798750

799751
static ssize_t mappingN(struct device *dev, char *buf, int n)

0 commit comments

Comments
 (0)