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:
@@ -1282,7 +1282,7 @@ static ssize_t hw_error_scrub_store(struct device *dev,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
device_lock(dev);
|
||||
nfit_device_lock(dev);
|
||||
nd_desc = dev_get_drvdata(dev);
|
||||
if (nd_desc) {
|
||||
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,
|
||||
break;
|
||||
}
|
||||
}
|
||||
device_unlock(dev);
|
||||
nfit_device_unlock(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
return size;
|
||||
@@ -1319,7 +1319,7 @@ static ssize_t scrub_show(struct device *dev,
|
||||
ssize_t rc = -ENXIO;
|
||||
bool busy;
|
||||
|
||||
device_lock(dev);
|
||||
nfit_device_lock(dev);
|
||||
nd_desc = dev_get_drvdata(dev);
|
||||
if (!nd_desc) {
|
||||
device_unlock(dev);
|
||||
@@ -1339,7 +1339,7 @@ static ssize_t scrub_show(struct device *dev,
|
||||
}
|
||||
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
device_unlock(dev);
|
||||
nfit_device_unlock(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1356,14 +1356,14 @@ static ssize_t scrub_store(struct device *dev,
|
||||
if (val != 1)
|
||||
return -EINVAL;
|
||||
|
||||
device_lock(dev);
|
||||
nfit_device_lock(dev);
|
||||
nd_desc = dev_get_drvdata(dev);
|
||||
if (nd_desc) {
|
||||
struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
|
||||
|
||||
rc = acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG);
|
||||
}
|
||||
device_unlock(dev);
|
||||
nfit_device_unlock(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
return size;
|
||||
@@ -1749,9 +1749,9 @@ static void acpi_nvdimm_notify(acpi_handle handle, u32 event, void *data)
|
||||
struct acpi_device *adev = data;
|
||||
struct device *dev = &adev->dev;
|
||||
|
||||
device_lock(dev->parent);
|
||||
nfit_device_lock(dev->parent);
|
||||
__acpi_nvdimm_notify(dev, event);
|
||||
device_unlock(dev->parent);
|
||||
nfit_device_unlock(dev->parent);
|
||||
}
|
||||
|
||||
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)
|
||||
struct device *dev = acpi_desc->dev;
|
||||
|
||||
/* Bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */
|
||||
device_lock(dev);
|
||||
device_unlock(dev);
|
||||
nfit_device_lock(dev);
|
||||
nfit_device_unlock(dev);
|
||||
|
||||
/* Bounce the init_mutex to complete initial registration */
|
||||
mutex_lock(&acpi_desc->init_mutex);
|
||||
@@ -3602,8 +3602,8 @@ void acpi_nfit_shutdown(void *data)
|
||||
* acpi_nfit_ars_rescan() submissions have had a chance to
|
||||
* either submit or see ->cancel set.
|
||||
*/
|
||||
device_lock(bus_dev);
|
||||
device_unlock(bus_dev);
|
||||
nfit_device_lock(bus_dev);
|
||||
nfit_device_unlock(bus_dev);
|
||||
|
||||
flush_workqueue(nfit_wq);
|
||||
}
|
||||
@@ -3746,9 +3746,9 @@ EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
|
||||
|
||||
static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
|
||||
{
|
||||
device_lock(&adev->dev);
|
||||
nfit_device_lock(&adev->dev);
|
||||
__acpi_nfit_notify(&adev->dev, adev->handle, event);
|
||||
device_unlock(&adev->dev);
|
||||
nfit_device_unlock(&adev->dev);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id acpi_nfit_ids[] = {
|
||||
|
@@ -312,6 +312,30 @@ static inline struct acpi_nfit_desc *to_acpi_desc(
|
||||
return container_of(nd_desc, struct acpi_nfit_desc, nd_desc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
static inline void nfit_device_lock(struct device *dev)
|
||||
{
|
||||
device_lock(dev);
|
||||
mutex_lock(&dev->lockdep_mutex);
|
||||
}
|
||||
|
||||
static inline void nfit_device_unlock(struct device *dev)
|
||||
{
|
||||
mutex_unlock(&dev->lockdep_mutex);
|
||||
device_unlock(dev);
|
||||
}
|
||||
#else
|
||||
static inline void nfit_device_lock(struct device *dev)
|
||||
{
|
||||
device_lock(dev);
|
||||
}
|
||||
|
||||
static inline void nfit_device_unlock(struct device *dev)
|
||||
{
|
||||
device_unlock(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
const guid_t *to_nfit_uuid(enum nfit_uuids id);
|
||||
int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
|
||||
void acpi_nfit_shutdown(void *data);
|
||||
|
Viittaa uudesa ongelmassa
Block a user