libnvdimm: Export nvdimm shutdown helper, nvdimm_delete()
authorDan Williams <dan.j.williams@intel.com>
Tue, 15 Jun 2021 23:18:22 +0000 (16:18 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 15 Jun 2021 23:47:22 +0000 (16:47 -0700)
CXL is a hotplug bus and arranges for nvdimm devices to be dynamically
discovered and removed. The libnvdimm core manages shutdown of nvdimm
security operations when the device is unregistered. That functionality
is moved to nvdimm_delete() and invoked by the CXL-to-nvdimm glue code.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/162379910271.2993820.2955889139842401250.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/nvdimm/bus.c
drivers/nvdimm/dimm_devs.c
include/linux/libnvdimm.h

index 3a777d0073b7203743059a17fedea61dc6ade3ca..a11821df83b56b69dadd6c37ed5be5f439590ce7 100644 (file)
@@ -396,21 +396,10 @@ static int child_unregister(struct device *dev, void *data)
        if (dev->class)
                return 0;
 
-       if (is_nvdimm(dev)) {
-               struct nvdimm *nvdimm = to_nvdimm(dev);
-               bool dev_put = false;
-
-               /* We are shutting down. Make state frozen artificially. */
-               nvdimm_bus_lock(dev);
-               set_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags);
-               if (test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags))
-                       dev_put = true;
-               nvdimm_bus_unlock(dev);
-               cancel_delayed_work_sync(&nvdimm->dwork);
-               if (dev_put)
-                       put_device(dev);
-       }
-       nd_device_unregister(dev, ND_SYNC);
+       if (is_nvdimm(dev))
+               nvdimm_delete(to_nvdimm(dev));
+       else
+               nd_device_unregister(dev, ND_SYNC);
 
        return 0;
 }
index 9d208570d059a2ec6df5004a070585ad57994c85..dc7449a400037b273ff0b7b01e115eb3cad19c81 100644 (file)
@@ -642,6 +642,24 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
 }
 EXPORT_SYMBOL_GPL(__nvdimm_create);
 
+void nvdimm_delete(struct nvdimm *nvdimm)
+{
+       struct device *dev = &nvdimm->dev;
+       bool dev_put = false;
+
+       /* We are shutting down. Make state frozen artificially. */
+       nvdimm_bus_lock(dev);
+       set_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags);
+       if (test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags))
+               dev_put = true;
+       nvdimm_bus_unlock(dev);
+       cancel_delayed_work_sync(&nvdimm->dwork);
+       if (dev_put)
+               put_device(dev);
+       nd_device_unregister(dev, ND_SYNC);
+}
+EXPORT_SYMBOL_GPL(nvdimm_delete);
+
 static void shutdown_security_notify(void *data)
 {
        struct nvdimm *nvdimm = data;
index 89b69e645ac74a7f0ed22ac52b5cb9ed99e02a4c..7074aa9af525c7b10a908eb677ff62e238e4df6c 100644 (file)
@@ -278,6 +278,7 @@ static inline struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus,
        return __nvdimm_create(nvdimm_bus, provider_data, groups, flags,
                        cmd_mask, num_flush, flush_wpq, NULL, NULL, NULL);
 }
+void nvdimm_delete(struct nvdimm *nvdimm);
 
 const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd);
 const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd);