Merge tag 'libnvdimm-fixes-5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams: "A collection of locking and async operations fixes for v5.3-rc2. These had been soaking in a branch targeting the merge window, but missed due to a regression hunt. This fixed up version has otherwise been in -next this past week with no reported issues. In order to gain confidence in the locking changes the pull also includes a debug / instrumentation patch to enable lockdep coverage for libnvdimm subsystem operations that depend on the device_lock for exclusion. As mentioned in the changelog it is a hack, but it works and documents the locking expectations of the sub-system in a way that others can use lockdep to verify. The driver core touches got an ack from Greg. Summary: - Fix duplicate device_unregister() calls (multiple threads competing to do unregister work when scheduling device removal from a sysfs attribute of the self-same device). - Fix badblocks registration order bug. Ensure region badblocks are initialized in advance of namespace registration. - Fix a deadlock between the bus lock and probe operations. - Export device-core infrastructure to coordinate async operations via the device ->dead state. - Add device-core infrastructure to validate device_lock() usage with lockdep" * tag 'libnvdimm-fixes-5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: driver-core, libnvdimm: Let device subsystems add local lockdep coverage libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA deadlock libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl() libnvdimm/bus: Prepare the nd_ioctl() path to be re-entrant libnvdimm/region: Register badblocks before namespaces libnvdimm/bus: Prevent duplicate device_unregister() calls drivers/base: Introduce kill_device()
This commit is contained in:
@@ -410,7 +410,7 @@ static ssize_t alt_name_store(struct device *dev,
|
||||
struct nd_region *nd_region = to_nd_region(dev->parent);
|
||||
ssize_t rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
nvdimm_bus_lock(dev);
|
||||
wait_nvdimm_bus_probe_idle(dev);
|
||||
rc = __alt_name_store(dev, buf, len);
|
||||
@@ -418,7 +418,7 @@ static ssize_t alt_name_store(struct device *dev,
|
||||
rc = nd_namespace_label_update(nd_region, dev);
|
||||
dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc);
|
||||
nvdimm_bus_unlock(dev);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc < 0 ? rc : len;
|
||||
}
|
||||
@@ -1077,7 +1077,7 @@ static ssize_t size_store(struct device *dev,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
nvdimm_bus_lock(dev);
|
||||
wait_nvdimm_bus_probe_idle(dev);
|
||||
rc = __size_store(dev, val);
|
||||
@@ -1103,7 +1103,7 @@ static ssize_t size_store(struct device *dev,
|
||||
dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc);
|
||||
|
||||
nvdimm_bus_unlock(dev);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc < 0 ? rc : len;
|
||||
}
|
||||
@@ -1286,7 +1286,7 @@ static ssize_t uuid_store(struct device *dev,
|
||||
} else
|
||||
return -ENXIO;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
nvdimm_bus_lock(dev);
|
||||
wait_nvdimm_bus_probe_idle(dev);
|
||||
if (to_ndns(dev)->claim)
|
||||
@@ -1302,7 +1302,7 @@ static ssize_t uuid_store(struct device *dev,
|
||||
dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf,
|
||||
buf[len - 1] == '\n' ? "" : "\n");
|
||||
nvdimm_bus_unlock(dev);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc < 0 ? rc : len;
|
||||
}
|
||||
@@ -1376,7 +1376,7 @@ static ssize_t sector_size_store(struct device *dev,
|
||||
} else
|
||||
return -ENXIO;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
nvdimm_bus_lock(dev);
|
||||
if (to_ndns(dev)->claim)
|
||||
rc = -EBUSY;
|
||||
@@ -1387,7 +1387,7 @@ static ssize_t sector_size_store(struct device *dev,
|
||||
dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote",
|
||||
buf, buf[len - 1] == '\n' ? "" : "\n");
|
||||
nvdimm_bus_unlock(dev);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc ? rc : len;
|
||||
}
|
||||
@@ -1502,9 +1502,9 @@ static ssize_t holder_show(struct device *dev,
|
||||
struct nd_namespace_common *ndns = to_ndns(dev);
|
||||
ssize_t rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
rc = sprintf(buf, "%s\n", ndns->claim ? dev_name(ndns->claim) : "");
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1541,7 +1541,7 @@ static ssize_t holder_class_store(struct device *dev,
|
||||
struct nd_region *nd_region = to_nd_region(dev->parent);
|
||||
ssize_t rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
nvdimm_bus_lock(dev);
|
||||
wait_nvdimm_bus_probe_idle(dev);
|
||||
rc = __holder_class_store(dev, buf);
|
||||
@@ -1549,7 +1549,7 @@ static ssize_t holder_class_store(struct device *dev,
|
||||
rc = nd_namespace_label_update(nd_region, dev);
|
||||
dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc);
|
||||
nvdimm_bus_unlock(dev);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc < 0 ? rc : len;
|
||||
}
|
||||
@@ -1560,7 +1560,7 @@ static ssize_t holder_class_show(struct device *dev,
|
||||
struct nd_namespace_common *ndns = to_ndns(dev);
|
||||
ssize_t rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
if (ndns->claim_class == NVDIMM_CCLASS_NONE)
|
||||
rc = sprintf(buf, "\n");
|
||||
else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) ||
|
||||
@@ -1572,7 +1572,7 @@ static ssize_t holder_class_show(struct device *dev,
|
||||
rc = sprintf(buf, "dax\n");
|
||||
else
|
||||
rc = sprintf(buf, "<unknown>\n");
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1586,7 +1586,7 @@ static ssize_t mode_show(struct device *dev,
|
||||
char *mode;
|
||||
ssize_t rc;
|
||||
|
||||
device_lock(dev);
|
||||
nd_device_lock(dev);
|
||||
claim = ndns->claim;
|
||||
if (claim && is_nd_btt(claim))
|
||||
mode = "safe";
|
||||
@@ -1599,7 +1599,7 @@ static ssize_t mode_show(struct device *dev,
|
||||
else
|
||||
mode = "raw";
|
||||
rc = sprintf(buf, "%s\n", mode);
|
||||
device_unlock(dev);
|
||||
nd_device_unlock(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1703,8 +1703,8 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)
|
||||
* Flush any in-progess probes / removals in the driver
|
||||
* for the raw personality of this namespace.
|
||||
*/
|
||||
device_lock(&ndns->dev);
|
||||
device_unlock(&ndns->dev);
|
||||
nd_device_lock(&ndns->dev);
|
||||
nd_device_unlock(&ndns->dev);
|
||||
if (ndns->dev.driver) {
|
||||
dev_dbg(&ndns->dev, "is active, can't bind %s\n",
|
||||
dev_name(dev));
|
||||
|
Reference in New Issue
Block a user