[RFC PATCH 0/4] device_schedule_reprobe(): core helper and conversions

Daniel Golle <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth,dev.linux.lists.driver-core,org.kernel.vger.linux-kernel,org.kernel.vger.linux-wireless,org.kernel.vger.netdev
Message-ID <[email protected]>
Three in-tree drivers (iwlwifi, hci_h5, btintel_pcie) schedule a
deferred re-probe of their own device from a work item in module
text. The hand-rolled copies share two bug classes: the work function
ends with module_put(THIS_MODULE), racing a concurrent rmmod freeing
the module text (the race module_put_and_kthread_exit() exists to
close for kthreads), and nothing synchronizes the deferred detach
against device_shutdown() or an administrative unbind.

Patch 1 moves the deferred work into the driver core.
device_schedule_reprobe() runs builtin code, so no module reference
is needed; it checks under a single __device_driver_lock() hold that
the device is still bound to the driver that scheduled the re-probe,
and skips the detach once device_shutdown() has reached the device
(a new one-bit shutdown_done flag in struct device_private). Patches
2 and 3 are mechanical conversions. Patch 4 (btintel_pcie) also
removes that driver's remove()-from-own-work contract; it changes
more and can be dropped without affecting patches 1-3.

This grew out of review of the mxl862xx DSA series [1][2], which
copied the iwlwifi pattern. There ->shutdown() clears drvdata so that
->remove() becomes a no-op, a stale re-probe escalates to
use-after-free, and its v10 cover letter walks through why a driver
cannot fully close the race itself: device_shutdown() holds
device_lock() across ->shutdown() and device_reprobe() takes the same
lock, so any driver-side check remains a TOCTOU. The helper closes it
in the core; mxl862xx will convert once it lands.

Testing: checkpatch --strict and kernel-doc clean. Patches 1-3 were
runtime-tested (backported to 7.0.11) on Intel AX101 hardware with
PROVE_LOCKING and DEBUG_OBJECTS_WORK, driving iwlwifi's crash
escalation into the re-probe path: normal detach+rebind, an unbind
racing a pending re-probe (the unbind is not undone), rmmod with a
re-probe pending (now succeeds instead of EBUSY), and reboot with a
re-probe pending; no lockdep or debugobjects reports. hci_h5 and
btintel_pcie are compile-tested only.

[1] https://lore.kernel.org/all/[email protected]/
[2] https://sashiko.dev/#/patchset/cover.1786294649.git.daniel%40makrotopia.org

Daniel Golle (4):
  driver core: add device_schedule_reprobe()
  wifi: iwlwifi: use device_schedule_reprobe()
  Bluetooth: hci_h5: use device_schedule_reprobe()
  Bluetooth: btintel_pcie: use device_schedule_reprobe() after reset

 drivers/base/base.h                           |  5 ++
 drivers/base/core.c                           |  3 +
 drivers/base/dd.c                             | 82 +++++++++++++++++++
 drivers/bluetooth/btintel_pcie.c              | 48 ++++++-----
 drivers/bluetooth/hci_h5.c                    | 41 ++--------
 .../net/wireless/intel/iwlwifi/iwl-trans.c    | 40 +--------
 include/linux/device.h                        |  2 +
 7 files changed, 122 insertions(+), 99 deletions(-)

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.