From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: "Christian König" <christian.koenig@amd.com>,
"Matthew Auld" <matthew.auld@intel.com>,
intel-xe@lists.freedesktop.org
Cc: "Matthew Brost" <matthew.brost@intel.com>,
stable@vger.kernel.org,
"Christian König" <ckoenig.leichtzumerken@gmail.com>
Subject: Re: [PATCH v2 3/3] drm/xe: skip p2p for suspected display buffers
Date: Fri, 09 Oct 2026 15:06:48 +0200 [thread overview]
Message-ID: <a048aaa445d06d2452853c2677fc2b2d21888325.camel@linux.intel.com> (raw)
In-Reply-To: <1a852df2-c2a4-48bb-84de-cdd4b98b95bb@amd.com>
On Fri, 2026-10-09 at 13:38 +0200, Christian König wrote:
> On 10/9/26 12:29, Matthew Auld wrote:
> > On 09/10/2026 10:26, Christian König wrote:
> > > On 10/9/26 11:16, Matthew Auld wrote:
> > > > On 08/10/2026 12:17, Matthew Auld wrote:
> > > > > On 08/10/2026 10:55, Christian König wrote:
> > > > > > On 10/8/26 11:46, Matthew Auld wrote:
> > > > > > > On 07/10/2026 19:11, Thomas Hellström wrote:
> > > > > > > > On Wed, 2026-10-07 at 16:36 +0100, Matthew Auld wrote:
> > > > > > > > > If p2p is allowed on the CPU (like on AMD), we
> > > > > > > > > currently permit p2p
> > > > > > > > > for
> > > > > > > > > all exported VRAM buffers. However, in some multi-GPU
> > > > > > > > > setups, like
> > > > > > > > > with
> > > > > > > > > prime rendering on a dgpu and scanout/compositor
> > > > > > > > > using the igpu, it
> > > > > > > > > looks like the exported dma-buf window buffer can in
> > > > > > > > > some cases end
> > > > > > > > > up
> > > > > > > > > using p2p.
> > > > > > > > >
> > > > > > > > > However, user is reporting a kernel regression where
> > > > > > > > > performance here
> > > > > > > > > massively tanks across many games/workloads, where it
> > > > > > > > > looks like on
> > > > > > > > > each
> > > > > > > > > frame, the igpu is reading/sampling from VRAM over
> > > > > > > > > pcie for the
> > > > > > > > > window
> > > > > > > > > buffer, since it uses p2p. p2p is currently more
> > > > > > > > > intended for dgpu <-
> > > > > > > > > >
> > > > > > > > > dgpu, and not so much display buffers with igpu <->
> > > > > > > > > dgpu, at least
> > > > > > > > > for
> > > > > > > > > now.
> > > > > > > > >
> > > > > > > > > We don't currently have any hints to say "please use
> > > > > > > > > p2p for this
> > > > > > > > > buffer, or please don't", however we can use some
> > > > > > > > > heuristics to try
> > > > > > > > > to
> > > > > > > > > determine if this is likely a display buffer being
> > > > > > > > > exported to an
> > > > > > > > > igpu,
> > > > > > > > > which probably never intended for p2p:
> > > > > > > > >
> > > > > > > > > 1. FLAG_SCANOUT being set on the buffer. Window
> > > > > > > > > buffers usually get
> > > > > > > > > tagged with this, but not always.
> > > > > > > > >
> > > > > > > > > 2. Importer being a PCI device with display,
> > > > > > > > > which is not xe driver.
> > > > > > > > >
> > > > > > > > > We also rely on the existing p2p Intel CPU whitelist
> > > > > > > > > to stop this
> > > > > > > > > happening on xe igpu. Currently p2p is only enabled
> > > > > > > > > for server CPUs,
> > > > > > > > > on
> > > > > > > > > Intel. We also limit the above to dual placement
> > > > > > > > > buffers.
> > > > > > > > >
> > > > > > > > > The original regression was bisected to commit
> > > > > > > > > 609fc8766d68 ("dma-
> > > > > > > > > buf:
> > > > > > > > > Always build with DMABUF_MOVE_NOTIFY"), however the
> > > > > > > > > behaviour was
> > > > > > > > > already present when enabling that knob, so this goes
> > > > > > > > > back even
> > > > > > > > > further.
> > > > > > > > >
> > > > > > > > > User has confirmed that along with the sticky dma-buf
> > > > > > > > > TT placement
> > > > > > > > > fix,
> > > > > > > > > to prevent ping-ponging, the performance is back to
> > > > > > > > > normal.
> > > > > > > > >
> > > > > > > >
> > > > > > > > Actually, I think this needs to be fixed on the
> > > > > > > > importer side. Until we
> > > > > > > > have some some user-space hints, I don't think the
> > > > > > > > exporter should
> > > > > > > > second-guess. Most sane solution IMO is if igfx
> > > > > > > > importers could just
> > > > > > > > not advertise pcie p2p support?
> > > > > > >
> > > > > > > Yeah, not sure tbh. I'm not a huge fan of this patch
> > > > > > > either. But you could argue that the SCANOUT flag is
> > > > > > > already a good implicit hint/ signal on the exporter
> > > > > > > side, but unfortunately there were some games where this
> > > > > > > did not reliably work. The other implicit hint/signal is
> > > > > > > perhaps the dual placement angle. For example, in
> > > > > > > compute-runtime, it might be that they use VRAM-only if
> > > > > > > they want p2p? AFAICT mesa for us always uses a dual
> > > > > > > placement or just system memory for these types of
> > > > > > > buffers.
> > > > > > >
> > > > > > > Christian, do you have any thoughts here? We have a
> > > > > > > kernel perf regression after DMABUF_MOVE_NOTIFY was made
> > > > > > > the default after updating to a new kernel. The gist is
> > > > > > > that this then turned on the p2p paths, with a multi-GPU
> > > > > > > setup with an AMD igpu/APU and Xe dgpu doing prime
> > > > > > > rendering. From the user bug report it sounds like the
> > > > > > > dgpu linear window buffer exported to the compositor
> > > > > > > (igpu) is dual placement VRAM + TT, and so this now
> > > > > > > attempts to keep that memory in VRAM instead of moving
> > > > > > > it. Compositor then uses p2p to access it. It works but
> > > > > > > performance falls off a massive cliff here.
> > > > > > >
> > > > > > > Perhaps Intel Mesa side should use tt-only for this type
> > > > > > > buffer (?), but since this is a kernel regression I was
> > > > > > > hoping we could fix this on the kernel side.
> > > > > > >
> > > > > > > Some questions:
> > > > > > >
> > > > > > > 1. Do you know what is the general story with p2p between
> > > > > > > igpu and dgpu? Is this a legit thing? For igpus/APUs,
> > > > > > > advertising p2p can't be dropped? It clearly seems to
> > > > > > > work though.
> > > > > > >
> > > > > > > 2. If this is legit, do you guys then also prevent p2p
> > > > > > > with display buffers? Are you just doing that at the Mesa
> > > > > > > level, or is there some magic in the kernel also?
> > > > > >
> > > > > > If I understand that correctly that the igpu is the
> > > > > > importer and the dgpu is the exporter then yeah Thomas is
> > > > > > right that definately needs to be fixed on the importer
> > > > > > side.
> > > > >
> > > > > Ideas on how do that? Could we do something like
> > > > > allow_peer2peer = false in amdgpu_gem_prime_import() if this
> > > > > is an APU device, or further check if the exporter side is
> > > > > not amdgpu, like APU + Xe?
> > > >
> > > > For example:
> > > > https://gitlab.freedesktop.org/mwa/kernel/-/commit/7ec86c68b42655b4bb85ee90af434a617e7bec8c
> > > >
> > > > Is that something you would accept?
> > >
> > > No, you misunderstood me. Enabling P2P is perfectly fine for APUs
> > > and mandatory for a couple of customer projects.
> > >
> > > The buffer should just be rejected from scanout in the display
> > > code and on the AMDGPU side we already do that if I'm not
> > > completely mistaken.
> >
> > Reporter confirmed seeing the issue in windowed mode also. So I
> > don't think it's just a case of rejecting from scanout?
>
> Then I don't understand what the problem is.
>
> When the dGPU renders and the iGPU displays you have only two
> possibilities, either the dGPU pushes the frames over the bus or the
> iGPU pulls the frames over the bus. Both should be equaly slow or
> fast, so what exactly is the expectation here?
I think PCIe reads, even p2p can be agonizingly slow. From my
understanding writes are posted whereas reads are not. The reading
/Thomas
>
> The only thing you need to avoid is that the iGPU starts to scan out
> over the PCIe bus directly, cause then the frame is pulled over the
> bus multiple times (if that actually works correctly).
>
> Do you have a link to the original bug report? I was only added later
> to the discussion so I don't have that.
>
> Regards,
> Christian.
>
> >
> > >
> > > Userspace has fallback path that when a DRM atomic requests fails
> > > for an imported buffer it falls back to copying the buffer first.
> > >
> > > Regards,
> > > Christian.
> > > > >
> > > > > >
> > > > > > At least for AMD APUs we clearly support P2P both as
> > > > > > exporter and importer, but what isn't supported is to scan
> > > > > > out over P2P. We explicitely reject that inside DC/DAL.
> > > > > >
> > > > > > And I'm pretty sure that you should do that as well. I'm
> > > > > > actually really suprised that this works technically and
> > > > > > doesn't cause corruption or anything.
> > > > >
> > > > > AFAICT on Intel iGPUs it will currently always end up with
> > > > > peer2peer = false on attach. Not 100% sure if direct scanout
> > > > > was happening on the p2p buffer itself, for the user report.
> > > > >
> > > > > >
> > > > > > Regards,
> > > > > > Christian.
> > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > > Thomas
> > > > > > > >
> > > > > > > > > Assisted-by: LLM
> > > > > > > > > Closes:
> > > > > > > > > https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/9415
> > > > > > > > > Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> > > > > > > > > Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM
> > > > > > > > > driver for Intel
> > > > > > > > > GPUs")
> > > > > > > > > Cc: Thomas Hellström
> > > > > > > > > <thomas.hellstrom@linux.intel.com>
> > > > > > > > > Cc: Matthew Brost <matthew.brost@intel.com>
> > > > > > > > > Cc: <stable@vger.kernel.org> # v6.12
> > > > > > > > > ---
> > > > > > > > > drivers/gpu/drm/xe/xe_bo.c | 3 +-
> > > > > > > > > drivers/gpu/drm/xe/xe_bo.h | 1 +
> > > > > > > > > drivers/gpu/drm/xe/xe_dma_buf.c | 63
> > > > > > > > > ++++++++++++++++++++++++ +------
> > > > > > > > > --
> > > > > > > > > 3 files changed, 51 insertions(+), 16 deletions(-
> > > > > > > > > )
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/gpu/drm/xe/xe_bo.c
> > > > > > > > > b/drivers/gpu/drm/xe/xe_bo.c
> > > > > > > > > index 5065a7bac39c..e63437a261cb 100644
> > > > > > > > > --- a/drivers/gpu/drm/xe/xe_bo.c
> > > > > > > > > +++ b/drivers/gpu/drm/xe/xe_bo.c
> > > > > > > > > @@ -3658,7 +3658,7 @@ int xe_gem_create_ioctl(struct
> > > > > > > > > drm_device *dev,
> > > > > > > > > void *data,
> > > > > > > > > * Display scanout is always non-coherent
> > > > > > > > > with the CPU
> > > > > > > > > cache.
> > > > > > > > > */
> > > > > > > > > if (args->flags &
> > > > > > > > > DRM_XE_GEM_CREATE_FLAG_SCANOUT)
> > > > > > > > > - bo_flags |= XE_BO_FLAG_FORCE_WC;
> > > > > > > > > + bo_flags |= XE_BO_FLAG_FORCE_WC |
> > > > > > > > > XE_BO_FLAG_SCANOUT;
> > > > > > > > > if (args->flags &
> > > > > > > > > DRM_XE_GEM_CREATE_FLAG_NO_COMPRESSION) {
> > > > > > > > > if (XE_IOCTL_DBG(xe, GRAPHICS_VER(xe) <
> > > > > > > > > 20))
> > > > > > > > > @@ -4228,6 +4228,7 @@ int xe_bo_dumb_create(struct
> > > > > > > > > drm_file
> > > > > > > > > *file_priv,
> > > > > > > > > DRM_XE_GEM_CPU_CACHING_WC,
> > > > > > > > > XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe))
> > > > > > > > > |
> > > > > > > > > XE_BO_FLAG_FORCE_WC |
> > > > > > > > > + XE_BO_FLAG_SCANOUT |
> > > > > > > > > XE_BO_FLAG_NEEDS_CPU_ACCESS,
> > > > > > > > > NULL);
> > > > > > > > > if (IS_ERR(bo))
> > > > > > > > > return PTR_ERR(bo);
> > > > > > > > > diff --git a/drivers/gpu/drm/xe/xe_bo.h
> > > > > > > > > b/drivers/gpu/drm/xe/xe_bo.h
> > > > > > > > > index 1ddf3b6d4a9e..6965c2655731 100644
> > > > > > > > > --- a/drivers/gpu/drm/xe/xe_bo.h
> > > > > > > > > +++ b/drivers/gpu/drm/xe/xe_bo.h
> > > > > > > > > @@ -56,6 +56,7 @@
> > > > > > > > > #define XE_BO_FLAG_FORCE_USER_VRAM BIT(25)
> > > > > > > > > #define XE_BO_FLAG_NO_COMPRESSION BIT(26)
> > > > > > > > > #define XE_BO_FLAG_NEEDS_1G BIT(27)
> > > > > > > > > +#define XE_BO_FLAG_SCANOUT BIT(28)
> > > > > > > > > /* this one is trigger internally only */
> > > > > > > > > #define XE_BO_FLAG_INTERNAL_TEST BIT(30)
> > > > > > > > > diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c
> > > > > > > > > b/drivers/gpu/drm/xe/xe_dma_buf.c
> > > > > > > > > index b973579a69b8..0a347f09cee4 100644
> > > > > > > > > --- a/drivers/gpu/drm/xe/xe_dma_buf.c
> > > > > > > > > +++ b/drivers/gpu/drm/xe/xe_dma_buf.c
> > > > > > > > > @@ -36,10 +36,40 @@ static void
> > > > > > > > > xe_ddebug_flip_bool(const struct
> > > > > > > > > _ddebug *desc, bool *flag)
> > > > > > > > > #define xe_dma_buf_p2p_debug_flip(flag) do { }
> > > > > > > > > while (0)
> > > > > > > > > #endif
> > > > > > > > > +static void xe_dma_buf_move_notify(struct
> > > > > > > > > dma_buf_attachment
> > > > > > > > > *attach)
> > > > > > > > > +{
> > > > > > > > > + struct drm_gem_object *obj = attach-
> > > > > > > > > >importer_priv;
> > > > > > > > > + struct xe_bo *bo = gem_to_xe_bo(obj);
> > > > > > > > > + struct drm_exec *exec =
> > > > > > > > > XE_VALIDATION_UNSUPPORTED;
> > > > > > > > > +
> > > > > > > > > + XE_WARN_ON(xe_bo_evict(bo, exec));
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static const struct dma_buf_attach_ops
> > > > > > > > > xe_dma_buf_attach_ops = {
> > > > > > > > > + .allow_peer2peer = true,
> > > > > > > > > + .invalidate_mappings = xe_dma_buf_move_notify
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +static struct pci_dev *xe_find_parent_pci_dev(struct
> > > > > > > > > device *dev)
> > > > > > > > > +{
> > > > > > > > > + while (dev) {
> > > > > > > > > + if (dev_is_pci(dev))
> > > > > > > > > + return to_pci_dev(dev);
> > > > > > > > > + dev = dev->parent;
> > > > > > > > > + }
> > > > > > > > > + return NULL;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > +static bool xe_dma_buf_attach_is_xe_device(struct
> > > > > > > > > dma_buf_attachment
> > > > > > > > > *attach)
> > > > > > > > > +{
> > > > > > > > > + return attach->importer_ops ==
> > > > > > > > > &xe_dma_buf_attach_ops;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > static int xe_dma_buf_attach(struct dma_buf
> > > > > > > > > *dmabuf,
> > > > > > > > > struct dma_buf_attachment
> > > > > > > > > *attach)
> > > > > > > > > {
> > > > > > > > > struct drm_gem_object *obj = attach->dmabuf-
> > > > > > > > > >priv;
> > > > > > > > > + struct xe_bo *bo = gem_to_xe_bo(obj);
> > > > > > > > > bool verbose_p2p_dist =
> > > > > > > > > drm_debug_enabled(DRM_UT_DRIVER);
> > > > > > > > >
> > > > > > > > > xe_dma_buf_p2p_debug_flip(&verbose_p2p_dist);
> > > > > > > > > @@ -48,7 +78,24 @@ static int
> > > > > > > > > xe_dma_buf_attach(struct dma_buf
> > > > > > > > > *dmabuf,
> > > > > > > > > pci_p2pdma_distance(to_pci_dev(obj->dev-
> > > > > > > > > >dev), attach-
> > > > > > > > > > dev, verbose_p2p_dist) < 0)
> > > > > > > > > attach->peer2peer = false;
> > > > > > > > > - if (!attach->peer2peer &&
> > > > > > > > > !xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
> > > > > > > > > + if (attach->peer2peer && xe_bo_can_migrate(bo,
> > > > > > > > > XE_PL_TT)) {
> > > > > > > > > + struct pci_dev *client =
> > > > > > > > > xe_find_parent_pci_dev(attach->dev);
> > > > > > > > > +
> > > > > > > > > + /*
> > > > > > > > > + * There are perf issues with using p2p with
> > > > > > > > > display
> > > > > > > > > buffers,
> > > > > > > > > + * like with igpu (compositor) <-> dgpu
> > > > > > > > > (exported
> > > > > > > > > p2p window
> > > > > > > > > + * buffer). Probably we need some actual
> > > > > > > > > userspace
> > > > > > > > > hints. We
> > > > > > > > > + * shouldn't really assume anything. Also,
> > > > > > > > > note that
> > > > > > > > > some of
> > > > > > > > > + * these buffers are not always tagged with
> > > > > > > > > SCANOUT.
> > > > > > > > > + */
> > > > > > > > > + if (bo->flags & XE_BO_FLAG_SCANOUT)
> > > > > > > > > + attach->peer2peer = false;
> > > > > > > > > + else if (client && pci_is_display(client) &&
> > > > > > > > > +
> > > > > > > > > !xe_dma_buf_attach_is_xe_device(attach))
> > > > > > > > > + attach->peer2peer = false;
> > > > > > > > > + }
> > > > > > > > > +
> > > > > > > > > + if (!attach->peer2peer && !xe_bo_can_migrate(bo,
> > > > > > > > > XE_PL_TT))
> > > > > > > > > return -EOPNOTSUPP;
> > > > > > > > > xe_pm_runtime_get(to_xe_device(obj->dev));
> > > > > > > > > @@ -349,20 +396,6 @@ xe_dma_buf_create_obj(struct
> > > > > > > > > drm_device *dev,
> > > > > > > > > struct dma_buf *dma_buf)
> > > > > > > > > return ret ? ERR_PTR(ret) : &bo->ttm.base;
> > > > > > > > > }
> > > > > > > > > -static void xe_dma_buf_move_notify(struct
> > > > > > > > > dma_buf_attachment
> > > > > > > > > *attach)
> > > > > > > > > -{
> > > > > > > > > - struct drm_gem_object *obj = attach-
> > > > > > > > > >importer_priv;
> > > > > > > > > - struct xe_bo *bo = gem_to_xe_bo(obj);
> > > > > > > > > - struct drm_exec *exec =
> > > > > > > > > XE_VALIDATION_UNSUPPORTED;
> > > > > > > > > -
> > > > > > > > > - XE_WARN_ON(xe_bo_evict(bo, exec));
> > > > > > > > > -}
> > > > > > > > > -
> > > > > > > > > -static const struct dma_buf_attach_ops
> > > > > > > > > xe_dma_buf_attach_ops = {
> > > > > > > > > - .allow_peer2peer = true,
> > > > > > > > > - .invalidate_mappings = xe_dma_buf_move_notify
> > > > > > > > > -};
> > > > > > > > > -
> > > > > > > > > #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
> > > > > > > > > struct dma_buf_test_params {
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
next prev parent reply other threads:[~2026-10-09 13:06 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 15:36 [PATCH v2 0/3] sticky TT Matthew Auld
2026-10-07 15:36 ` [PATCH v2 1/3] drm/xe/dma-buf: keep non-p2p imported buffers in system memory Matthew Auld
2026-10-07 15:36 ` [PATCH v2 2/3] drm/xe/vm: make PREFETCH to TT sticky Matthew Auld
2026-10-07 15:36 ` [PATCH v2 3/3] drm/xe: skip p2p for suspected display buffers Matthew Auld
2026-10-07 18:11 ` Thomas Hellström
2026-10-08 9:46 ` Matthew Auld
2026-10-08 9:55 ` Christian König
2026-10-08 11:17 ` Matthew Auld
2026-10-09 9:16 ` Matthew Auld
2026-10-09 9:26 ` Christian König
2026-10-09 10:29 ` Matthew Auld
2026-10-09 11:38 ` Christian König
2026-10-09 13:02 ` Matthew Auld
2026-10-13 8:51 ` Matthew Auld
2026-10-13 9:10 ` Christian König
2026-10-13 9:18 ` Thomas Hellström
2026-10-13 9:55 ` Christian König
2026-10-13 10:16 ` Thomas Hellström
2026-10-13 11:45 ` Christian König
2026-10-13 12:36 ` Matthew Auld
2026-10-13 9:40 ` Matthew Auld
2026-10-13 11:50 ` Christian König
2026-10-13 13:15 ` Matthew Auld
2026-10-09 13:06 ` Thomas Hellström [this message]
2026-10-08 14:40 ` Simon Richter
2026-10-08 16:22 ` Matthew Auld
2026-10-07 15:42 ` ✗ CI.checkpatch: warning for sticky TT (rev2) Patchwork
2026-10-07 15:45 ` ✓ CI.KUnit: success " Patchwork
2026-10-07 16:46 ` ✓ Xe.CI.BAT: " Patchwork
2026-10-07 20:16 ` ✓ Xe.CI.FULL: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a048aaa445d06d2452853c2677fc2b2d21888325.camel@linux.intel.com \
--to=thomas.hellstrom@linux.intel.com \
--cc=christian.koenig@amd.com \
--cc=ckoenig.leichtzumerken@gmail.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
--cc=matthew.brost@intel.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.