Skip to content

Commit 7199946

Browse files
committed
libnvdimm: async notification support
In preparation for asynchronous address range scrub support add an ability for the pmem driver to dynamically consume address range scrub results. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 5faecf4 commit 7199946

File tree

5 files changed

+62
-0
lines changed

5 files changed

+62
-0
lines changed

drivers/nvdimm/bus.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,32 @@ static int nvdimm_bus_remove(struct device *dev)
133133
return rc;
134134
}
135135

136+
void nd_device_notify(struct device *dev, enum nvdimm_event event)
137+
{
138+
device_lock(dev);
139+
if (dev->driver) {
140+
struct nd_device_driver *nd_drv;
141+
142+
nd_drv = to_nd_device_driver(dev->driver);
143+
if (nd_drv->notify)
144+
nd_drv->notify(dev, event);
145+
}
146+
device_unlock(dev);
147+
}
148+
EXPORT_SYMBOL(nd_device_notify);
149+
150+
void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event)
151+
{
152+
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
153+
154+
if (!nvdimm_bus)
155+
return;
156+
157+
/* caller is responsible for holding a reference on the device */
158+
nd_device_notify(&nd_region->dev, event);
159+
}
160+
EXPORT_SYMBOL_GPL(nvdimm_region_notify);
161+
136162
static struct bus_type nvdimm_bus_type = {
137163
.name = "nd",
138164
.uevent = nvdimm_bus_uevent,

drivers/nvdimm/nd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/mutex.h>
1919
#include <linux/ndctl.h>
2020
#include <linux/types.h>
21+
#include <linux/nd.h>
2122
#include "label.h"
2223

2324
enum {
@@ -168,6 +169,7 @@ int nd_integrity_init(struct gendisk *disk, unsigned long meta_size);
168169
void wait_nvdimm_bus_probe_idle(struct device *dev);
169170
void nd_device_register(struct device *dev);
170171
void nd_device_unregister(struct device *dev, enum nd_async_mode mode);
172+
void nd_device_notify(struct device *dev, enum nvdimm_event event);
171173
int nd_uuid_store(struct device *dev, u8 **uuid_out, const char *buf,
172174
size_t len);
173175
ssize_t nd_sector_size_show(unsigned long current_lbasize,

drivers/nvdimm/pmem.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,27 @@ static int nd_pmem_remove(struct device *dev)
488488
return 0;
489489
}
490490

491+
static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
492+
{
493+
struct pmem_device *pmem = dev_get_drvdata(dev);
494+
struct nd_namespace_common *ndns = pmem->ndns;
495+
496+
if (event != NVDIMM_REVALIDATE_POISON)
497+
return;
498+
499+
if (is_nd_btt(dev))
500+
nvdimm_namespace_add_poison(ndns, &pmem->bb, 0);
501+
else
502+
nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset);
503+
}
504+
491505
MODULE_ALIAS("pmem");
492506
MODULE_ALIAS_ND_DEVICE(ND_DEVICE_NAMESPACE_IO);
493507
MODULE_ALIAS_ND_DEVICE(ND_DEVICE_NAMESPACE_PMEM);
494508
static struct nd_device_driver nd_pmem_driver = {
495509
.probe = nd_pmem_probe,
496510
.remove = nd_pmem_remove,
511+
.notify = nd_pmem_notify,
497512
.drv = {
498513
.name = "nd_pmem",
499514
},

drivers/nvdimm/region.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,21 @@ static int nd_region_remove(struct device *dev)
9393
return 0;
9494
}
9595

96+
static int child_notify(struct device *dev, void *data)
97+
{
98+
nd_device_notify(dev, *(enum nvdimm_event *) data);
99+
return 0;
100+
}
101+
102+
static void nd_region_notify(struct device *dev, enum nvdimm_event event)
103+
{
104+
device_for_each_child(dev, &event, child_notify);
105+
}
106+
96107
static struct nd_device_driver nd_region_driver = {
97108
.probe = nd_region_probe,
98109
.remove = nd_region_remove,
110+
.notify = nd_region_notify,
99111
.drv = {
100112
.name = "nd_region",
101113
},

include/linux/nd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616
#include <linux/ndctl.h>
1717
#include <linux/device.h>
1818

19+
enum nvdimm_event {
20+
NVDIMM_REVALIDATE_POISON,
21+
};
22+
1923
struct nd_device_driver {
2024
struct device_driver drv;
2125
unsigned long type;
2226
int (*probe)(struct device *dev);
2327
int (*remove)(struct device *dev);
28+
void (*notify)(struct device *dev, enum nvdimm_event event);
2429
};
2530

2631
static inline struct nd_device_driver *to_nd_device_driver(
@@ -144,6 +149,8 @@ static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns,
144149
MODULE_ALIAS("nd:t" __stringify(type) "*")
145150
#define ND_DEVICE_MODALIAS_FMT "nd:t%d"
146151

152+
struct nd_region;
153+
void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event);
147154
int __must_check __nd_driver_register(struct nd_device_driver *nd_drv,
148155
struct module *module, const char *mod_name);
149156
#define nd_driver_register(driver) \

0 commit comments

Comments
 (0)