FAILED: patch "[PATCH] drm/amdgpu: hold a runtime PM reference for P2P dma-buf" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 636139603b99d2e3a18a46cf3f8d39313ce8042e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092255-footer-unscathed-ed09@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 636139603b99d2e3a18a46cf3f8d39313ce8042e Mon Sep 17 00:00:00 2001
From: Mike Lothian <[email protected]>
Date: Sat, 12 Sep 2026 00:29:08 +0100
Subject: [PATCH] drm/amdgpu: hold a runtime PM reference for P2P dma-buf
attachments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
amdgpu_dma_buf_map() adds VRAM to the allowed domains for a peer2peer attachment. GTT is only a fallback placement when VRAM is preferred, so ttm_bo_validate() migrates the buffer from GTT into VRAM. While the exporting device is runtime suspended its SDMA rings are down and the move fails:
amdgpu: Move buffer fallback to memcpy unavailable
An importer on a second GPU reaches this holding no runtime PM reference on the exporter, e.g. a compositor on the APU submitting a frame that references a buffer exported by an idle dGPU:
amdgpu_cs_ioctl -> amdgpu_cs_parser_bos -> amdgpu_cs_bo_validate
-> ttm_bo_validate -> amdgpu_bo_move -> dma_buf_map_attachment
-> amdgpu_dma_buf_map -> ttm_bo_validate -> amdgpu_bo_movePinning a dma-buf into VRAM has the same requirement, which commit 030631e97b20 ("drm/amdgpu: revert "take runtime pm reference when we attach a buffer" v2") called out as the one case that would need the reference back.
Take it in attach and drop it in detach. pm_runtime_get_if_active() never resumes the device, so it cannot deadlock against the reservation taken during resume, which is why the old pm_runtime_get_sync() had to go. If the device is not active, clear peer2peer instead: the buffer then stays in GTT, which remains accessible while the GPU is powered down. If runtime PM is disabled, take a plain reference so the put in detach stays balanced.
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +42 -1
@@ -43,6 +43,7 @@#include <linux/dma-buf.h> #include <linux/dma-fence-array.h> #include <linux/pci-p2pdma.h> +#include <linux/pm_runtime.h> static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
@@ -100,15 +101,54 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) attach->peer2peer = false; +/* +* Only allow P2P while the exporter is active, and keep it active +* until detach. With runtime PM disabled take a plain reference so +* the put in detach stays balanced. +*/ +if (attach->peer2peer) { +struct device *dev =adev_to_drm (adev)->dev; +int ret =pm_runtime_get_if_active (dev); + +if (!ret) + attach->peer2peer = false; +else if (ret <0 ) +pm_runtime_get_noresume (dev); + } + r =dma_resv_lock (bo->tbo.base.resv,NULL );if (r) -return r; + goto err_pm_put;amdgpu_vm_bo_update_shared (bo);dma_resv_unlock (bo->tbo.base.resv);return 0 ; + +err_pm_put: +if (attach->peer2peer) +pm_runtime_put_autosuspend (adev_to_drm (adev)->dev); +return r; +} + +/** +* amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation +* +* @dmabuf: DMA-buf where we remove the attachment from +* @attach: the attachment to remove +* +* Drop the runtime PM reference taken in amdgpu_dma_buf_attach(). +*/ +static void amdgpu_dma_buf_detach (struct dma_buf *dmabuf, +struct dma_buf_attachment *attach) +{ +struct drm_gem_object *obj = dmabuf->priv; +struct amdgpu_bo *bo =gem_to_amdgpu_bo (obj); +struct amdgpu_device *adev =amdgpu_ttm_adev (bo->tbo.bdev); + +if (attach->peer2peer) +pm_runtime_put_autosuspend (adev_to_drm (adev)->dev); }/**
@@ -350,6 +390,7 @@ static void amdgpu_dma_buf_vunmap(struct dma_buf *dma_buf, struct iosys_map *mapconst struct dma_buf_ops amdgpu_dmabuf_ops = { .attach = amdgpu_dma_buf_attach, + .detach = amdgpu_dma_buf_detach, .pin = amdgpu_dma_buf_pin, .unpin = amdgpu_dma_buf_unpin, .map_dma_buf = amdgpu_dma_buf_map,
Sasha Levin
maintainerPATCH 1/2 drm: add drm_memory_stats_is_zero
From: Yunxiang Li <[email protected]>
[ Upstream commit fd265d9e0c3358e6b9fe244d8f5d2824fda1c0dc ]
Add a helper to check if the memory stats is zero, this will be used to check for memory accounting errors.
Stable-dep-of: 636139603b99 ("drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments")
--- drivers/gpu/drm/drm_file.c | 10 ++++++++++ include/drm/drm_file.h | 1 + 2 files changed, 11 insertions(+)
drivers/gpu/drm/drm_file.c +10 -0
@@ -840,6 +840,16 @@ static void print_size(struct drm_printer *p, const char *stat,drm_printf (p,"drm-%s-%s:\t%llu%s\n" , stat, region, sz, units[u]); } +int drm_memory_stats_is_zero (const struct drm_memory_stats *stats) +{ +return (stats->shared ==0 && + stats->private ==0 && + stats->resident ==0 && + stats->purgeable ==0 && + stats->active ==0 ); +} +EXPORT_SYMBOL (drm_memory_stats_is_zero); +/** * drm_print_memory_stats - A helper to print memory stats * @p: The printer to print output to
include/drm/drm_file.h +1 -0
@@ -485,6 +485,7 @@ struct drm_memory_stats {enum drm_gem_object_status ; +int drm_memory_stats_is_zero (const struct drm_memory_stats *stats); void drm_print_memory_stats(struct drm_printer *p, const struct drm_memory_stats *stats, enum drm_gem_object_status supported_status,
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments
From: Mike Lothian <[email protected]>
[ Upstream commit 636139603b99d2e3a18a46cf3f8d39313ce8042e ]
amdgpu_dma_buf_map() adds VRAM to the allowed domains for a peer2peer attachment. GTT is only a fallback placement when VRAM is preferred, so ttm_bo_validate() migrates the buffer from GTT into VRAM. While the exporting device is runtime suspended its SDMA rings are down and the move fails:
amdgpu: Move buffer fallback to memcpy unavailable
An importer on a second GPU reaches this holding no runtime PM reference on the exporter, e.g. a compositor on the APU submitting a frame that references a buffer exported by an idle dGPU:
amdgpu_cs_ioctl -> amdgpu_cs_parser_bos -> amdgpu_cs_bo_validate
-> ttm_bo_validate -> amdgpu_bo_move -> dma_buf_map_attachment
-> amdgpu_dma_buf_map -> ttm_bo_validate -> amdgpu_bo_movePinning a dma-buf into VRAM has the same requirement, which commit 030631e97b20 ("drm/amdgpu: revert "take runtime pm reference when we attach a buffer" v2") called out as the one case that would need the reference back.
Take it in attach and drop it in detach. pm_runtime_get_if_active() never resumes the device, so it cannot deadlock against the reservation taken during resume, which is why the old pm_runtime_get_sync() had to go. If the device is not active, clear peer2peer instead: the buffer then stays in GTT, which remains accessible while the GPU is powered down. If runtime PM is disabled, take a plain reference so the put in detach stays balanced.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +36 -0
@@ -41,6 +41,7 @@#include <linux/dma-buf.h> #include <linux/dma-fence-array.h> #include <linux/pci-p2pdma.h> +#include <linux/pm_runtime.h> static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
@@ -97,9 +98,43 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) attach->peer2peer = false; +/* +* Only allow P2P while the exporter is active, and keep it active +* until detach. With runtime PM disabled take a plain reference so +* the put in detach stays balanced. +*/ +if (attach->peer2peer) { +struct device *dev =adev_to_drm (adev)->dev; +int ret =pm_runtime_get_if_active (dev); + +if (!ret) + attach->peer2peer = false; +else if (ret <0 ) +pm_runtime_get_noresume (dev); + } +return 0 ; } +/** +* amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation +* +* @dmabuf: DMA-buf where we remove the attachment from +* @attach: the attachment to remove +* +* Drop the runtime PM reference taken in amdgpu_dma_buf_attach(). +*/ +static void amdgpu_dma_buf_detach (struct dma_buf *dmabuf, +struct dma_buf_attachment *attach) +{ +struct drm_gem_object *obj = dmabuf->priv; +struct amdgpu_bo *bo =gem_to_amdgpu_bo (obj); +struct amdgpu_device *adev =amdgpu_ttm_adev (bo->tbo.bdev); + +if (attach->peer2peer) +pm_runtime_put_autosuspend (adev_to_drm (adev)->dev); +} +/** * amdgpu_dma_buf_pin - &dma_buf_ops.pin implementation *
@@ -270,6 +305,7 @@ static int amdgpu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf,const struct dma_buf_ops amdgpu_dmabuf_ops = { .attach = amdgpu_dma_buf_attach, + .detach = amdgpu_dma_buf_detach, .pin = amdgpu_dma_buf_pin, .unpin = amdgpu_dma_buf_unpin, .map_dma_buf = amdgpu_dma_buf_map,
Signature · 1 line
2.53.0