* [PATCH 0/5] Batch of PCI peer-to-peer fixes
@ 2026-08-30 11:16 Leon Romanovsky
2026-08-30 11:16 ` [PATCH 1/5] PCI/P2PDMA: Do not tear down the allocate attribute on registration failure Leon Romanovsky
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Tushar Dave, Matt Evans
Hi Bjorn,
These fixes come from my larger series that aligns the code with the PCI
specification regarding the handling of ACS bits [1].
This series has already been reviewed by Logan and Jason.
Thanks,
[1] https://lore.kernel.org/all/20260821-fix-p2p-acs-v4-0-v4-0-94426b96de73@nvidia.com/
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
Leon Romanovsky (5):
PCI/P2PDMA: Do not tear down the allocate attribute on registration failure
PCI/P2PDMA: Wait for RCU readers before freeing state
PCI/P2PDMA: Restrict the p2pmem search to pool backed providers
PCI/P2PDMA: Safely terminate ACS redirect lists
PCI/P2PDMA: Gate the host bridge whitelist warning on verbose
drivers/pci/p2pdma.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
---
base-commit: 08dbfad3f5040f5bdb6c529da20d6d4e81fefd72
change-id: 20260830-batch-p2p-fixes-b73c10cdeff8
Best regards,
--
Leon Romanovsky <leonro@nvidia.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] PCI/P2PDMA: Do not tear down the allocate attribute on registration failure
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
@ 2026-08-30 11:16 ` Leon Romanovsky
2026-08-30 11:16 ` [PATCH 2/5] PCI/P2PDMA: Wait for RCU readers before freeing state Leon Romanovsky
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Tushar Dave, Jason Gunthorpe
From: Leon Romanovsky <leonro@nvidia.com>
pci_p2pdma_add_resource() installs pci_p2pdma_unmap_mappings() as a devres
action with the devres allocated p2p_pgmap as its data, and only then adds
the range to the pool:
error = devm_add_action_or_reset(&pdev->dev, pci_p2pdma_unmap_mappings,
p2p_pgmap);
if (error)
goto pages_free;
p2pdma = rcu_dereference_protected(pdev->p2pdma, 1);
error = gen_pool_add_owner(p2pdma->pool, ...);
if (error)
goto pages_free;
The action removes the allocate attribute for the whole device, which
tears down existing userspace mappings of every BAR already registered on
it. Both failures here get that wrong, in opposite ways.
devm_add_action_or_reset() runs the action when it cannot allocate its
devres node, so an -ENOMEM while registering a second BAR unmaps the
first one. Use devm_add_action() and let the error path unwind only what
this call created.
gen_pool_add_owner() allocates a chunk and can also fail with -ENOMEM.
There the action is registered, and the error path frees p2p_pgmap with
devm_kfree() while leaving the action pointing at it. On unbind devres
runs the action and pci_p2pdma_unmap_mappings() dereferences
p2p_pgmap->mem->owner->kobj, which is freed memory. Give that failure its
own label and drop the action with devm_remove_action(), which removes it
without running it.
Fixes: 7e9c7ef83d78 ("PCI/P2PDMA: Allow userspace VMA allocations through sysfs")
Fixes: f58ef9d1d135 ("PCI/P2PDMA: Separate the mmap() support from the core logic")
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Tushar Dave <tdave@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/pci/p2pdma.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 9334eb314663..8124bcebfa2d 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -440,8 +440,8 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
goto pgmap_free;
}
- error = devm_add_action_or_reset(&pdev->dev, pci_p2pdma_unmap_mappings,
- p2p_pgmap);
+ error = devm_add_action(&pdev->dev, pci_p2pdma_unmap_mappings,
+ p2p_pgmap);
if (error)
goto pages_free;
@@ -451,13 +451,15 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
range_len(&pgmap->range), dev_to_node(&pdev->dev),
&pgmap->ref);
if (error)
- goto pages_free;
+ goto mappings_remove;
pci_info(pdev, "added peer-to-peer DMA memory %#llx-%#llx\n",
pgmap->range.start, pgmap->range.end);
return 0;
+mappings_remove:
+ devm_remove_action(&pdev->dev, pci_p2pdma_unmap_mappings, p2p_pgmap);
pages_free:
devm_memunmap_pages(&pdev->dev, pgmap);
pgmap_free:
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/5] PCI/P2PDMA: Wait for RCU readers before freeing state
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
2026-08-30 11:16 ` [PATCH 1/5] PCI/P2PDMA: Do not tear down the allocate attribute on registration failure Leon Romanovsky
@ 2026-08-30 11:16 ` Leon Romanovsky
2026-08-30 11:16 ` [PATCH 3/5] PCI/P2PDMA: Restrict the p2pmem search to pool backed providers Leon Romanovsky
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Matt Evans, Tushar Dave, Jason Gunthorpe
From: Leon Romanovsky <leonro@nvidia.com>
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@shazbot.org>
Cc: Matt Evans <matt@ozlabs.org>
Fixes: 372d6d1b8ae3 ("PCI/P2PDMA: Refactor to separate core P2P functionality from memory allocation")
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Tushar Dave <tdave@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
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 8124bcebfa2d..52974809e1e1 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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] PCI/P2PDMA: Restrict the p2pmem search to pool backed providers
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
2026-08-30 11:16 ` [PATCH 1/5] PCI/P2PDMA: Do not tear down the allocate attribute on registration failure Leon Romanovsky
2026-08-30 11:16 ` [PATCH 2/5] PCI/P2PDMA: Wait for RCU readers before freeing state Leon Romanovsky
@ 2026-08-30 11:16 ` Leon Romanovsky
2026-08-30 11:16 ` [PATCH 4/5] PCI/P2PDMA: Safely terminate ACS redirect lists Leon Romanovsky
2026-08-30 11:16 ` [PATCH 5/5] PCI/P2PDMA: Gate the host bridge whitelist warning on verbose Leon Romanovsky
4 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Tushar Dave, Jason Gunthorpe
From: Leon Romanovsky <leonro@nvidia.com>
pci_p2pmem_find_many() exists to pick a provider that the caller will
then allocate from with pci_alloc_p2pmem(), which goes straight to the
gen_pool:
ret = (void *)gen_pool_alloc_owner(p2pdma->pool, size, (void **) &ref);
pci_has_p2pmem() does not ask for that pool, only for the published flag.
The two used to be equivalent, because a provider could only exist by way
of pci_p2pdma_add_resource(), which always creates the pool.
pcim_p2pdma_init() broke that. It registers a provider for the DMABUF
path and never creates a pool, so pdev->p2pdma is set while
p2pdma->pool stays NULL. Nothing publishes such a provider today, so the
search cannot return one yet, but the flag alone no longer says what the
caller needs.
Ask for the pool as well, so the search covers the providers its result
is used for. A later patch documents the pdev->p2pdma lifetime and RCU
rules.
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Tushar Dave <tdave@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/pci/p2pdma.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 52974809e1e1..914848a993ba 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -868,7 +868,12 @@ static bool pci_has_p2pmem(struct pci_dev *pdev)
rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma);
- res = p2pdma && p2pdma->p2pmem_published;
+ /*
+ * The callers hand the result to pci_alloc_p2pmem(), so only a
+ * provider backed by a pool is of any use here. pcim_p2pdma_init()
+ * creates providers without one.
+ */
+ res = p2pdma && p2pdma->pool && p2pdma->p2pmem_published;
rcu_read_unlock();
return res;
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] PCI/P2PDMA: Safely terminate ACS redirect lists
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
` (2 preceding siblings ...)
2026-08-30 11:16 ` [PATCH 3/5] PCI/P2PDMA: Restrict the p2pmem search to pool backed providers Leon Romanovsky
@ 2026-08-30 11:16 ` Leon Romanovsky
2026-08-30 11:16 ` [PATCH 5/5] PCI/P2PDMA: Gate the host bridge whitelist warning on verbose Leon Romanovsky
4 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Tushar Dave, Jason Gunthorpe
From: Leon Romanovsky <leonro@nvidia.com>
seq_buf marks an overflow by setting len to size + 1. The ACS diagnostic
path unconditionally writes a terminator to buffer[len - 1], so a path
with enough ACS ports to fill the 128-byte buffer writes one byte beyond
the buffer when verbose diagnostics are requested.
Use seq_buf_str() to terminate truncated output safely and remove the final
semicolon only when the buffer did not overflow.
Fixes: 52916982af48 ("PCI/P2PDMA: Support peer-to-peer memory")
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Tushar Dave <tdave@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/pci/p2pdma.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 914848a993ba..becc869cbc17 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -772,11 +772,13 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
}
if (verbose) {
- acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
+ /* Drop the final semicolon; the list is not empty here. */
+ if (!seq_buf_has_overflowed(&acs_list))
+ acs_list.buffer[acs_list.len - 1] = '\0';
pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
pci_name(provider));
pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
- acs_list.buffer);
+ seq_buf_str(&acs_list));
}
acs_redirects = true;
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] PCI/P2PDMA: Gate the host bridge whitelist warning on verbose
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
` (3 preceding siblings ...)
2026-08-30 11:16 ` [PATCH 4/5] PCI/P2PDMA: Safely terminate ACS redirect lists Leon Romanovsky
@ 2026-08-30 11:16 ` Leon Romanovsky
4 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2026-08-30 11:16 UTC (permalink / raw)
To: Bjorn Helgaas, Logan Gunthorpe, Greg Kroah-Hartman, Jens Axboe,
Chaitanya Kulkarni, Leon Romanovsky, Jason Gunthorpe,
Ankit Agrawal, Alex Williamson
Cc: linux-pci, linux-kernel, Tushar Dave, Jason Gunthorpe
From: Leon Romanovsky <leonro@nvidia.com>
calc_map_type_and_dist() prints every other diagnostic under its verbose
argument, but reaches the "Host bridge not in P2PDMA whitelist" warning
through host_bridge_whitelist(), which it hands acs_redirects instead.
A caller that asked for a silent answer still gets the warning whenever
any port on the path has an ACS redirect bit set, the CPU is not
whitelisted by cpu_supports_p2pdma(), and the host bridge is not in
pci_p2pdma_whitelist[].
pci_p2pmem_find_many() is such a caller. It sweeps every device with
published p2pmem and asks for the distance to each client with
verbose=false, and pci_p2pdma_distance_many() recomputes rather than
consulting the map_types cache, so the warning repeats on every sweep.
The argument was never meant to say "ACS redirects were found". When
commit cf201bfe8cdc ("PCI/P2PDMA: Warn if host bridge not in whitelist")
added it, acs_redirects was a bool pointer that the quiet entry point
passed as NULL:
if (verbose)
map = calc_map_type_and_dist_warn(provider, pci_client,
&distance);
else
map = calc_map_type_and_dist(provider, pci_client,
&distance, NULL, NULL);
so the argument was true on exactly the path that commit describes.
Folding the two entry points into one verbose flag turned the pointer
into a value and left the call site alone, silently narrowing the
warning to paths that carry an ACS redirect.
Pass verbose. This also restores the warning for a verbose caller that
takes the host bridge route with no ACS redirect on the path, which
until now was told it could not use peer-to-peer DMA without being told
which vendor and device would have to be added to the whitelist.
Fixes: d1b8dc09dd71 ("PCI/P2PDMA: Simplify distance calculation")
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Tested-by: Tushar Dave <tdave@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/pci/p2pdma.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index becc869cbc17..349537b4fa42 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -709,7 +709,6 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
{
enum pci_p2pdma_map_type map_type = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
struct pci_dev *a = provider, *b = client, *bb;
- bool acs_redirects = false;
struct pci_p2pdma *p2pdma;
struct seq_buf acs_list;
int acs_cnt = 0;
@@ -780,11 +779,10 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
seq_buf_str(&acs_list));
}
- acs_redirects = true;
map_through_host_bridge:
if (!cpu_supports_p2pdma() &&
- !host_bridge_whitelist(provider, client, acs_redirects)) {
+ !host_bridge_whitelist(provider, client, verbose)) {
if (verbose)
pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
pci_name(provider));
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-30 11:16 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-30 11:16 [PATCH 0/5] Batch of PCI peer-to-peer fixes Leon Romanovsky
2026-08-30 11:16 ` [PATCH 1/5] PCI/P2PDMA: Do not tear down the allocate attribute on registration failure Leon Romanovsky
2026-08-30 11:16 ` [PATCH 2/5] PCI/P2PDMA: Wait for RCU readers before freeing state Leon Romanovsky
2026-08-30 11:16 ` [PATCH 3/5] PCI/P2PDMA: Restrict the p2pmem search to pool backed providers Leon Romanovsky
2026-08-30 11:16 ` [PATCH 4/5] PCI/P2PDMA: Safely terminate ACS redirect lists Leon Romanovsky
2026-08-30 11:16 ` [PATCH 5/5] PCI/P2PDMA: Gate the host bridge whitelist warning on verbose Leon Romanovsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®