aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-07-09 03:12:52 -0400
committerDan Williams <dan.j.williams@intel.com>2016-07-12 18:13:48 -0400
commit476f848aaee466fd5d74f123fa652e757f2baeba (patch)
treed84cdd4fdb50252dfc5d1e2916b665d4f5570b76
parent7e267a8c790edfde9b697cbe944ee566f41219c3 (diff)
libnvdimm, pmem: flush posted-write queues on shutdown
Commit writes to media on system shutdown or pmem driver unload. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/bus.c16
-rw-r--r--drivers/nvdimm/pmem.c8
-rw-r--r--include/linux/nd.h1
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index e4882e63bece..1cc7880320fe 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -136,6 +136,21 @@ static int nvdimm_bus_remove(struct device *dev)
136 return rc; 136 return rc;
137} 137}
138 138
139static void nvdimm_bus_shutdown(struct device *dev)
140{
141 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
142 struct nd_device_driver *nd_drv = NULL;
143
144 if (dev->driver)
145 nd_drv = to_nd_device_driver(dev->driver);
146
147 if (nd_drv && nd_drv->shutdown) {
148 nd_drv->shutdown(dev);
149 dev_dbg(&nvdimm_bus->dev, "%s.shutdown(%s)\n",
150 dev->driver->name, dev_name(dev));
151 }
152}
153
139void nd_device_notify(struct device *dev, enum nvdimm_event event) 154void nd_device_notify(struct device *dev, enum nvdimm_event event)
140{ 155{
141 device_lock(dev); 156 device_lock(dev);
@@ -214,6 +229,7 @@ static struct bus_type nvdimm_bus_type = {
214 .match = nvdimm_bus_match, 229 .match = nvdimm_bus_match,
215 .probe = nvdimm_bus_probe, 230 .probe = nvdimm_bus_probe,
216 .remove = nvdimm_bus_remove, 231 .remove = nvdimm_bus_remove,
232 .shutdown = nvdimm_bus_shutdown,
217}; 233};
218 234
219static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain); 235static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 9d9c1beef020..8bfc6acc2e43 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -349,9 +349,16 @@ static int nd_pmem_remove(struct device *dev)
349{ 349{
350 if (is_nd_btt(dev)) 350 if (is_nd_btt(dev))
351 nvdimm_namespace_detach_btt(to_nd_btt(dev)); 351 nvdimm_namespace_detach_btt(to_nd_btt(dev));
352 nvdimm_flush(to_nd_region(dev->parent));
353
352 return 0; 354 return 0;
353} 355}
354 356
357static void nd_pmem_shutdown(struct device *dev)
358{
359 nvdimm_flush(to_nd_region(dev->parent));
360}
361
355static void nd_pmem_notify(struct device *dev, enum nvdimm_event event) 362static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
356{ 363{
357 struct pmem_device *pmem = dev_get_drvdata(dev); 364 struct pmem_device *pmem = dev_get_drvdata(dev);
@@ -391,6 +398,7 @@ static struct nd_device_driver nd_pmem_driver = {
391 .probe = nd_pmem_probe, 398 .probe = nd_pmem_probe,
392 .remove = nd_pmem_remove, 399 .remove = nd_pmem_remove,
393 .notify = nd_pmem_notify, 400 .notify = nd_pmem_notify,
401 .shutdown = nd_pmem_shutdown,
394 .drv = { 402 .drv = {
395 .name = "nd_pmem", 403 .name = "nd_pmem",
396 }, 404 },
diff --git a/include/linux/nd.h b/include/linux/nd.h
index aee2761d294c..1ecd64643512 100644
--- a/include/linux/nd.h
+++ b/include/linux/nd.h
@@ -26,6 +26,7 @@ struct nd_device_driver {
26 unsigned long type; 26 unsigned long type;
27 int (*probe)(struct device *dev); 27 int (*probe)(struct device *dev);
28 int (*remove)(struct device *dev); 28 int (*remove)(struct device *dev);
29 void (*shutdown)(struct device *dev);
29 void (*notify)(struct device *dev, enum nvdimm_event event); 30 void (*notify)(struct device *dev, enum nvdimm_event event);
30}; 31};
31 32