From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: intel-xe@lists.freedesktop.org
Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Matthew Auld" <matthew.auld@intel.com>,
"Dave Airlie" <airlied@redhat.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
stable@vger.kernel.org
Subject: [PATCH] drm/xe/dma-buf: Validate BOs on export to charge the exporter
Date: Wed, 11 Nov 2026 11:09:29 +0100 [thread overview]
Message-ID: <20261111100929.2228-1-thomas.hellstrom@linux.intel.com> (raw)
xe_gem_prime_export() calls ttm_bo_setup_export() to make sure the
exporter is charged for the memory backing an exported BO. However,
that only populates a TTM_PL_SYSTEM tt. A BO that has been evicted, or
that has deferred backing, will instead get its memory allocated when
the importer maps it. For p2p imports this happens through
xe_bo_validate() in xe_dma_buf_map(), so the importer, not the
exporter, is charged for the allocation.
Call xe_bo_validate() at export time instead, so that the BO is moved
into its preferred placement and the exporter is charged.
Do the purgeable checks and the validation in the same
xe_validation_guard() transaction, to avoid locking the BO twice.
The commit message and code was drafted using LLM.
Link: https://patchwork.freedesktop.org/patch/747480/?series=172524&rev=1
Fixes: 91494dee1091 ("xe: populate buffers before exporting them.")
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: intel-xe@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.18+
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
drivers/gpu/drm/xe/xe_dma_buf.c | 76 +++++++++++++++++----------------
1 file changed, 39 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index 5bf13dc4b61d..90c9b90de552 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -263,60 +263,62 @@ struct drm_gem_object *xe_dma_buf_to_gem(struct drm_device *dev,
struct dma_buf *xe_gem_prime_export(struct drm_gem_object *obj, int flags)
{
struct xe_bo *bo = gem_to_xe_bo(obj);
+ struct xe_validation_ctx ctx;
+ struct drm_exec exec;
struct dma_buf *buf;
- struct ttm_operation_ctx ctx = {
- .interruptible = true,
- .no_wait_gpu = true,
- /* We opt to avoid OOM on system pages allocations */
- .gfp_retry_mayfail = true,
- .allow_res_evict = false,
- };
- int ret;
+ int ret = 0;
if (bo->vm)
return ERR_PTR(-EPERM);
- /*
- * Reject exporting purgeable BOs. DONTNEED BOs can be purged
- * at any time, making the exported dma-buf unusable. Purged BOs
- * have no backing store and are permanently invalid.
- */
- ret = xe_bo_lock(bo, true);
- if (ret)
- return ERR_PTR(ret);
+ xe_validation_guard(&ctx, &xe_bo_device(bo)->val, &exec,
+ (struct xe_val_flags) {.interruptible = true}, ret) {
+ ret = drm_exec_lock_obj(&exec, &bo->ttm.base);
+ drm_exec_retry_on_contention(&exec);
+ if (ret)
+ break;
- if (xe_bo_madv_is_dontneed(bo)) {
- ret = -EBUSY;
- goto out_unlock;
- }
+ /*
+ * Reject exporting purgeable BOs. DONTNEED BOs can be purged
+ * at any time, making the exported dma-buf unusable. Purged BOs
+ * have no backing store and are permanently invalid.
+ */
+ if (xe_bo_madv_is_dontneed(bo)) {
+ ret = -EBUSY;
+ break;
+ }
- if (xe_bo_is_purged(bo)) {
- ret = -EINVAL;
- goto out_unlock;
- }
+ if (xe_bo_is_purged(bo)) {
+ ret = -EINVAL;
+ break;
+ }
- xe_bo_willneed_get_locked(bo);
- xe_bo_unlock(bo);
+ /*
+ * Make sure the BO is backed in its preferred placement so that
+ * the exporter, rather than the importer, is charged for the
+ * memory allocation.
+ */
+ ret = xe_bo_validate(bo, NULL, false, &exec);
+ drm_exec_retry_on_contention(&exec);
+ xe_validation_retry_on_oom(&ctx, &ret);
+ if (ret)
+ break;
- ret = ttm_bo_setup_export(&bo->ttm, &ctx);
+ xe_bo_willneed_get_locked(bo);
+ }
if (ret)
- goto out_put;
+ return ERR_PTR(ret);
buf = drm_gem_prime_export(obj, flags);
if (IS_ERR(buf)) {
- ret = PTR_ERR(buf);
- goto out_put;
+ xe_bo_lock(bo, false);
+ xe_bo_willneed_put_locked(bo);
+ xe_bo_unlock(bo);
+ return buf;
}
buf->ops = &xe_dmabuf_ops;
return buf;
-
-out_put:
- xe_bo_lock(bo, false);
- xe_bo_willneed_put_locked(bo);
-out_unlock:
- xe_bo_unlock(bo);
- return ERR_PTR(ret);
}
static struct drm_gem_object *
--
2.56.0
next reply other threads:[~2026-11-11 10:10 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 10:09 Thomas Hellström [this message]
2026-11-11 10:19 ` ✓ CI.KUnit: success for drm/xe/dma-buf: Validate BOs on export to charge the exporter Patchwork
2026-11-11 10:34 ` ✗ CI.checksparse: warning " Patchwork
2026-11-11 10:53 ` ✓ Xe.CI.BAT: success " Patchwork
2026-11-11 12:18 ` [PATCH] " Matthew Auld
2026-11-11 12:22 ` Thomas Hellström
2026-11-11 17:03 ` ✗ Xe.CI.FULL: failure for " Patchwork
2026-11-11 17:19 ` Thomas Hellström
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=20261111100929.2228-1-thomas.hellstrom@linux.intel.com \
--to=thomas.hellstrom@linux.intel.com \
--cc=airlied@redhat.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
--cc=matthew.brost@intel.com \
--cc=rodrigo.vivi@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox