Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Cc: "Carlos Santa" <carlos.santa@intel.com>,
	"Ryan Neph" <ryanneph@google.com>,
	"Christian Koenig" <christian.koenig@amd.com>,
	"Huang Rui" <ray.huang@amd.com>,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	linux-kernel@vger.kernel.org,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Subject: [PATCH v2 28/33] drm/xe: Use IOVA-based DMA mapping for eligible tt BOs
Date: Fri, 10 Jul 2026 14:54:37 -0700	[thread overview]
Message-ID: <20260710215442.2444235-29-matthew.brost@intel.com> (raw)
In-Reply-To: <20260710215442.2444235-1-matthew.brost@intel.com>

Add support for mapping a ttm_tt's pages using the IOVA-based DMA API
(dma_iova_try_alloc()/link()/sync()/unlink()/free()) as an alternative
to the scatter-gather list. An IOVA mapping is a single contiguous DMA
range, which is cheaper to walk and program than an sg list.

Whether the IOVA API can be used depends on the IOMMU mode, so the
decision is made once per tt at xe_ttm_tt_create() time and recorded in
struct xe_ttm_tt::use_iova. To keep the scope limited, only device BOs
that are not GGTT-mapped are eligible: dma-buf imports manage their own
mapping and GGTT bindings are programmed directly from the sg list.
dma_iova_try_alloc() may still fail, in which case the tt transparently
falls back to the sg list, which remains the default.

The IOVA reservation is allocated at tt creation and freed at tt
destroy. xe_tt_map_iova() links the tt pages (coalescing physically
contiguous runs) and syncs the IOTLB; xe_tt_unmap_iova() unlinks them
but keeps the reservation so the tt can be remapped without
re-allocating IOVA space. xe_tt_map()/xe_tt_unmap() dispatch between the
IOVA and sg backends, and xe_bo_dma_unmap_pinned() learns about the IOVA
case.

Consumers that walked the sg list via xe_res_first_sg(xe_bo_sg()) now go
through the new xe_res_first_tt() helper, which initializes either an
IOVA cursor (xe_res_first_iova()) or an sg cursor depending on the tt's
mapping mode.

Cc: Carlos Santa <carlos.santa@intel.com>
Cc: Ryan Neph <ryanneph@google.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Cc: Huang Rui <ray.huang@amd.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Assisted-by: GitHub_Copilot:claude-opus-4.8
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
 drivers/gpu/drm/xe/tests/xe_migrate.c |   6 +-
 drivers/gpu/drm/xe/xe_bo.c            | 239 ++++++++++++++++++++++++--
 drivers/gpu/drm/xe/xe_bo.h            |   5 +-
 drivers/gpu/drm/xe/xe_ggtt.c          |   2 +-
 drivers/gpu/drm/xe/xe_migrate.c       |  14 +-
 drivers/gpu/drm/xe/xe_pt.c            |   2 +-
 6 files changed, 237 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
index 41de648b2c86..119134e67c89 100644
--- a/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -253,7 +253,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test,
 	if (xe_bo_is_vram(pt))
 		xe_res_first(pt->ttm.resource, 0, xe_bo_size(pt), &src_it);
 	else
-		xe_res_first_sg(xe_bo_sg(pt), 0, xe_bo_size(pt), &src_it);
+		xe_res_first_tt(pt->ttm.ttm, 0, xe_bo_size(pt), &src_it);
 
 	emit_pte(m, bb, NUM_KERNEL_PDE - 1, xe_bo_is_vram(pt), false,
 		 &src_it, XE_PAGE_SIZE, pt->ttm.resource);
@@ -385,12 +385,12 @@ static struct dma_fence *blt_copy(struct xe_tile *tile,
 	bool dst_is_vram = mem_type_is_vram(dst->mem_type);
 
 	if (!src_is_vram)
-		xe_res_first_sg(xe_bo_sg(src_bo), 0, size, &src_it);
+		xe_res_first_tt(src_bo->ttm.ttm, 0, size, &src_it);
 	else
 		xe_res_first(src, 0, size, &src_it);
 
 	if (!dst_is_vram)
-		xe_res_first_sg(xe_bo_sg(dst_bo), 0, size, &dst_it);
+		xe_res_first_tt(dst_bo->ttm.ttm, 0, size, &dst_it);
 	else
 		xe_res_first(dst, 0, size, &dst_it);
 
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index c096f3dbd528..f3d76ad9a105 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -6,6 +6,7 @@
 #include "xe_bo.h"
 
 #include <linux/dma-buf.h>
+#include <linux/dma-mapping.h>
 #include <linux/nospec.h>
 
 #include <drm/drm_drv.h>
@@ -15,6 +16,7 @@
 #include <drm/ttm/ttm_backup.h>
 #include <drm/ttm/ttm_device.h>
 #include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_pool.h>
 #include <drm/ttm/ttm_tt.h>
 #include <uapi/drm/xe_drm.h>
 
@@ -420,6 +422,32 @@ struct xe_ttm_tt {
 	struct ttm_tt ttm;
 	struct sg_table sgt;
 	struct sg_table *sg;
+	/**
+	 * @iova: IOVA state describing the single contiguous IOVA mapping of
+	 * the tt pages. Only valid when @use_iova is true.
+	 */
+	struct dma_iova_state iova;
+	/**
+	 * @use_iova: Whether this tt is DMA mapped using the IOVA-based DMA
+	 * API instead of a scatter-gather list. Decided once at tt creation
+	 * time and stable for the lifetime of the tt.
+	 */
+	bool use_iova;
+	/**
+	 * @iova_linked: Whether the tt pages are currently linked into the
+	 * IOVA mapping. Only meaningful when @use_iova is true.
+	 */
+	bool iova_linked;
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	/**
+	 * @iova_dma_pages: Per-order count of DMA-mapped pages this tt
+	 * accounted into xe->mem.dma_mapped_pages[] for its IOVA mapping,
+	 * recorded at link time so the unlink can apply an exactly matching
+	 * decrement without re-walking tt->pages (which TTM may mutate, e.g.
+	 * during defrag). Counter ownership stays isolated in xe_bo.c.
+	 */
+	unsigned long iova_dma_pages[NR_PAGE_ORDERS];
+#endif
 	/** @purgeable: Whether the content of the pages of @ttm is purgeable. */
 	bool purgeable;
 };
@@ -468,6 +496,52 @@ static void xe_tt_account_dma_pages(struct xe_device *xe,
 }
 #endif
 
+/*
+ * xe_tt_account_iova_add - account one freshly linked IOVA folio
+ * @xe: the xe device
+ * @xe_tt: the xe_ttm_tt being mapped
+ * @order: page order of the linked folio
+ *
+ * Add the folio's 2^order pages to xe->mem.dma_mapped_pages[order] and record
+ * the same amount in @xe_tt so xe_tt_unaccount_iova() can later subtract an
+ * exactly matching count without re-walking tt->pages.
+ */
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+static void xe_tt_account_iova_add(struct xe_device *xe,
+				   struct xe_ttm_tt *xe_tt, unsigned int order)
+{
+	unsigned long chunk = 1UL << order;
+
+	xe_tt->iova_dma_pages[order] += chunk;
+	atomic_long_add(chunk, &xe->mem.dma_mapped_pages[order]);
+}
+
+static void xe_tt_unaccount_iova(struct xe_device *xe,
+				 struct xe_ttm_tt *xe_tt)
+{
+	unsigned int order;
+
+	for (order = 0; order < NR_PAGE_ORDERS; order++) {
+		unsigned long pages = xe_tt->iova_dma_pages[order];
+
+		if (pages) {
+			atomic_long_sub(pages, &xe->mem.dma_mapped_pages[order]);
+			xe_tt->iova_dma_pages[order] = 0;
+		}
+	}
+}
+#else
+static void xe_tt_account_iova_add(struct xe_device *xe,
+				   struct xe_ttm_tt *xe_tt, unsigned int order)
+{
+}
+
+static void xe_tt_unaccount_iova(struct xe_device *xe,
+				 struct xe_ttm_tt *xe_tt)
+{
+}
+#endif
+
 static int xe_tt_map_sg(struct xe_device *xe, struct ttm_tt *tt)
 {
 	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
@@ -514,28 +588,129 @@ static void xe_tt_unmap_sg(struct xe_device *xe, struct ttm_tt *tt)
 	}
 }
 
-struct sg_table *xe_bo_sg(struct xe_bo *bo)
+/*
+ * xe_tt_map_iova - DMA map a tt using the IOVA-based DMA API.
+ *
+ * Link all of the tt's pages into the IOVA range reserved at tt creation
+ * time, one folio at a time, and sync the IOTLB once at the end. The IOVA
+ * reservation itself is kept across map/unmap cycles and only released when
+ * the tt is destroyed.
+ */
+static int xe_tt_map_iova(struct xe_device *xe, struct ttm_tt *tt)
 {
-	struct ttm_tt *tt = bo->ttm.ttm;
 	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+	struct device *dev = xe->drm.dev;
+	unsigned long num_pages = tt->num_pages;
+	unsigned long i = 0;
+	size_t mapped = 0;
+	int ret;
+
+	if (xe_tt->iova_linked)
+		return 0;
+
+	while (i < num_pages) {
+		struct page *page = tt->pages[i];
+		unsigned int order = ttm_pool_page_order_nodma(page);
+		size_t len = PAGE_SIZE << order;
+
+		ret = dma_iova_link(dev, &xe_tt->iova, page_to_phys(page),
+				    mapped, len, DMA_BIDIRECTIONAL,
+				    DMA_ATTR_SKIP_CPU_SYNC);
+		if (ret)
+			goto err_unlink;
 
-	return xe_tt->sg;
+		xe_tt_account_iova_add(xe, xe_tt, order);
+		mapped += len;
+		i += 1UL << order;
+	}
+
+	ret = dma_iova_sync(dev, &xe_tt->iova, 0, mapped);
+	if (ret)
+		goto err_unlink;
+
+	xe_tt->iova_linked = true;
+	return 0;
+
+err_unlink:
+	if (mapped) {
+		dma_iova_unlink(dev, &xe_tt->iova, 0, mapped,
+				DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);
+		xe_tt_unaccount_iova(xe, xe_tt);
+	}
+	return ret;
 }
 
-/**
- * xe_tt_sg() - Return the DMA scatter-gather table backing a ttm_tt.
- * @tt: The ttm_tt to query.
+/*
+ * xe_tt_unmap_iova - Unlink a tt's pages from its IOVA mapping.
  *
- * Like xe_bo_sg(), but takes the ttm_tt directly. Used by the defrag copy
- * path which needs the old (source) tt's sg table without a backing xe_bo.
+ * Unlink the pages but keep the IOVA reservation so the tt can be remapped
+ * later without re-allocating IOVA space.
+ */
+static void xe_tt_unmap_iova(struct xe_device *xe, struct ttm_tt *tt)
+{
+	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+
+	if (xe_tt->iova_linked) {
+		/*
+		 * Unmap with attrs 0 (matching the sg unmap path) so that the
+		 * CPU copy-back sync is performed for non-coherent or bounced
+		 * (SWIOTLB) mappings, even though the link was done with
+		 * DMA_ATTR_SKIP_CPU_SYNC.
+		 */
+		dma_iova_unlink(xe->drm.dev, &xe_tt->iova, 0,
+				dma_iova_size(&xe_tt->iova),
+				DMA_BIDIRECTIONAL, 0);
+		xe_tt_unaccount_iova(xe, xe_tt);
+		xe_tt->iova_linked = false;
+	}
+}
+
+/*
+ * xe_tt_map - DMA map a tt, using IOVA when available and sg otherwise.
+ */
+static int xe_tt_map(struct xe_device *xe, struct ttm_tt *tt)
+{
+	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+
+	if (xe_tt->use_iova)
+		return xe_tt_map_iova(xe, tt);
+
+	return xe_tt_map_sg(xe, tt);
+}
+
+/*
+ * xe_tt_unmap - Undo xe_tt_map().
+ */
+static void xe_tt_unmap(struct xe_device *xe, struct ttm_tt *tt)
+{
+	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+
+	if (xe_tt->use_iova)
+		xe_tt_unmap_iova(xe, tt);
+	else
+		xe_tt_unmap_sg(xe, tt);
+}
+
+/**
+ * xe_res_first_tt() - Initialize a resource cursor over a ttm_tt's DMA mapping.
+ * @tt: The ttm_tt to walk.
+ * @start: Start of the range, in bytes.
+ * @size: Size of the range, in bytes.
+ * @cur: The cursor to initialize.
  *
- * Return: The sg table, or NULL if the tt is not currently mapped.
+ * Initialize @cur to walk the DMA addresses backing @tt, transparently
+ * handling both the IOVA-based mapping (single contiguous range) and the
+ * scatter-gather list fallback.
  */
-struct sg_table *xe_tt_sg(struct ttm_tt *tt)
+void xe_res_first_tt(struct ttm_tt *tt, u64 start, u64 size,
+		     struct xe_res_cursor *cur)
 {
 	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
 
-	return xe_tt->sg;
+	if (xe_tt->use_iova)
+		xe_res_first_iova(&xe_tt->iova, start, size, cur);
+	else
+		xe_res_first_sg(xe_tt->sg, start, size, cur);
 }
 
 /*
@@ -651,6 +826,21 @@ static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo,
 		}
 	}
 
+	/*
+	 * Eligible BOs are DMA mapped using the IOVA-based DMA API, which
+	 * yields a single contiguous IOVA range instead of a scatter-gather
+	 * list. Only device BOs that are not GGTT-mapped qualify: dma-buf
+	 * imports manage their own mapping and GGTT bindings are programmed
+	 * directly from the sg list. dma_iova_try_alloc() may still fail
+	 * depending on the IOMMU mode, in which case we transparently fall
+	 * back to the sg list. The reservation lives for the tt's lifetime.
+	 */
+	if (ttm_bo->type != ttm_bo_type_sg &&
+	    !(bo->flags & (XE_BO_FLAG_GGTT | XE_BO_FLAG_GGTT_ALL)) &&
+	    dma_iova_try_alloc(xe->drm.dev, &xe_tt->iova, 0,
+			       (size_t)tt->num_pages << PAGE_SHIFT))
+		xe_tt->use_iova = true;
+
 	return tt;
 }
 
@@ -700,7 +890,7 @@ static void xe_ttm_tt_unpopulate(struct ttm_device *ttm_dev, struct ttm_tt *tt)
 	    !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE))
 		return;
 
-	xe_tt_unmap_sg(xe, tt);
+	xe_tt_unmap(xe, tt);
 
 	ttm_pool_free(&ttm_dev->pool, tt);
 	xe_ttm_tt_account_subtract(xe, tt);
@@ -709,6 +899,19 @@ static void xe_ttm_tt_unpopulate(struct ttm_device *ttm_dev, struct ttm_tt *tt)
 
 static void xe_ttm_tt_destroy(struct ttm_device *ttm_dev, struct ttm_tt *tt)
 {
+	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
+
+	/*
+	 * Release the IOVA reservation made in xe_ttm_tt_create(). The pages
+	 * must already have been unlinked by xe_tt_unmap().
+	 */
+	if (xe_tt->use_iova) {
+		struct xe_device *xe = ttm_to_xe_device(ttm_dev);
+
+		xe_assert(xe, !xe_tt->iova_linked);
+		dma_iova_free(xe->drm.dev, &xe_tt->iova);
+	}
+
 	ttm_tt_fini(tt);
 	kfree(tt);
 }
@@ -1533,7 +1736,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
 	/* Bo creation path, moving to system or TT. */
 	if ((!old_mem && ttm) && !handle_system_ccs) {
 		if (new_mem->mem_type == XE_PL_TT)
-			ret = xe_tt_map_sg(xe, ttm);
+			ret = xe_tt_map(xe, ttm);
 		if (!ret)
 			ttm_bo_move_null(ttm_bo, new_mem);
 		goto out;
@@ -1563,7 +1766,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
 		(!ttm && ttm_bo->type == ttm_bo_type_device);
 
 	if (new_mem->mem_type == XE_PL_TT) {
-		ret = xe_tt_map_sg(xe, ttm);
+		ret = xe_tt_map(xe, ttm);
 		if (ret)
 			goto out;
 	}
@@ -1733,7 +1936,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
 		if (IS_VF_CCS_READY(xe))
 			xe_sriov_vf_ccs_detach_bo(bo);
 
-		xe_tt_unmap_sg(xe, ttm_bo->ttm);
+		xe_tt_unmap(xe, ttm_bo->ttm);
 	}
 
 	xe_bo_defrag_update(bo);
@@ -1761,7 +1964,7 @@ static long xe_bo_shrink_purge(struct ttm_operation_ctx *ctx,
 		if (lret)
 			return lret;
 
-		xe_tt_unmap_sg(xe, bo->ttm);
+		xe_tt_unmap(xe, bo->ttm);
 		ttm_bo_move_null(bo, new_resource);
 	}
 
@@ -2188,6 +2391,8 @@ int xe_bo_dma_unmap_pinned(struct xe_bo *bo)
 						 DMA_BIDIRECTIONAL);
 			ttm_bo->sg = NULL;
 			xe_tt->sg = NULL;
+		} else if (xe_tt->use_iova) {
+			xe_tt_unmap_iova(ttm_to_xe_device(ttm_bo->bdev), tt);
 		} else if (xe_tt->sg) {
 			dma_unmap_sgtable(ttm_to_xe_device(ttm_bo->bdev)->drm.dev,
 					  xe_tt->sg,
@@ -3755,7 +3960,7 @@ dma_addr_t __xe_bo_addr(struct xe_bo *bo, u64 offset, size_t page_size)
 	if (!xe_bo_is_vram(bo) && !xe_bo_is_stolen(bo)) {
 		xe_assert(xe, bo->ttm.ttm);
 
-		xe_res_first_sg(xe_bo_sg(bo), page << PAGE_SHIFT,
+		xe_res_first_tt(bo->ttm.ttm, page << PAGE_SHIFT,
 				page_size, &cur);
 		return xe_res_dma(&cur) + offset;
 	} else {
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 18fcccd082b7..3e2eaefecb8f 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -552,8 +552,9 @@ void xe_bo_dev_init(struct xe_bo_dev *bo_device);
 
 void xe_bo_dev_fini(struct xe_bo_dev *bo_device);
 
-struct sg_table *xe_bo_sg(struct xe_bo *bo);
-struct sg_table *xe_tt_sg(struct ttm_tt *tt);
+struct xe_res_cursor;
+void xe_res_first_tt(struct ttm_tt *tt, u64 start, u64 size,
+		     struct xe_res_cursor *cur);
 
 /*
  * xe_sg_segment_size() - Provides upper limit for sg segment size.
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index 8ec23862477f..4084bc183e06 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -699,7 +699,7 @@ static void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
 	if (!xe_bo_is_vram(bo) && !xe_bo_is_stolen(bo)) {
 		xe_assert(xe_bo_device(bo), bo->ttm.ttm);
 
-		for (xe_res_first_sg(xe_bo_sg(bo), 0, xe_bo_size(bo), &cur);
+		for (xe_res_first_tt(bo->ttm.ttm, 0, xe_bo_size(bo), &cur);
 		     cur.remaining; xe_res_next(&cur, XE_PAGE_SIZE))
 			ggtt->pt_ops->ggtt_set_pte(ggtt, end - cur.remaining,
 						   pte | xe_res_dma(&cur));
diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
index c1e96f105648..80fff1b5b3aa 100644
--- a/drivers/gpu/drm/xe/xe_migrate.c
+++ b/drivers/gpu/drm/xe/xe_migrate.c
@@ -1005,16 +1005,16 @@ static struct dma_fence *__xe_migrate_copy(struct xe_migrate *m,
 		return ERR_PTR(-EINVAL);
 
 	if (!src_is_vram)
-		xe_res_first_sg(src_tt ? xe_tt_sg(src_tt) : xe_bo_sg(src_bo), 0, size, &src_it);
+		xe_res_first_tt(src_tt ? src_tt : src_bo->ttm.ttm, 0, size, &src_it);
 	else
 		xe_res_first(src, 0, size, &src_it);
 	if (!dst_is_vram)
-		xe_res_first_sg(xe_bo_sg(dst_bo), 0, size, &dst_it);
+		xe_res_first_tt(dst_bo->ttm.ttm, 0, size, &dst_it);
 	else
 		xe_res_first(dst, 0, size, &dst_it);
 
 	if (copy_system_ccs)
-		xe_res_first_sg(src_tt ? xe_tt_sg(src_tt) : xe_bo_sg(src_bo),
+		xe_res_first_tt(src_tt ? src_tt : src_bo->ttm.ttm,
 				xe_bo_ccs_pages_start(src_bo),
 				PAGE_ALIGN(xe_device_ccs_bytes(xe, size)),
 				&ccs_it);
@@ -1383,9 +1383,9 @@ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
 
 	ctx = &xe->sriov.vf.ccs.contexts[read_write];
 
-	xe_res_first_sg(xe_bo_sg(src_bo), 0, size, &src_it);
+	xe_res_first_tt(src_bo->ttm.ttm, 0, size, &src_it);
 
-	xe_res_first_sg(xe_bo_sg(src_bo), xe_bo_ccs_pages_start(src_bo),
+	xe_res_first_tt(src_bo->ttm.ttm, xe_bo_ccs_pages_start(src_bo),
 			PAGE_ALIGN(xe_device_ccs_bytes(xe, size)),
 			&ccs_it);
 
@@ -1588,7 +1588,7 @@ struct dma_fence *xe_migrate_vram_copy_chunk(struct xe_bo *vram_bo, u64 vram_off
 	xe_assert(xe, !range_overflows(sysmem_offset, size, (u64)sysmem_bo->ttm.base.size));
 
 	xe_res_first(vram, vram_offset, size, &vram_it);
-	xe_res_first_sg(xe_bo_sg(sysmem_bo), sysmem_offset, size, &sysmem_it);
+	xe_res_first_tt(sysmem_bo->ttm.ttm, sysmem_offset, size, &sysmem_it);
 
 	while (size) {
 		u32 pte_flags = PTE_UPDATE_FLAG_IS_VRAM;
@@ -1800,7 +1800,7 @@ struct dma_fence *xe_migrate_clear(struct xe_migrate *m,
 		clear_only_system_ccs = true;
 
 	if (!clear_vram)
-		xe_res_first_sg(xe_bo_sg(bo), 0, xe_bo_size(bo), &src_it);
+		xe_res_first_tt(bo->ttm.ttm, 0, xe_bo_size(bo), &src_it);
 	else
 		xe_res_first(src, 0, xe_bo_size(bo), &src_it);
 
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 7111b5d0f6aa..185d15fb0a97 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -797,7 +797,7 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
 			xe_res_first(bo->ttm.resource, xe_vma_bo_offset(vma),
 				     xe_vma_size(vma), &curs);
 		else
-			xe_res_first_sg(xe_bo_sg(bo), xe_vma_bo_offset(vma),
+			xe_res_first_tt(bo->ttm.ttm, xe_vma_bo_offset(vma),
 					xe_vma_size(vma), &curs);
 	} else if (!range) {
 		curs.size = xe_vma_size(vma);
-- 
2.34.1


  parent reply	other threads:[~2026-07-10 21:55 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10 21:54 [PATCH v2 00/33] drm/ttm, drm/xe: Minimize dma-resv hold times and defragment sub-optimally backed BOs Matthew Brost
2026-07-10 21:54 ` [PATCH v2 01/33] drm/ttm/pool: Allow backing off reclaim at the beneficial order Matthew Brost
2026-07-11 10:38   ` Christian König
2026-07-11 13:27     ` Matthew Brost
2026-07-10 21:54 ` [PATCH v2 02/33] drm/ttm/pool: Add ttm_pool_page_order_nodma() helper Matthew Brost
2026-07-11 10:39   ` Christian König
2026-07-11 12:40     ` Matthew Brost
2026-07-10 21:54 ` [PATCH v2 03/33] drm/ttm: Record sub-optimal page order allocations in ttm_tt Matthew Brost
2026-07-10 21:54 ` [PATCH v2 04/33] drm/ttm: Introduce ttm_pool_alloc_iter for __ttm_pool_alloc() Matthew Brost
2026-07-10 21:54 ` [PATCH v2 05/33] drm/ttm: Support defragmentation moves Matthew Brost
2026-07-10 21:54 ` [PATCH v2 06/33] drm/ttm: Add fault injection for beneficial-order allocation failures Matthew Brost
2026-07-10 21:54 ` [PATCH v2 07/33] drm/ttm: Harvest beneficial-order pages on defragmentation moves Matthew Brost
2026-07-10 21:54 ` [PATCH v2 08/33] drm/ttm: Bound page (re)allocation per defragmentation move Matthew Brost
2026-07-10 21:54 ` [PATCH v2 09/33] drm/ttm: Preallocate beneficial-order defrag pages outside the lock Matthew Brost
2026-07-10 21:54 ` [PATCH v2 10/33] drm/ttm: Add full out-of-lock preallocation for ttm_pool_alloc() Matthew Brost
2026-07-10 21:54 ` [PATCH v2 11/33] drm/gpusvm: Add a DMA-mapping accounting callback Matthew Brost
2026-07-10 21:54 ` [PATCH v2 12/33] drm/xe: Add debugfs stats for DMA-mapped pages per order Matthew Brost
2026-07-10 21:54 ` [PATCH v2 13/33] drm/xe: Flush L2 asynchronously in xe_bo_trigger_rebind() Matthew Brost
2026-07-10 21:54 ` [PATCH v2 14/33] drm/xe: Destroy page tables after unlinking all VMAs on VM close Matthew Brost
2026-07-10 21:54 ` [PATCH v2 15/33] drm/xe: Track BOs backed at a sub-optimal page order Matthew Brost
2026-07-10 21:54 ` [PATCH v2 16/33] drm/xe: Back off beneficial-order reclaim under defrag pressure Matthew Brost
2026-07-10 21:54 ` [PATCH v2 17/33] drm/xe: Add xe_migrate_copy_defrag() for on-GPU defrag copies Matthew Brost
2026-07-10 21:54 ` [PATCH v2 18/33] drm/xe: Handle defrag moves in xe_bo_move() Matthew Brost
2026-07-10 21:54 ` [PATCH v2 19/33] drm/xe: Skip self-copies for borrowed pages on defrag moves Matthew Brost
2026-07-10 21:54 ` [PATCH v2 20/33] drm/xe: Add a page defragmentation worker Matthew Brost
2026-07-10 21:54 ` [PATCH v2 21/33] drm/xe: Add defrag GT stats Matthew Brost
2026-07-10 21:54 ` [PATCH v2 22/33] drm/xe: Add Kconfig.profile options for BO defrag configuration Matthew Brost
2026-07-10 21:54 ` [PATCH v2 23/33] drm/xe: Defrag using out-of-lock page preallocation Matthew Brost
2026-07-10 21:54 ` [PATCH v2 24/33] drm/xe: Add defrag profiling tracepoints Matthew Brost
2026-07-10 21:54 ` [PATCH v2 25/33] drm/xe: Preallocate system BO backing outside the dma-resv lock Matthew Brost
2026-07-10 21:54 ` [PATCH v2 26/33] drm/xe: Add tracepoint for xe_gem_create_ioctl Matthew Brost
2026-07-10 21:54 ` [PATCH v2 27/33] drm/xe: Add IOVA-based xe_res_cursor variant Matthew Brost
2026-07-10 21:54 ` Matthew Brost [this message]
2026-07-10 21:54 ` [PATCH v2 29/33] drm/xe: Add per-device dependency scheduler for IOVA defrag finalize Matthew Brost
2026-07-10 21:54 ` [PATCH v2 30/33] drm/xe: Add packed copy-step IOVA mapping for defrag Matthew Brost
2026-07-10 21:54 ` [PATCH v2 31/33] drm/xe: Blit src-natural to dst-packed for defrag-IOVA copies Matthew Brost
2026-07-10 21:54 ` [PATCH v2 32/33] drm/xe: Finalize defrag-IOVA moves with post-copy job Matthew Brost
2026-07-10 21:54 ` [PATCH v2 33/33] drm/amdgpu: Preallocate system BO pages outside the reservation lock Matthew Brost
2026-07-10 22:03 ` ✗ CI.checkpatch: warning for drm/ttm, drm/xe: Minimize dma-resv hold times and defragment sub-optimally backed BOs Patchwork
2026-07-10 22:05 ` ✓ CI.KUnit: success " Patchwork
2026-07-10 22:20 ` ✗ CI.checksparse: warning " Patchwork
2026-07-10 22:40 ` ✗ Xe.CI.BAT: failure " Patchwork
2026-07-11 10:33 ` [PATCH v2 00/33] " Christian König
2026-07-11 13:49   ` Matthew Brost

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=20260710215442.2444235-29-matthew.brost@intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=carlos.santa@intel.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@intel.com \
    --cc=mripard@kernel.org \
    --cc=ray.huang@amd.com \
    --cc=ryanneph@google.com \
    --cc=simona@ffwll.ch \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=tzimmermann@suse.de \
    /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