diff options
author | Dan Williams <dan.j.williams@intel.com> | 2019-07-17 21:08:26 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2019-07-18 19:23:27 -0400 |
commit | 87a30e1f05d73a34e6d1895065541369131aaf1c (patch) | |
tree | a5582d3cd7723db8b7ad2f4801a5540c36c5266a | |
parent | ca6bf264f6d856f959c4239cda1047b587745c67 (diff) |
driver-core, libnvdimm: Let device subsystems add local lockdep coverage
For good reason, the standard device_lock() is marked
lockdep_set_novalidate_class() because there is simply no sane way to
describe the myriad ways the device_lock() ordered with other locks.
However, that leaves subsystems that know their own local device_lock()
ordering rules to find lock ordering mistakes manually. Instead,
introduce an optional / additional lockdep-enabled lock that a subsystem
can acquire in all the same paths that the device_lock() is acquired.
A conversion of the NFIT driver and NVDIMM subsystem to a
lockdep-validate device_lock() scheme is included. The
debug_nvdimm_lock() implementation implements the correct lock-class and
stacking order for the libnvdimm device topology hierarchy.
Yes, this is a hack, but hopefully it is a useful hack for other
subsystems device_lock() debug sessions. Quoting Greg:
"Yeah, it feels a bit hacky but it's really up to a subsystem to mess up
using it as much as anything else, so user beware :)
I don't object to it if it makes things easier for you to debug."
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Link: https://lore.kernel.org/r/156341210661.292348.7014034644265455704.stgit@dwillia2-desk3.amr.corp.intel.com
-rw-r--r-- | drivers/acpi/nfit/core.c | 28 | ||||
-rw-r--r-- | drivers/acpi/nfit/nfit.h | 24 | ||||
-rw-r--r-- | drivers/base/core.c | 3 | ||||
-rw-r--r-- | drivers/nvdimm/btt_devs.c | 16 | ||||
-rw-r--r-- | drivers/nvdimm/bus.c | 28 | ||||
-rw-r--r-- | drivers/nvdimm/core.c | 10 | ||||
-rw-r--r-- | drivers/nvdimm/dimm_devs.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 36 | ||||
-rw-r--r-- | drivers/nvdimm/nd-core.h | 68 | ||||
-rw-r--r-- | drivers/nvdimm/pfn_devs.c | 24 | ||||
-rw-r--r-- | drivers/nvdimm/pmem.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/region.c | 2 | ||||
-rw-r--r-- | drivers/nvdimm/region_devs.c | 16 | ||||
-rw-r--r-- | include/linux/device.h | 5 |
14 files changed, 187 insertions, 81 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 23022cf20d26..f22139458ce1 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c | |||
@@ -1282,7 +1282,7 @@ static ssize_t hw_error_scrub_store(struct device *dev, | |||
1282 | if (rc) | 1282 | if (rc) |
1283 | return rc; | 1283 | return rc; |
1284 | 1284 | ||
1285 | device_lock(dev); | 1285 | nfit_device_lock(dev); |
1286 | nd_desc = dev_get_drvdata(dev); | 1286 | nd_desc = dev_get_drvdata(dev); |
1287 | if (nd_desc) { | 1287 | if (nd_desc) { |
1288 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); | 1288 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); |
@@ -1299,7 +1299,7 @@ static ssize_t hw_error_scrub_store(struct device *dev, | |||
1299 | break; | 1299 | break; |
1300 | } | 1300 | } |
1301 | } | 1301 | } |
1302 | device_unlock(dev); | 1302 | nfit_device_unlock(dev); |
1303 | if (rc) | 1303 | if (rc) |
1304 | return rc; | 1304 | return rc; |
1305 | return size; | 1305 | return size; |
@@ -1319,7 +1319,7 @@ static ssize_t scrub_show(struct device *dev, | |||
1319 | ssize_t rc = -ENXIO; | 1319 | ssize_t rc = -ENXIO; |
1320 | bool busy; | 1320 | bool busy; |
1321 | 1321 | ||
1322 | device_lock(dev); | 1322 | nfit_device_lock(dev); |
1323 | nd_desc = dev_get_drvdata(dev); | 1323 | nd_desc = dev_get_drvdata(dev); |
1324 | if (!nd_desc) { | 1324 | if (!nd_desc) { |
1325 | device_unlock(dev); | 1325 | device_unlock(dev); |
@@ -1339,7 +1339,7 @@ static ssize_t scrub_show(struct device *dev, | |||
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | mutex_unlock(&acpi_desc->init_mutex); | 1341 | mutex_unlock(&acpi_desc->init_mutex); |
1342 | device_unlock(dev); | 1342 | nfit_device_unlock(dev); |
1343 | return rc; | 1343 | return rc; |
1344 | } | 1344 | } |
1345 | 1345 | ||
@@ -1356,14 +1356,14 @@ static ssize_t scrub_store(struct device *dev, | |||
1356 | if (val != 1) | 1356 | if (val != 1) |
1357 | return -EINVAL; | 1357 | return -EINVAL; |
1358 | 1358 | ||
1359 | device_lock(dev); | 1359 | nfit_device_lock(dev); |
1360 | nd_desc = dev_get_drvdata(dev); | 1360 | nd_desc = dev_get_drvdata(dev); |
1361 | if (nd_desc) { | 1361 | if (nd_desc) { |
1362 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); | 1362 | struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); |
1363 | 1363 | ||
1364 | rc = acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG); | 1364 | rc = acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG); |
1365 | } | 1365 | } |
1366 | device_unlock(dev); | 1366 | nfit_device_unlock(dev); |
1367 | if (rc) | 1367 | if (rc) |
1368 | return rc; | 1368 | return rc; |
1369 | return size; | 1369 | return size; |
@@ -1749,9 +1749,9 @@ static void acpi_nvdimm_notify(acpi_handle handle, u32 event, void *data) | |||
1749 | struct acpi_device *adev = data; | 1749 | struct acpi_device *adev = data; |
1750 | struct device *dev = &adev->dev; | 1750 | struct device *dev = &adev->dev; |
1751 | 1751 | ||
1752 | device_lock(dev->parent); | 1752 | nfit_device_lock(dev->parent); |
1753 | __acpi_nvdimm_notify(dev, event); | 1753 | __acpi_nvdimm_notify(dev, event); |
1754 | device_unlock(dev->parent); | 1754 | nfit_device_unlock(dev->parent); |
1755 | } | 1755 | } |
1756 | 1756 | ||
1757 | static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method) | 1757 | static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method) |
@@ -3457,8 +3457,8 @@ static int acpi_nfit_flush_probe(struct nvdimm_bus_descriptor *nd_desc) | |||
3457 | struct device *dev = acpi_desc->dev; | 3457 | struct device *dev = acpi_desc->dev; |
3458 | 3458 | ||
3459 | /* Bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */ | 3459 | /* Bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */ |
3460 | device_lock(dev); | 3460 | nfit_device_lock(dev); |
3461 | device_unlock(dev); | 3461 | nfit_device_unlock(dev); |
3462 | 3462 | ||
3463 | /* Bounce the init_mutex to complete initial registration */ | 3463 | /* Bounce the init_mutex to complete initial registration */ |
3464 | mutex_lock(&acpi_desc->init_mutex); | 3464 | mutex_lock(&acpi_desc->init_mutex); |
@@ -3602,8 +3602,8 @@ void acpi_nfit_shutdown(void *data) | |||
3602 | * acpi_nfit_ars_rescan() submissions have had a chance to | 3602 | * acpi_nfit_ars_rescan() submissions have had a chance to |
3603 | * either submit or see ->cancel set. | 3603 | * either submit or see ->cancel set. |
3604 | */ | 3604 | */ |
3605 | device_lock(bus_dev); | 3605 | nfit_device_lock(bus_dev); |
3606 | device_unlock(bus_dev); | 3606 | nfit_device_unlock(bus_dev); |
3607 | 3607 | ||
3608 | flush_workqueue(nfit_wq); | 3608 | flush_workqueue(nfit_wq); |
3609 | } | 3609 | } |
@@ -3746,9 +3746,9 @@ EXPORT_SYMBOL_GPL(__acpi_nfit_notify); | |||
3746 | 3746 | ||
3747 | static void acpi_nfit_notify(struct acpi_device *adev, u32 event) | 3747 | static void acpi_nfit_notify(struct acpi_device *adev, u32 event) |
3748 | { | 3748 | { |
3749 | device_lock(&adev->dev); | 3749 | nfit_device_lock(&adev->dev); |
3750 | __acpi_nfit_notify(&adev->dev, adev->handle, event); | 3750 | __acpi_nfit_notify(&adev->dev, adev->handle, event); |
3751 | device_unlock(&adev->dev); | 3751 | nfit_device_unlock(&adev->dev); |
3752 | } | 3752 | } |
3753 | 3753 | ||
3754 | static const struct acpi_device_id acpi_nfit_ids[] = { | 3754 | static const struct acpi_device_id acpi_nfit_ids[] = { |
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index 6ee2b02af73e..24241941181c 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h | |||
@@ -312,6 +312,30 @@ static inline struct acpi_nfit_desc *to_acpi_desc( | |||
312 | return container_of(nd_desc, struct acpi_nfit_desc, nd_desc); | 312 | return container_of(nd_desc, struct acpi_nfit_desc, nd_desc); |
313 | } | 313 | } |
314 | 314 | ||
315 | #ifdef CONFIG_PROVE_LOCKING | ||
316 | static inline void nfit_device_lock(struct device *dev) | ||
317 | { | ||
318 | device_lock(dev); | ||
319 | mutex_lock(&dev->lockdep_mutex); | ||
320 | } | ||
321 | |||
322 | static inline void nfit_device_unlock(struct device *dev) | ||
323 | { | ||
324 | mutex_unlock(&dev->lockdep_mutex); | ||
325 | device_unlock(dev); | ||
326 | } | ||
327 | #else | ||
328 | static inline void nfit_device_lock(struct device *dev) | ||
329 | { | ||
330 | device_lock(dev); | ||
331 | } | ||
332 | |||
333 | static inline void nfit_device_unlock(struct device *dev) | ||
334 | { | ||
335 | device_unlock(dev); | ||
336 | } | ||
337 | #endif | ||
338 | |||
315 | const guid_t *to_nfit_uuid(enum nfit_uuids id); | 339 | const guid_t *to_nfit_uuid(enum nfit_uuids id); |
316 | int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); | 340 | int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); |
317 | void acpi_nfit_shutdown(void *data); | 341 | void acpi_nfit_shutdown(void *data); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index eaf3aa0cb803..4825949d6547 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1663,6 +1663,9 @@ void device_initialize(struct device *dev) | |||
1663 | kobject_init(&dev->kobj, &device_ktype); | 1663 | kobject_init(&dev->kobj, &device_ktype); |
1664 | INIT_LIST_HEAD(&dev->dma_pools); | 1664 | INIT_LIST_HEAD(&dev->dma_pools); |
1665 | mutex_init(&dev->mutex); | 1665 | mutex_init(&dev->mutex); |
1666 | #ifdef CONFIG_PROVE_LOCKING | ||
1667 | mutex_init(&dev->lockdep_mutex); | ||
1668 | #endif | ||
1666 | lockdep_set_novalidate_class(&dev->mutex); | 1669 | lockdep_set_novalidate_class(&dev->mutex); |
1667 | spin_lock_init(&dev->devres_lock); | 1670 | spin_lock_init(&dev->devres_lock); |
1668 | INIT_LIST_HEAD(&dev->devres_head); | 1671 | INIT_LIST_HEAD(&dev->devres_head); |
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index 62d00fffa4af..3508a79110c7 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c | |||
@@ -62,14 +62,14 @@ static ssize_t sector_size_store(struct device *dev, | |||
62 | struct nd_btt *nd_btt = to_nd_btt(dev); | 62 | struct nd_btt *nd_btt = to_nd_btt(dev); |
63 | ssize_t rc; | 63 | ssize_t rc; |
64 | 64 | ||
65 | device_lock(dev); | 65 | nd_device_lock(dev); |
66 | nvdimm_bus_lock(dev); | 66 | nvdimm_bus_lock(dev); |
67 | rc = nd_size_select_store(dev, buf, &nd_btt->lbasize, | 67 | rc = nd_size_select_store(dev, buf, &nd_btt->lbasize, |
68 | btt_lbasize_supported); | 68 | btt_lbasize_supported); |
69 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 69 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
70 | buf[len - 1] == '\n' ? "" : "\n"); | 70 | buf[len - 1] == '\n' ? "" : "\n"); |
71 | nvdimm_bus_unlock(dev); | 71 | nvdimm_bus_unlock(dev); |
72 | device_unlock(dev); | 72 | nd_device_unlock(dev); |
73 | 73 | ||
74 | return rc ? rc : len; | 74 | return rc ? rc : len; |
75 | } | 75 | } |
@@ -91,11 +91,11 @@ static ssize_t uuid_store(struct device *dev, | |||
91 | struct nd_btt *nd_btt = to_nd_btt(dev); | 91 | struct nd_btt *nd_btt = to_nd_btt(dev); |
92 | ssize_t rc; | 92 | ssize_t rc; |
93 | 93 | ||
94 | device_lock(dev); | 94 | nd_device_lock(dev); |
95 | rc = nd_uuid_store(dev, &nd_btt->uuid, buf, len); | 95 | rc = nd_uuid_store(dev, &nd_btt->uuid, buf, len); |
96 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 96 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
97 | buf[len - 1] == '\n' ? "" : "\n"); | 97 | buf[len - 1] == '\n' ? "" : "\n"); |
98 | device_unlock(dev); | 98 | nd_device_unlock(dev); |
99 | 99 | ||
100 | return rc ? rc : len; | 100 | return rc ? rc : len; |
101 | } | 101 | } |
@@ -120,13 +120,13 @@ static ssize_t namespace_store(struct device *dev, | |||
120 | struct nd_btt *nd_btt = to_nd_btt(dev); | 120 | struct nd_btt *nd_btt = to_nd_btt(dev); |
121 | ssize_t rc; | 121 | ssize_t rc; |
122 | 122 | ||
123 | device_lock(dev); | 123 | nd_device_lock(dev); |
124 | nvdimm_bus_lock(dev); | 124 | nvdimm_bus_lock(dev); |
125 | rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len); | 125 | rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len); |
126 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 126 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
127 | buf[len - 1] == '\n' ? "" : "\n"); | 127 | buf[len - 1] == '\n' ? "" : "\n"); |
128 | nvdimm_bus_unlock(dev); | 128 | nvdimm_bus_unlock(dev); |
129 | device_unlock(dev); | 129 | nd_device_unlock(dev); |
130 | 130 | ||
131 | return rc; | 131 | return rc; |
132 | } | 132 | } |
@@ -138,14 +138,14 @@ static ssize_t size_show(struct device *dev, | |||
138 | struct nd_btt *nd_btt = to_nd_btt(dev); | 138 | struct nd_btt *nd_btt = to_nd_btt(dev); |
139 | ssize_t rc; | 139 | ssize_t rc; |
140 | 140 | ||
141 | device_lock(dev); | 141 | nd_device_lock(dev); |
142 | if (dev->driver) | 142 | if (dev->driver) |
143 | rc = sprintf(buf, "%llu\n", nd_btt->size); | 143 | rc = sprintf(buf, "%llu\n", nd_btt->size); |
144 | else { | 144 | else { |
145 | /* no size to convey if the btt instance is disabled */ | 145 | /* no size to convey if the btt instance is disabled */ |
146 | rc = -ENXIO; | 146 | rc = -ENXIO; |
147 | } | 147 | } |
148 | device_unlock(dev); | 148 | nd_device_unlock(dev); |
149 | 149 | ||
150 | return rc; | 150 | return rc; |
151 | } | 151 | } |
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index df41f3571dc9..798c5c4aea9c 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | int nvdimm_major; | 27 | int nvdimm_major; |
28 | static int nvdimm_bus_major; | 28 | static int nvdimm_bus_major; |
29 | static struct class *nd_class; | 29 | struct class *nd_class; |
30 | static DEFINE_IDA(nd_ida); | 30 | static DEFINE_IDA(nd_ida); |
31 | 31 | ||
32 | static int to_nd_device_type(struct device *dev) | 32 | static int to_nd_device_type(struct device *dev) |
@@ -91,7 +91,10 @@ static int nvdimm_bus_probe(struct device *dev) | |||
91 | dev->driver->name, dev_name(dev)); | 91 | dev->driver->name, dev_name(dev)); |
92 | 92 | ||
93 | nvdimm_bus_probe_start(nvdimm_bus); | 93 | nvdimm_bus_probe_start(nvdimm_bus); |
94 | debug_nvdimm_lock(dev); | ||
94 | rc = nd_drv->probe(dev); | 95 | rc = nd_drv->probe(dev); |
96 | debug_nvdimm_unlock(dev); | ||
97 | |||
95 | if (rc == 0) | 98 | if (rc == 0) |
96 | nd_region_probe_success(nvdimm_bus, dev); | 99 | nd_region_probe_success(nvdimm_bus, dev); |
97 | else | 100 | else |
@@ -113,8 +116,11 @@ static int nvdimm_bus_remove(struct device *dev) | |||
113 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); | 116 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); |
114 | int rc = 0; | 117 | int rc = 0; |
115 | 118 | ||
116 | if (nd_drv->remove) | 119 | if (nd_drv->remove) { |
120 | debug_nvdimm_lock(dev); | ||
117 | rc = nd_drv->remove(dev); | 121 | rc = nd_drv->remove(dev); |
122 | debug_nvdimm_unlock(dev); | ||
123 | } | ||
118 | nd_region_disable(nvdimm_bus, dev); | 124 | nd_region_disable(nvdimm_bus, dev); |
119 | 125 | ||
120 | dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name, | 126 | dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name, |
@@ -140,7 +146,7 @@ static void nvdimm_bus_shutdown(struct device *dev) | |||
140 | 146 | ||
141 | void nd_device_notify(struct device *dev, enum nvdimm_event event) | 147 | void nd_device_notify(struct device *dev, enum nvdimm_event event) |
142 | { | 148 | { |
143 | device_lock(dev); | 149 | nd_device_lock(dev); |
144 | if (dev->driver) { | 150 | if (dev->driver) { |
145 | struct nd_device_driver *nd_drv; | 151 | struct nd_device_driver *nd_drv; |
146 | 152 | ||
@@ -148,7 +154,7 @@ void nd_device_notify(struct device *dev, enum nvdimm_event event) | |||
148 | if (nd_drv->notify) | 154 | if (nd_drv->notify) |
149 | nd_drv->notify(dev, event); | 155 | nd_drv->notify(dev, event); |
150 | } | 156 | } |
151 | device_unlock(dev); | 157 | nd_device_unlock(dev); |
152 | } | 158 | } |
153 | EXPORT_SYMBOL(nd_device_notify); | 159 | EXPORT_SYMBOL(nd_device_notify); |
154 | 160 | ||
@@ -296,7 +302,7 @@ static void nvdimm_bus_release(struct device *dev) | |||
296 | kfree(nvdimm_bus); | 302 | kfree(nvdimm_bus); |
297 | } | 303 | } |
298 | 304 | ||
299 | static bool is_nvdimm_bus(struct device *dev) | 305 | bool is_nvdimm_bus(struct device *dev) |
300 | { | 306 | { |
301 | return dev->release == nvdimm_bus_release; | 307 | return dev->release == nvdimm_bus_release; |
302 | } | 308 | } |
@@ -575,9 +581,9 @@ void nd_device_unregister(struct device *dev, enum nd_async_mode mode) | |||
575 | * or otherwise let the async path handle it if the | 581 | * or otherwise let the async path handle it if the |
576 | * unregistration was already queued. | 582 | * unregistration was already queued. |
577 | */ | 583 | */ |
578 | device_lock(dev); | 584 | nd_device_lock(dev); |
579 | killed = kill_device(dev); | 585 | killed = kill_device(dev); |
580 | device_unlock(dev); | 586 | nd_device_unlock(dev); |
581 | 587 | ||
582 | if (!killed) | 588 | if (!killed) |
583 | return; | 589 | return; |
@@ -888,10 +894,10 @@ void wait_nvdimm_bus_probe_idle(struct device *dev) | |||
888 | if (nvdimm_bus->probe_active == 0) | 894 | if (nvdimm_bus->probe_active == 0) |
889 | break; | 895 | break; |
890 | nvdimm_bus_unlock(dev); | 896 | nvdimm_bus_unlock(dev); |
891 | device_unlock(dev); | 897 | nd_device_unlock(dev); |
892 | wait_event(nvdimm_bus->wait, | 898 | wait_event(nvdimm_bus->wait, |
893 | nvdimm_bus->probe_active == 0); | 899 | nvdimm_bus->probe_active == 0); |
894 | device_lock(dev); | 900 | nd_device_lock(dev); |
895 | nvdimm_bus_lock(dev); | 901 | nvdimm_bus_lock(dev); |
896 | } while (true); | 902 | } while (true); |
897 | } | 903 | } |
@@ -1107,7 +1113,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, | |||
1107 | goto out; | 1113 | goto out; |
1108 | } | 1114 | } |
1109 | 1115 | ||
1110 | device_lock(dev); | 1116 | nd_device_lock(dev); |
1111 | nvdimm_bus_lock(dev); | 1117 | nvdimm_bus_lock(dev); |
1112 | rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); | 1118 | rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); |
1113 | if (rc) | 1119 | if (rc) |
@@ -1129,7 +1135,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, | |||
1129 | 1135 | ||
1130 | out_unlock: | 1136 | out_unlock: |
1131 | nvdimm_bus_unlock(dev); | 1137 | nvdimm_bus_unlock(dev); |
1132 | device_unlock(dev); | 1138 | nd_device_unlock(dev); |
1133 | out: | 1139 | out: |
1134 | kfree(in_env); | 1140 | kfree(in_env); |
1135 | kfree(out_env); | 1141 | kfree(out_env); |
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 5e1f060547bf..9204f1e9fd14 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c | |||
@@ -246,7 +246,7 @@ static int nd_uuid_parse(struct device *dev, u8 *uuid_out, const char *buf, | |||
246 | * | 246 | * |
247 | * Enforce that uuids can only be changed while the device is disabled | 247 | * Enforce that uuids can only be changed while the device is disabled |
248 | * (driver detached) | 248 | * (driver detached) |
249 | * LOCKING: expects device_lock() is held on entry | 249 | * LOCKING: expects nd_device_lock() is held on entry |
250 | */ | 250 | */ |
251 | int nd_uuid_store(struct device *dev, u8 **uuid_out, const char *buf, | 251 | int nd_uuid_store(struct device *dev, u8 **uuid_out, const char *buf, |
252 | size_t len) | 252 | size_t len) |
@@ -347,15 +347,15 @@ static DEVICE_ATTR_RO(provider); | |||
347 | 347 | ||
348 | static int flush_namespaces(struct device *dev, void *data) | 348 | static int flush_namespaces(struct device *dev, void *data) |
349 | { | 349 | { |
350 | device_lock(dev); | 350 | nd_device_lock(dev); |
351 | device_unlock(dev); | 351 | nd_device_unlock(dev); |
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
355 | static int flush_regions_dimms(struct device *dev, void *data) | 355 | static int flush_regions_dimms(struct device *dev, void *data) |
356 | { | 356 | { |
357 | device_lock(dev); | 357 | nd_device_lock(dev); |
358 | device_unlock(dev); | 358 | nd_device_unlock(dev); |
359 | device_for_each_child(dev, NULL, flush_namespaces); | 359 | device_for_each_child(dev, NULL, flush_namespaces); |
360 | return 0; | 360 | return 0; |
361 | } | 361 | } |
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index dfecd6e17043..29a065e769ea 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c | |||
@@ -484,12 +484,12 @@ static ssize_t security_store(struct device *dev, | |||
484 | * done while probing is idle and the DIMM is not in active use | 484 | * done while probing is idle and the DIMM is not in active use |
485 | * in any region. | 485 | * in any region. |
486 | */ | 486 | */ |
487 | device_lock(dev); | 487 | nd_device_lock(dev); |
488 | nvdimm_bus_lock(dev); | 488 | nvdimm_bus_lock(dev); |
489 | wait_nvdimm_bus_probe_idle(dev); | 489 | wait_nvdimm_bus_probe_idle(dev); |
490 | rc = __security_store(dev, buf, len); | 490 | rc = __security_store(dev, buf, len); |
491 | nvdimm_bus_unlock(dev); | 491 | nvdimm_bus_unlock(dev); |
492 | device_unlock(dev); | 492 | nd_device_unlock(dev); |
493 | 493 | ||
494 | return rc; | 494 | return rc; |
495 | } | 495 | } |
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index a434a5964cb9..92cd809d7e43 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -410,7 +410,7 @@ static ssize_t alt_name_store(struct device *dev, | |||
410 | struct nd_region *nd_region = to_nd_region(dev->parent); | 410 | struct nd_region *nd_region = to_nd_region(dev->parent); |
411 | ssize_t rc; | 411 | ssize_t rc; |
412 | 412 | ||
413 | device_lock(dev); | 413 | nd_device_lock(dev); |
414 | nvdimm_bus_lock(dev); | 414 | nvdimm_bus_lock(dev); |
415 | wait_nvdimm_bus_probe_idle(dev); | 415 | wait_nvdimm_bus_probe_idle(dev); |
416 | rc = __alt_name_store(dev, buf, len); | 416 | rc = __alt_name_store(dev, buf, len); |
@@ -418,7 +418,7 @@ static ssize_t alt_name_store(struct device *dev, | |||
418 | rc = nd_namespace_label_update(nd_region, dev); | 418 | rc = nd_namespace_label_update(nd_region, dev); |
419 | dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); | 419 | dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); |
420 | nvdimm_bus_unlock(dev); | 420 | nvdimm_bus_unlock(dev); |
421 | device_unlock(dev); | 421 | nd_device_unlock(dev); |
422 | 422 | ||
423 | return rc < 0 ? rc : len; | 423 | return rc < 0 ? rc : len; |
424 | } | 424 | } |
@@ -1077,7 +1077,7 @@ static ssize_t size_store(struct device *dev, | |||
1077 | if (rc) | 1077 | if (rc) |
1078 | return rc; | 1078 | return rc; |
1079 | 1079 | ||
1080 | device_lock(dev); | 1080 | nd_device_lock(dev); |
1081 | nvdimm_bus_lock(dev); | 1081 | nvdimm_bus_lock(dev); |
1082 | wait_nvdimm_bus_probe_idle(dev); | 1082 | wait_nvdimm_bus_probe_idle(dev); |
1083 | rc = __size_store(dev, val); | 1083 | rc = __size_store(dev, val); |
@@ -1103,7 +1103,7 @@ static ssize_t size_store(struct device *dev, | |||
1103 | dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc); | 1103 | dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc); |
1104 | 1104 | ||
1105 | nvdimm_bus_unlock(dev); | 1105 | nvdimm_bus_unlock(dev); |
1106 | device_unlock(dev); | 1106 | nd_device_unlock(dev); |
1107 | 1107 | ||
1108 | return rc < 0 ? rc : len; | 1108 | return rc < 0 ? rc : len; |
1109 | } | 1109 | } |
@@ -1286,7 +1286,7 @@ static ssize_t uuid_store(struct device *dev, | |||
1286 | } else | 1286 | } else |
1287 | return -ENXIO; | 1287 | return -ENXIO; |
1288 | 1288 | ||
1289 | device_lock(dev); | 1289 | nd_device_lock(dev); |
1290 | nvdimm_bus_lock(dev); | 1290 | nvdimm_bus_lock(dev); |
1291 | wait_nvdimm_bus_probe_idle(dev); | 1291 | wait_nvdimm_bus_probe_idle(dev); |
1292 | if (to_ndns(dev)->claim) | 1292 | if (to_ndns(dev)->claim) |
@@ -1302,7 +1302,7 @@ static ssize_t uuid_store(struct device *dev, | |||
1302 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 1302 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
1303 | buf[len - 1] == '\n' ? "" : "\n"); | 1303 | buf[len - 1] == '\n' ? "" : "\n"); |
1304 | nvdimm_bus_unlock(dev); | 1304 | nvdimm_bus_unlock(dev); |
1305 | device_unlock(dev); | 1305 | nd_device_unlock(dev); |
1306 | 1306 | ||
1307 | return rc < 0 ? rc : len; | 1307 | return rc < 0 ? rc : len; |
1308 | } | 1308 | } |
@@ -1376,7 +1376,7 @@ static ssize_t sector_size_store(struct device *dev, | |||
1376 | } else | 1376 | } else |
1377 | return -ENXIO; | 1377 | return -ENXIO; |
1378 | 1378 | ||
1379 | device_lock(dev); | 1379 | nd_device_lock(dev); |
1380 | nvdimm_bus_lock(dev); | 1380 | nvdimm_bus_lock(dev); |
1381 | if (to_ndns(dev)->claim) | 1381 | if (to_ndns(dev)->claim) |
1382 | rc = -EBUSY; | 1382 | rc = -EBUSY; |
@@ -1387,7 +1387,7 @@ static ssize_t sector_size_store(struct device *dev, | |||
1387 | dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote", | 1387 | dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote", |
1388 | buf, buf[len - 1] == '\n' ? "" : "\n"); | 1388 | buf, buf[len - 1] == '\n' ? "" : "\n"); |
1389 | nvdimm_bus_unlock(dev); | 1389 | nvdimm_bus_unlock(dev); |
1390 | device_unlock(dev); | 1390 | nd_device_unlock(dev); |
1391 | 1391 | ||
1392 | return rc ? rc : len; | 1392 | return rc ? rc : len; |
1393 | } | 1393 | } |
@@ -1502,9 +1502,9 @@ static ssize_t holder_show(struct device *dev, | |||
1502 | struct nd_namespace_common *ndns = to_ndns(dev); | 1502 | struct nd_namespace_common *ndns = to_ndns(dev); |
1503 | ssize_t rc; | 1503 | ssize_t rc; |
1504 | 1504 | ||
1505 | device_lock(dev); | 1505 | nd_device_lock(dev); |
1506 | rc = sprintf(buf, "%s\n", ndns->claim ? dev_name(ndns->claim) : ""); | 1506 | rc = sprintf(buf, "%s\n", ndns->claim ? dev_name(ndns->claim) : ""); |
1507 | device_unlock(dev); | 1507 | nd_device_unlock(dev); |
1508 | 1508 | ||
1509 | return rc; | 1509 | return rc; |
1510 | } | 1510 | } |
@@ -1541,7 +1541,7 @@ static ssize_t holder_class_store(struct device *dev, | |||
1541 | struct nd_region *nd_region = to_nd_region(dev->parent); | 1541 | struct nd_region *nd_region = to_nd_region(dev->parent); |
1542 | ssize_t rc; | 1542 | ssize_t rc; |
1543 | 1543 | ||
1544 | device_lock(dev); | 1544 | nd_device_lock(dev); |
1545 | nvdimm_bus_lock(dev); | 1545 | nvdimm_bus_lock(dev); |
1546 | wait_nvdimm_bus_probe_idle(dev); | 1546 | wait_nvdimm_bus_probe_idle(dev); |
1547 | rc = __holder_class_store(dev, buf); | 1547 | rc = __holder_class_store(dev, buf); |
@@ -1549,7 +1549,7 @@ static ssize_t holder_class_store(struct device *dev, | |||
1549 | rc = nd_namespace_label_update(nd_region, dev); | 1549 | rc = nd_namespace_label_update(nd_region, dev); |
1550 | dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); | 1550 | dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); |
1551 | nvdimm_bus_unlock(dev); | 1551 | nvdimm_bus_unlock(dev); |
1552 | device_unlock(dev); | 1552 | nd_device_unlock(dev); |
1553 | 1553 | ||
1554 | return rc < 0 ? rc : len; | 1554 | return rc < 0 ? rc : len; |
1555 | } | 1555 | } |
@@ -1560,7 +1560,7 @@ static ssize_t holder_class_show(struct device *dev, | |||
1560 | struct nd_namespace_common *ndns = to_ndns(dev); | 1560 | struct nd_namespace_common *ndns = to_ndns(dev); |
1561 | ssize_t rc; | 1561 | ssize_t rc; |
1562 | 1562 | ||
1563 | device_lock(dev); | 1563 | nd_device_lock(dev); |
1564 | if (ndns->claim_class == NVDIMM_CCLASS_NONE) | 1564 | if (ndns->claim_class == NVDIMM_CCLASS_NONE) |
1565 | rc = sprintf(buf, "\n"); | 1565 | rc = sprintf(buf, "\n"); |
1566 | else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) || | 1566 | else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) || |
@@ -1572,7 +1572,7 @@ static ssize_t holder_class_show(struct device *dev, | |||
1572 | rc = sprintf(buf, "dax\n"); | 1572 | rc = sprintf(buf, "dax\n"); |
1573 | else | 1573 | else |
1574 | rc = sprintf(buf, "<unknown>\n"); | 1574 | rc = sprintf(buf, "<unknown>\n"); |
1575 | device_unlock(dev); | 1575 | nd_device_unlock(dev); |
1576 | 1576 | ||
1577 | return rc; | 1577 | return rc; |
1578 | } | 1578 | } |
@@ -1586,7 +1586,7 @@ static ssize_t mode_show(struct device *dev, | |||
1586 | char *mode; | 1586 | char *mode; |
1587 | ssize_t rc; | 1587 | ssize_t rc; |
1588 | 1588 | ||
1589 | device_lock(dev); | 1589 | nd_device_lock(dev); |
1590 | claim = ndns->claim; | 1590 | claim = ndns->claim; |
1591 | if (claim && is_nd_btt(claim)) | 1591 | if (claim && is_nd_btt(claim)) |
1592 | mode = "safe"; | 1592 | mode = "safe"; |
@@ -1599,7 +1599,7 @@ static ssize_t mode_show(struct device *dev, | |||
1599 | else | 1599 | else |
1600 | mode = "raw"; | 1600 | mode = "raw"; |
1601 | rc = sprintf(buf, "%s\n", mode); | 1601 | rc = sprintf(buf, "%s\n", mode); |
1602 | device_unlock(dev); | 1602 | nd_device_unlock(dev); |
1603 | 1603 | ||
1604 | return rc; | 1604 | return rc; |
1605 | } | 1605 | } |
@@ -1703,8 +1703,8 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev) | |||
1703 | * Flush any in-progess probes / removals in the driver | 1703 | * Flush any in-progess probes / removals in the driver |
1704 | * for the raw personality of this namespace. | 1704 | * for the raw personality of this namespace. |
1705 | */ | 1705 | */ |
1706 | device_lock(&ndns->dev); | 1706 | nd_device_lock(&ndns->dev); |
1707 | device_unlock(&ndns->dev); | 1707 | nd_device_unlock(&ndns->dev); |
1708 | if (ndns->dev.driver) { | 1708 | if (ndns->dev.driver) { |
1709 | dev_dbg(&ndns->dev, "is active, can't bind %s\n", | 1709 | dev_dbg(&ndns->dev, "is active, can't bind %s\n", |
1710 | dev_name(dev)); | 1710 | dev_name(dev)); |
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index 6cd470547106..0ac52b6eb00e 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/sizes.h> | 9 | #include <linux/sizes.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
11 | #include <linux/nd.h> | 11 | #include <linux/nd.h> |
12 | #include "nd.h" | ||
12 | 13 | ||
13 | extern struct list_head nvdimm_bus_list; | 14 | extern struct list_head nvdimm_bus_list; |
14 | extern struct mutex nvdimm_bus_list_mutex; | 15 | extern struct mutex nvdimm_bus_list_mutex; |
@@ -182,4 +183,71 @@ ssize_t nd_namespace_store(struct device *dev, | |||
182 | struct nd_namespace_common **_ndns, const char *buf, | 183 | struct nd_namespace_common **_ndns, const char *buf, |
183 | size_t len); | 184 | size_t len); |
184 | struct nd_pfn *to_nd_pfn_safe(struct device *dev); | 185 | struct nd_pfn *to_nd_pfn_safe(struct device *dev); |
186 | bool is_nvdimm_bus(struct device *dev); | ||
187 | |||
188 | #ifdef CONFIG_PROVE_LOCKING | ||
189 | extern struct class *nd_class; | ||
190 | |||
191 | enum { | ||
192 | LOCK_BUS, | ||
193 | LOCK_NDCTL, | ||
194 | LOCK_REGION, | ||
195 | LOCK_DIMM = LOCK_REGION, | ||
196 | LOCK_NAMESPACE, | ||
197 | LOCK_CLAIM, | ||
198 | }; | ||
199 | |||
200 | static inline void debug_nvdimm_lock(struct device *dev) | ||
201 | { | ||
202 | if (is_nd_region(dev)) | ||
203 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_REGION); | ||
204 | else if (is_nvdimm(dev)) | ||
205 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_DIMM); | ||
206 | else if (is_nd_btt(dev) || is_nd_pfn(dev) || is_nd_dax(dev)) | ||
207 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_CLAIM); | ||
208 | else if (dev->parent && (is_nd_region(dev->parent))) | ||
209 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_NAMESPACE); | ||
210 | else if (is_nvdimm_bus(dev)) | ||
211 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_BUS); | ||
212 | else if (dev->class && dev->class == nd_class) | ||
213 | mutex_lock_nested(&dev->lockdep_mutex, LOCK_NDCTL); | ||
214 | else | ||
215 | dev_WARN(dev, "unknown lock level\n"); | ||
216 | } | ||
217 | |||
218 | static inline void debug_nvdimm_unlock(struct device *dev) | ||
219 | { | ||
220 | mutex_unlock(&dev->lockdep_mutex); | ||
221 | } | ||
222 | |||
223 | static inline void nd_device_lock(struct device *dev) | ||
224 | { | ||
225 | device_lock(dev); | ||
226 | debug_nvdimm_lock(dev); | ||
227 | } | ||
228 | |||
229 | static inline void nd_device_unlock(struct device *dev) | ||
230 | { | ||
231 | debug_nvdimm_unlock(dev); | ||
232 | device_unlock(dev); | ||
233 | } | ||
234 | #else | ||
235 | static inline void nd_device_lock(struct device *dev) | ||
236 | { | ||
237 | device_lock(dev); | ||
238 | } | ||
239 | |||
240 | static inline void nd_device_unlock(struct device *dev) | ||
241 | { | ||
242 | device_unlock(dev); | ||
243 | } | ||
244 | |||
245 | static inline void debug_nvdimm_lock(struct device *dev) | ||
246 | { | ||
247 | } | ||
248 | |||
249 | static inline void debug_nvdimm_unlock(struct device *dev) | ||
250 | { | ||
251 | } | ||
252 | #endif | ||
185 | #endif /* __ND_CORE_H__ */ | 253 | #endif /* __ND_CORE_H__ */ |
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 0f81fc56bbfd..9b09fe18e666 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c | |||
@@ -67,7 +67,7 @@ static ssize_t mode_store(struct device *dev, | |||
67 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 67 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
68 | ssize_t rc = 0; | 68 | ssize_t rc = 0; |
69 | 69 | ||
70 | device_lock(dev); | 70 | nd_device_lock(dev); |
71 | nvdimm_bus_lock(dev); | 71 | nvdimm_bus_lock(dev); |
72 | if (dev->driver) | 72 | if (dev->driver) |
73 | rc = -EBUSY; | 73 | rc = -EBUSY; |
@@ -89,7 +89,7 @@ static ssize_t mode_store(struct device *dev, | |||
89 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 89 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
90 | buf[len - 1] == '\n' ? "" : "\n"); | 90 | buf[len - 1] == '\n' ? "" : "\n"); |
91 | nvdimm_bus_unlock(dev); | 91 | nvdimm_bus_unlock(dev); |
92 | device_unlock(dev); | 92 | nd_device_unlock(dev); |
93 | 93 | ||
94 | return rc ? rc : len; | 94 | return rc ? rc : len; |
95 | } | 95 | } |
@@ -132,14 +132,14 @@ static ssize_t align_store(struct device *dev, | |||
132 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 132 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
133 | ssize_t rc; | 133 | ssize_t rc; |
134 | 134 | ||
135 | device_lock(dev); | 135 | nd_device_lock(dev); |
136 | nvdimm_bus_lock(dev); | 136 | nvdimm_bus_lock(dev); |
137 | rc = nd_size_select_store(dev, buf, &nd_pfn->align, | 137 | rc = nd_size_select_store(dev, buf, &nd_pfn->align, |
138 | nd_pfn_supported_alignments()); | 138 | nd_pfn_supported_alignments()); |
139 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 139 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
140 | buf[len - 1] == '\n' ? "" : "\n"); | 140 | buf[len - 1] == '\n' ? "" : "\n"); |
141 | nvdimm_bus_unlock(dev); | 141 | nvdimm_bus_unlock(dev); |
142 | device_unlock(dev); | 142 | nd_device_unlock(dev); |
143 | 143 | ||
144 | return rc ? rc : len; | 144 | return rc ? rc : len; |
145 | } | 145 | } |
@@ -161,11 +161,11 @@ static ssize_t uuid_store(struct device *dev, | |||
161 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 161 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
162 | ssize_t rc; | 162 | ssize_t rc; |
163 | 163 | ||
164 | device_lock(dev); | 164 | nd_device_lock(dev); |
165 | rc = nd_uuid_store(dev, &nd_pfn->uuid, buf, len); | 165 | rc = nd_uuid_store(dev, &nd_pfn->uuid, buf, len); |
166 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 166 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
167 | buf[len - 1] == '\n' ? "" : "\n"); | 167 | buf[len - 1] == '\n' ? "" : "\n"); |
168 | device_unlock(dev); | 168 | nd_device_unlock(dev); |
169 | 169 | ||
170 | return rc ? rc : len; | 170 | return rc ? rc : len; |
171 | } | 171 | } |
@@ -190,13 +190,13 @@ static ssize_t namespace_store(struct device *dev, | |||
190 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 190 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
191 | ssize_t rc; | 191 | ssize_t rc; |
192 | 192 | ||
193 | device_lock(dev); | 193 | nd_device_lock(dev); |
194 | nvdimm_bus_lock(dev); | 194 | nvdimm_bus_lock(dev); |
195 | rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len); | 195 | rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len); |
196 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, | 196 | dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, |
197 | buf[len - 1] == '\n' ? "" : "\n"); | 197 | buf[len - 1] == '\n' ? "" : "\n"); |
198 | nvdimm_bus_unlock(dev); | 198 | nvdimm_bus_unlock(dev); |
199 | device_unlock(dev); | 199 | nd_device_unlock(dev); |
200 | 200 | ||
201 | return rc; | 201 | return rc; |
202 | } | 202 | } |
@@ -208,7 +208,7 @@ static ssize_t resource_show(struct device *dev, | |||
208 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 208 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
209 | ssize_t rc; | 209 | ssize_t rc; |
210 | 210 | ||
211 | device_lock(dev); | 211 | nd_device_lock(dev); |
212 | if (dev->driver) { | 212 | if (dev->driver) { |
213 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; | 213 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
214 | u64 offset = __le64_to_cpu(pfn_sb->dataoff); | 214 | u64 offset = __le64_to_cpu(pfn_sb->dataoff); |
@@ -222,7 +222,7 @@ static ssize_t resource_show(struct device *dev, | |||
222 | /* no address to convey if the pfn instance is disabled */ | 222 | /* no address to convey if the pfn instance is disabled */ |
223 | rc = -ENXIO; | 223 | rc = -ENXIO; |
224 | } | 224 | } |
225 | device_unlock(dev); | 225 | nd_device_unlock(dev); |
226 | 226 | ||
227 | return rc; | 227 | return rc; |
228 | } | 228 | } |
@@ -234,7 +234,7 @@ static ssize_t size_show(struct device *dev, | |||
234 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); | 234 | struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); |
235 | ssize_t rc; | 235 | ssize_t rc; |
236 | 236 | ||
237 | device_lock(dev); | 237 | nd_device_lock(dev); |
238 | if (dev->driver) { | 238 | if (dev->driver) { |
239 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; | 239 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
240 | u64 offset = __le64_to_cpu(pfn_sb->dataoff); | 240 | u64 offset = __le64_to_cpu(pfn_sb->dataoff); |
@@ -250,7 +250,7 @@ static ssize_t size_show(struct device *dev, | |||
250 | /* no size to convey if the pfn instance is disabled */ | 250 | /* no size to convey if the pfn instance is disabled */ |
251 | rc = -ENXIO; | 251 | rc = -ENXIO; |
252 | } | 252 | } |
253 | device_unlock(dev); | 253 | nd_device_unlock(dev); |
254 | 254 | ||
255 | return rc; | 255 | return rc; |
256 | } | 256 | } |
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 28cb44c61d4a..53797e7be18a 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c | |||
@@ -520,8 +520,8 @@ static int nd_pmem_remove(struct device *dev) | |||
520 | nvdimm_namespace_detach_btt(to_nd_btt(dev)); | 520 | nvdimm_namespace_detach_btt(to_nd_btt(dev)); |
521 | else { | 521 | else { |
522 | /* | 522 | /* |
523 | * Note, this assumes device_lock() context to not race | 523 | * Note, this assumes nd_device_lock() context to not |
524 | * nd_pmem_notify() | 524 | * race nd_pmem_notify() |
525 | */ | 525 | */ |
526 | sysfs_put(pmem->bb_state); | 526 | sysfs_put(pmem->bb_state); |
527 | pmem->bb_state = NULL; | 527 | pmem->bb_state = NULL; |
diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 488c47ac4c4a..37bf8719a2a4 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c | |||
@@ -102,7 +102,7 @@ static int nd_region_remove(struct device *dev) | |||
102 | nvdimm_bus_unlock(dev); | 102 | nvdimm_bus_unlock(dev); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Note, this assumes device_lock() context to not race | 105 | * Note, this assumes nd_device_lock() context to not race |
106 | * nd_region_notify() | 106 | * nd_region_notify() |
107 | */ | 107 | */ |
108 | sysfs_put(nd_region->bb_state); | 108 | sysfs_put(nd_region->bb_state); |
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index a15276cdec7d..91b5a7ade0d5 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c | |||
@@ -329,7 +329,7 @@ static ssize_t set_cookie_show(struct device *dev, | |||
329 | * the v1.1 namespace label cookie definition. To read all this | 329 | * the v1.1 namespace label cookie definition. To read all this |
330 | * data we need to wait for probing to settle. | 330 | * data we need to wait for probing to settle. |
331 | */ | 331 | */ |
332 | device_lock(dev); | 332 | nd_device_lock(dev); |
333 | nvdimm_bus_lock(dev); | 333 | nvdimm_bus_lock(dev); |
334 | wait_nvdimm_bus_probe_idle(dev); | 334 | wait_nvdimm_bus_probe_idle(dev); |
335 | if (nd_region->ndr_mappings) { | 335 | if (nd_region->ndr_mappings) { |
@@ -346,7 +346,7 @@ static ssize_t set_cookie_show(struct device *dev, | |||
346 | } | 346 | } |
347 | } | 347 | } |
348 | nvdimm_bus_unlock(dev); | 348 | nvdimm_bus_unlock(dev); |
349 | device_unlock(dev); | 349 | nd_device_unlock(dev); |
350 | 350 | ||
351 | if (rc) | 351 | if (rc) |
352 | return rc; | 352 | return rc; |
@@ -422,12 +422,12 @@ static ssize_t available_size_show(struct device *dev, | |||
422 | * memory nvdimm_bus_lock() is dropped, but that's userspace's | 422 | * memory nvdimm_bus_lock() is dropped, but that's userspace's |
423 | * problem to not race itself. | 423 | * problem to not race itself. |
424 | */ | 424 | */ |
425 | device_lock(dev); | 425 | nd_device_lock(dev); |
426 | nvdimm_bus_lock(dev); | 426 | nvdimm_bus_lock(dev); |
427 | wait_nvdimm_bus_probe_idle(dev); | 427 | wait_nvdimm_bus_probe_idle(dev); |
428 | available = nd_region_available_dpa(nd_region); | 428 | available = nd_region_available_dpa(nd_region); |
429 | nvdimm_bus_unlock(dev); | 429 | nvdimm_bus_unlock(dev); |
430 | device_unlock(dev); | 430 | nd_device_unlock(dev); |
431 | 431 | ||
432 | return sprintf(buf, "%llu\n", available); | 432 | return sprintf(buf, "%llu\n", available); |
433 | } | 433 | } |
@@ -439,12 +439,12 @@ static ssize_t max_available_extent_show(struct device *dev, | |||
439 | struct nd_region *nd_region = to_nd_region(dev); | 439 | struct nd_region *nd_region = to_nd_region(dev); |
440 | unsigned long long available = 0; | 440 | unsigned long long available = 0; |
441 | 441 | ||
442 | device_lock(dev); | 442 | nd_device_lock(dev); |
443 | nvdimm_bus_lock(dev); | 443 | nvdimm_bus_lock(dev); |
444 | wait_nvdimm_bus_probe_idle(dev); | 444 | wait_nvdimm_bus_probe_idle(dev); |
445 | available = nd_region_allocatable_dpa(nd_region); | 445 | available = nd_region_allocatable_dpa(nd_region); |
446 | nvdimm_bus_unlock(dev); | 446 | nvdimm_bus_unlock(dev); |
447 | device_unlock(dev); | 447 | nd_device_unlock(dev); |
448 | 448 | ||
449 | return sprintf(buf, "%llu\n", available); | 449 | return sprintf(buf, "%llu\n", available); |
450 | } | 450 | } |
@@ -563,12 +563,12 @@ static ssize_t region_badblocks_show(struct device *dev, | |||
563 | struct nd_region *nd_region = to_nd_region(dev); | 563 | struct nd_region *nd_region = to_nd_region(dev); |
564 | ssize_t rc; | 564 | ssize_t rc; |
565 | 565 | ||
566 | device_lock(dev); | 566 | nd_device_lock(dev); |
567 | if (dev->driver) | 567 | if (dev->driver) |
568 | rc = badblocks_show(&nd_region->bb, buf, 0); | 568 | rc = badblocks_show(&nd_region->bb, buf, 0); |
569 | else | 569 | else |
570 | rc = -ENXIO; | 570 | rc = -ENXIO; |
571 | device_unlock(dev); | 571 | nd_device_unlock(dev); |
572 | 572 | ||
573 | return rc; | 573 | return rc; |
574 | } | 574 | } |
diff --git a/include/linux/device.h b/include/linux/device.h index 0da5c67f6be1..9237b857b598 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -909,6 +909,8 @@ struct dev_links_info { | |||
909 | * This identifies the device type and carries type-specific | 909 | * This identifies the device type and carries type-specific |
910 | * information. | 910 | * information. |
911 | * @mutex: Mutex to synchronize calls to its driver. | 911 | * @mutex: Mutex to synchronize calls to its driver. |
912 | * @lockdep_mutex: An optional debug lock that a subsystem can use as a | ||
913 | * peer lock to gain localized lockdep coverage of the device_lock. | ||
912 | * @bus: Type of bus device is on. | 914 | * @bus: Type of bus device is on. |
913 | * @driver: Which driver has allocated this | 915 | * @driver: Which driver has allocated this |
914 | * @platform_data: Platform data specific to the device. | 916 | * @platform_data: Platform data specific to the device. |
@@ -991,6 +993,9 @@ struct device { | |||
991 | core doesn't touch it */ | 993 | core doesn't touch it */ |
992 | void *driver_data; /* Driver data, set and get with | 994 | void *driver_data; /* Driver data, set and get with |
993 | dev_set_drvdata/dev_get_drvdata */ | 995 | dev_set_drvdata/dev_get_drvdata */ |
996 | #ifdef CONFIG_PROVE_LOCKING | ||
997 | struct mutex lockdep_mutex; | ||
998 | #endif | ||
994 | struct mutex mutex; /* mutex to synchronize calls to | 999 | struct mutex mutex; /* mutex to synchronize calls to |
995 | * its driver. | 1000 | * its driver. |
996 | */ | 1001 | */ |