All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Dan Williams <dan.j.williams@intel.com>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Alexander Duyck <alexander.h.duyck@linux.intel.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.19 03/45] driver core: Establish order of operations for device_add and device_del via bitflag
Date: Thu,  8 Aug 2019 21:04:49 +0200	[thread overview]
Message-ID: <20190808190454.008105790@linuxfoundation.org> (raw)
In-Reply-To: <20190808190453.827571908@linuxfoundation.org>

commit 3451a495ef244a88ed6317a035299d835554d579 upstream.

Add an additional bit flag to the device_private struct named "dead".

This additional flag provides a guarantee that when a device_del is
executed on a given interface an async worker will not attempt to attach
the driver following the earlier device_del call. Previously this
guarantee was not present and could result in the device_del call
attempting to remove a driver from an interface only to have the async
worker attempt to probe the driver later when it finally completes the
asynchronous probe call.

One additional change added was that I pulled the check for dev->driver
out of the __device_attach_driver call and instead placed it in the
__device_attach_async_helper call. This was motivated by the fact that the
only other caller of this, __device_attach, had already taken the
device_lock() and checked for dev->driver. Instead of testing for this
twice in this path it makes more sense to just consolidate the dev->dead
and dev->driver checks together into one set of checks.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/base/base.h |  4 ++++
 drivers/base/core.c | 11 +++++++++++
 drivers/base/dd.c   | 22 +++++++++++-----------
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 7a419a7a6235b..559b047de9f75 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -66,6 +66,9 @@ struct driver_private {
  *	probed first.
  * @device - pointer back to the struct device that this structure is
  * associated with.
+ * @dead - This device is currently either in the process of or has been
+ *	removed from the system. Any asynchronous events scheduled for this
+ *	device should exit without taking any action.
  *
  * Nothing outside of the driver core should ever touch these fields.
  */
@@ -76,6 +79,7 @@ struct device_private {
 	struct klist_node knode_bus;
 	struct list_head deferred_probe;
 	struct device *device;
+	u8 dead:1;
 };
 #define to_device_private_parent(obj)	\
 	container_of(obj, struct device_private, knode_parent)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 92e2c32c22270..37a90d72f3736 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2050,6 +2050,17 @@ 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;
+	device_unlock(dev);
+
 	/* Notify clients of device removal.  This call must come
 	 * before dpm_sysfs_remove().
 	 */
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index d48b310c47603..11d24a552ee49 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -725,15 +725,6 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
 	bool async_allowed;
 	int ret;
 
-	/*
-	 * Check if device has already been claimed. This may
-	 * happen with driver loading, device discovery/registration,
-	 * and deferred probe processing happens all at once with
-	 * multiple threads.
-	 */
-	if (dev->driver)
-		return -EBUSY;
-
 	ret = driver_match_device(drv, dev);
 	if (ret == 0) {
 		/* no match */
@@ -768,6 +759,15 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
 
 	device_lock(dev);
 
+	/*
+	 * Check if device has already been removed or claimed. This may
+	 * happen with driver loading, device discovery/registration,
+	 * and deferred probe processing happens all at once with
+	 * multiple threads.
+	 */
+	if (dev->p->dead || dev->driver)
+		goto out_unlock;
+
 	if (dev->parent)
 		pm_runtime_get_sync(dev->parent);
 
@@ -778,7 +778,7 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
 
 	if (dev->parent)
 		pm_runtime_put(dev->parent);
-
+out_unlock:
 	device_unlock(dev);
 
 	put_device(dev);
@@ -891,7 +891,7 @@ static int __driver_attach(struct device *dev, void *data)
 	if (dev->parent && dev->bus->need_parent_lock)
 		device_lock(dev->parent);
 	device_lock(dev);
-	if (!dev->driver)
+	if (!dev->p->dead && !dev->driver)
 		driver_probe_device(drv, dev);
 	device_unlock(dev);
 	if (dev->parent && dev->bus->need_parent_lock)
-- 
2.20.1




  parent reply	other threads:[~2019-08-08 19:14 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-08 19:04 [PATCH 4.19 00/45] 4.19.66-stable review Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 01/45] scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 02/45] gcc-9: dont warn about uninitialized variable Greg Kroah-Hartman
2019-08-08 19:04 ` Greg Kroah-Hartman [this message]
2019-08-08 19:04 ` [PATCH 4.19 04/45] drivers/base: Introduce kill_device() Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 05/45] libnvdimm/bus: Prevent duplicate device_unregister() calls Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 06/45] libnvdimm/region: Register badblocks before namespaces Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 07/45] libnvdimm/bus: Prepare the nd_ioctl() path to be re-entrant Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 08/45] libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA deadlock Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 09/45] HID: wacom: fix bit shift for Cintiq Companion 2 Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 10/45] HID: Add quirk for HP X1200 PIXART OEM mouse Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 11/45] [PATCH] IB: directly cast the sockaddr union to aockaddr Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 12/45] atm: iphase: Fix Spectre v1 vulnerability Greg Kroah-Hartman
2019-08-08 19:04 ` [PATCH 4.19 13/45] bnx2x: Disable multi-cos feature Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 14/45] ife: error out when nla attributes are empty Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 15/45] ip6_gre: reload ipv6h in prepare_ip6gre_xmit_ipv6 Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 16/45] ip6_tunnel: fix possible use-after-free on xmit Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 17/45] ipip: validate header length in ipip_tunnel_xmit Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 18/45] mlxsw: spectrum: Fix error path in mlxsw_sp_module_init() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 19/45] mvpp2: fix panic on module removal Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 20/45] mvpp2: refactor MTU change code Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 21/45] net: bridge: delete local fdb on device init failure Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 22/45] net: bridge: mcast: dont delete permanent entries when fast leave is enabled Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 23/45] net: fix ifindex collision during namespace removal Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 24/45] net/mlx5e: always initialize frag->last_in_page Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 25/45] net/mlx5: Use reversed order when unregister devices Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 26/45] net: phylink: Fix flow control for fixed-link Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 27/45] net: qualcomm: rmnet: Fix incorrect UL checksum offload logic Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 28/45] net: sched: Fix a possible null-pointer dereference in dequeue_func() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 29/45] net sched: update vlan action for batched events operations Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 30/45] net: sched: use temporary variable for actions indexes Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 31/45] net/smc: do not schedule tx_work in SMC_CLOSED state Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 32/45] NFC: nfcmrvl: fix gpio-handling regression Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 33/45] ocelot: Cancel delayed work before wq destruction Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 34/45] tipc: compat: allow tipc commands without arguments Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 35/45] tun: mark small packets as owned by the tap sock Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 36/45] net/mlx5: Fix modify_cq_in alignment Greg Kroah-Hartman
2019-08-10 11:25   ` Pavel Machek
2019-08-11  6:17     ` Leon Romanovsky
2019-08-08 19:05 ` [PATCH 4.19 37/45] net/mlx5e: Prevent encap flow counter update async to user query Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 38/45] r8169: dont use MSI before RTL8168d Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 39/45] compat_ioctl: pppoe: fix PPPOEIOCSFWD handling Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 40/45] cgroup: Call cgroup_release() before __exit_signal() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 41/45] cgroup: Implement css_task_iter_skip() Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 42/45] cgroup: Include dying leaders with live threads in PROCS iterations Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 43/45] cgroup: css_task_iter_skip()d iterators must be advanced before accessed Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 44/45] cgroup: Fix css_task_iter_advance_css_set() cset skip condition Greg Kroah-Hartman
2019-08-08 19:05 ` [PATCH 4.19 45/45] spi: bcm2835: Fix 3-wire mode if DMA is enabled Greg Kroah-Hartman
2019-08-09  0:37 ` [PATCH 4.19 00/45] 4.19.66-stable review shuah
2019-08-09  3:20 ` Naresh Kamboju
2019-08-09 14:49 ` Thierry Reding
2019-08-09 14:49   ` Thierry Reding
2019-08-09 15:37 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190808190454.008105790@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=alexander.h.duyck@linux.intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.