Message ID | 156341207332.292348.14959761496009347574.stgit@dwillia2-desk3.amr.corp.intel.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 00289cd87676e14913d2d8492d1ce05c4baafdae |
Headers | show |
Series | libnvdimm: Fix async operations and locking | expand |
On Wed, Jul 17, 2019 at 06:07:53PM -0700, Dan Williams wrote: > The libnvdimm subsystem arranges for devices to be destroyed as a result > of a sysfs operation. Since device_unregister() cannot be called from > an actively running sysfs attribute of the same device libnvdimm > arranges for device_unregister() to be performed in an out-of-line async > context. > > The driver core maintains a 'dead' state for coordinating its own racing > async registration / de-registration requests. Rather than add local > 'dead' state tracking infrastructure to libnvdimm device objects, export > the existing state tracking via a new kill_device() helper. > > The kill_device() helper simply marks the device as dead, i.e. that it > is on its way to device_del(), or returns that the device was already > dead. This can be used in advance of calling device_unregister() for > subsystems like libnvdimm that might need to handle multiple user > threads racing to delete a device. > > This refactoring does not change any behavior, but it is a pre-requisite > for follow-on fixes and therefore marked for -stable. > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Cc: "Rafael J. Wysocki" <rafael@kernel.org> > Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver...") > Cc: <stable@vger.kernel.org> > Tested-by: Jane Chu <jane.chu@oracle.com> > Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Hi, [This is an automated email] This commit has been processed because it contains a "Fixes:" tag, fixing commit: 4d88a97aa9e8 libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver infrastructure. The bot has tested the following trees: v5.2.1, v5.1.18, v4.19.59, v4.14.133, v4.9.185, v4.4.185. v5.2.1: Build OK! v5.1.18: Build OK! v4.19.59: Failed to apply! Possible dependencies: 3451a495ef24 ("driver core: Establish order of operations for device_add and device_del via bitflag") v4.14.133: Failed to apply! Possible dependencies: 3451a495ef24 ("driver core: Establish order of operations for device_add and device_del via bitflag") v4.9.185: Failed to apply! Possible dependencies: 3451a495ef24 ("driver core: Establish order of operations for device_add and device_del via bitflag") v4.4.185: Failed to apply! Possible dependencies: 3451a495ef24 ("driver core: Establish order of operations for device_add and device_del via bitflag") 656b8035b0ee ("ARM: 8524/1: driver cohandle -EPROBE_DEFER from bus_type.match()") NOTE: The patch will not be queued to stable trees until it is upstream. How should we proceed with this patch? -- Thanks, Sasha
diff --git a/drivers/base/core.c b/drivers/base/core.c index fd7511e04e62..eaf3aa0cb803 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2211,6 +2211,24 @@ void put_device(struct device *dev) } EXPORT_SYMBOL_GPL(put_device); +bool kill_device(struct device *dev) +{ + /* + * Require the device lock and set the "dead" flag to guarantee that + * the update behavior is consistent with the other bitfields near + * it and that we cannot have an asynchronous probe routine trying + * to run while we are tearing out the bus/class/sysfs from + * underneath the device. + */ + lockdep_assert_held(&dev->mutex); + + if (dev->p->dead) + return false; + dev->p->dead = true; + return true; +} +EXPORT_SYMBOL_GPL(kill_device); + /** * device_del - delete device from system. * @dev: device. @@ -2230,15 +2248,8 @@ void device_del(struct device *dev) struct kobject *glue_dir = NULL; struct class_interface *class_intf; - /* - * Hold the device lock and set the "dead" flag to guarantee that - * the update behavior is consistent with the other bitfields near - * it and that we cannot have an asynchronous probe routine trying - * to run while we are tearing out the bus/class/sysfs from - * underneath the device. - */ device_lock(dev); - dev->p->dead = true; + kill_device(dev); device_unlock(dev); /* Notify clients of device removal. This call must come diff --git a/include/linux/device.h b/include/linux/device.h index e85264fb6616..0da5c67f6be1 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1373,6 +1373,7 @@ extern int (*platform_notify_remove)(struct device *dev); */ extern struct device *get_device(struct device *dev); extern void put_device(struct device *dev); +extern bool kill_device(struct device *dev); #ifdef CONFIG_DEVTMPFS extern int devtmpfs_create_node(struct device *dev);