Re: [PATCH v8 1/1] PCI/IOV: Make pci_lock_rescan_remove() reentrant and protect sriov_add_vfs/sriov_del_vfs

From: Niklas Schnelle

Date: Mon Mar 09 2026 - 16:24:29 EST


On Mon, 2026-03-09 at 21:49 +0200, Ionut Nechita (Wind River) wrote:
> After reverting commit 05703271c3cd ("PCI/IOV: Add PCI rescan-remove
> locking when enabling/disabling SR-IOV") and moving the lock to
> sriov_numvfs_store(), the path through driver .remove() (e.g. rmmod,
> or manual unbind) that calls pci_disable_sriov() directly remains
> unprotected against concurrent hotplug events. This affects any SR-IOV
> capable driver that calls pci_disable_sriov() from its .remove()
> callback (i40e, ice, mlx5, bnxt, etc.).
>
> On s390, platform-generated hot-unplug events for VFs can race with
> sriov_del_vfs() when a PF driver is being unloaded. The platform event
> handler takes pci_rescan_remove_lock, but sriov_del_vfs() does not,
> leading to double removal and list corruption.
>
> We cannot use a plain mutex_lock() here because sriov_del_vfs() may also
> be called from paths that already hold pci_rescan_remove_lock (e.g.
> remove_store -> pci_stop_and_remove_bus_device_locked, or
> sriov_numvfs_store with the lock taken by the previous patch). Using
> mutex_lock() in those cases would deadlock.
>
> Make pci_lock_rescan_remove() itself reentrant using mutex_get_owner()
> and a reentrant depth counter, as suggested by Lukas Wunner and
> Benjamin Block, since these recursive locking scenarios exist elsewhere
> in the PCI subsystem:
> - If the lock is already held by the current task (checked via
> mutex_get_owner()): increments the reentrant counter and returns
> without re-acquiring, avoiding deadlock.
> - If the lock is held by another task: blocks until the lock is
> released, providing complete serialization.
> - If the lock is not held: acquires the mutex normally.
>
> pci_unlock_rescan_remove() decrements the reentrant counter if it is
> non-zero, otherwise releases the mutex.
>
> This approach keeps the API unchanged: callers simply pair lock/unlock
> calls without needing to track any return value or use separate
> reentrant variants.
>
> Add pci_lock_rescan_remove()/pci_unlock_rescan_remove() calls to
> sriov_add_vfs() and sriov_del_vfs() to protect VF addition and
> removal against concurrent hotplug events.
>
> Fixes: 18f9e9d150fc ("PCI/IOV: Factor out sriov_add_vfs()")
> Cc: stable@xxxxxxxxxxxxxxx
> Suggested-by: Lukas Wunner <lukas@xxxxxxxxx>
> Suggested-by: Benjamin Block <bblock@xxxxxxxxxxxxx>
> Reviewed-by: Benjamin Block <bblock@xxxxxxxxxxxxx>
> Tested-by: Benjamin Block <bblock@xxxxxxxxxxxxx>
> Signed-off-by: Ionut Nechita <ionut_n2001@xxxxxxxxx>
> Signed-off-by: Ionut Nechita <ionut.nechita@xxxxxxxxxxxxx>
> ---

Sorry, bad timing on my part, I had just sent my reply[0] for v7 before
I looked again at my Inbox. Seeing as the code hasn't changed it still
applies. Also I forgot to add that I also tested this on s390. My
testing was in combination with Benjamin's series[1] because otherwise
there are still interfering issues.

Tested-by: Niklas Schnelle <schnelle@xxxxxxxxxxxxx> # s390

Thanks,
Niklas

[0]
https://lore.kernel.org/linux-pci/eea6652a968a9ad772eaa8e161e165e4414b1800.camel@xxxxxxxxxxxxx/
[1]
https://lore.kernel.org/linux-pci/cover.1772815642.git.bblock@xxxxxxxxxxxxx/