[PATCH v3 02/17] PCI/P2PDMA: Wait for RCU readers before freeing state
From: Leon Romanovsky
Date: Tue Aug 11 2026 - 05:40:21 EST
From: Leon Romanovsky <leonro@xxxxxxxxxx>
pci_p2pmem_find_many() scans all PCI devices without locking or
protection against driver unbind, including devices with poolless
P2PDMA state. pci_has_p2pmem() may observe pdev->p2pdma just before
driver unbind clears it, while pci_p2pdma_release() skips the grace
period when no pool is present. This allows devres to free the object
while it is still in use.
Clear the pointer with RCU_INIT_POINTER() and always wait for pre-existing
RCU readers before returning. The same grace period continues to protect
gen_pool users for pool-backed providers.
Cc: Alex Williamson <alex@xxxxxxxxxxx>
Cc: Matt Evans <matt@xxxxxxxxxx>
Fixes: 372d6d1b8ae3 ("PCI/P2PDMA: Refactor to separate core P2P functionality from memory allocation")
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx>
---
drivers/pci/p2pdma.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index dc7aaa990fed..e8e8c7d81d22 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -236,9 +236,8 @@ static void pci_p2pdma_release(void *data)
return;
/* Flush and disable pci_alloc_p2p_mem() */
- pdev->p2pdma = NULL;
- if (p2pdma->pool)
- synchronize_rcu();
+ RCU_INIT_POINTER(pdev->p2pdma, NULL);
+ synchronize_rcu();
xa_destroy(&p2pdma->map_types);
if (!p2pdma->pool)
--
2.55.0