* [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement
@ 2026-11-02 10:18 Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
` (9 more replies)
0 siblings, 10 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
The backing pages of an Xe system memory BO are allocated on the device
local node (dev_to_node()), or on the allocating CPU's node when the
device has none. That is fine when CPU and GPU access a buffer from the
same place, but not in general:
- On multi-socket systems, and where the GPU's PCIe/CXL link attaches
to a different node than the threads using a buffer, the cost of
accessing a BO depends on which node backs its pages. The device
local node is not always the best choice.
- A runtime often knows where a BO should live: the node of the CPU
threads producing or consuming it, the node closest to the link the
GPU uses, or a node chosen to balance memory bandwidth. Today it has
no way to express that for driver allocated system memory.
- mbind()/set_mempolicy() do not help: BO pages are allocated by the
driver, not through the task's fault path, and BO CPU mappings are
VM_PFNMAP.
This series lets userspace select the host NUMA node per BO at
creation time.
UAPI:
- New DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE property on the existing
GEM_CREATE set-property extension.
- The node is a preference (best effort, like MPOL_PREFERRED); the
allocation falls back to other nodes under memory pressure.
- A negative value, or not setting the property, keeps the current
default placement.
- Invalid or offline nodes, and BOs that can't be placed in system
memory, are rejected with -EINVAL.
- The placement is preserved across shrinker backup / restore.
- A richer placement policy can be added later as a separate extension
without changing this one.
Why a node aware TTM allocation API rather than one ttm_pool per node
in the driver:
The NUMA node is a property of each allocation, not of the pool. TTM
already tracks pages per node (per-node LRUs in the pool caches,
per-node shrinker, per-node cache limits) and __ttm_pool_alloc()
already takes a node internally. ttm_pool_alloc_node() and
ttm_tt_restore_node() only let a caller pass that node in, following
the alloc_pages_node() / kmalloc_node() pattern, with no new state.
One pool per node in the driver would work for Xe today, but:
- TTM core helpers (ttm_tt_restore(), ttm_tt_backup(), pool debugfs)
all use the device pool. The driver would have to bypass them for
populate, restore, backup and free, and re-check that whenever TTM
adds or changes a helper. The restore issue fixed in this series is
an example: the placement was silently lost after backup.
- It relies on non dma_alloc pools having no per-pool state. For
dma_alloc pools, N pools mean N separate page caches that can't
share pages.
- Every TTM driver that wants per-BO placement would have to duplicate
the same per-node pool handling.
The existing ttm_pool_alloc() and ttm_tt_restore() become wrappers
passing NUMA_NO_NODE, so current users are unaffected.
Himal Prasad Ghimiray (7):
drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
drm/ttm: Add NUMA node aware restore helpers
drm/ttm/pool: enforce per-node cache limits on free
drm/xe/bo: Plumb a per-BO host NUMA node hint into tt populate
drm/xe/bo: Preserve the host NUMA node across backup / restore
drm/xe/uapi: Add GEM_CREATE NUMA node placement property
drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
drivers/gpu/drm/ttm/ttm_pool.c | 104 +++++++++++++++++++---
drivers/gpu/drm/ttm/ttm_pool_internal.h | 4 +
drivers/gpu/drm/ttm/ttm_tt.c | 20 ++++-
drivers/gpu/drm/xe/tests/xe_bo.c | 12 +--
drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 +-
drivers/gpu/drm/xe/tests/xe_migrate.c | 8 +-
drivers/gpu/drm/xe/xe_bo.c | 109 +++++++++++++++++++-----
drivers/gpu/drm/xe/xe_bo.h | 5 +-
drivers/gpu/drm/xe/xe_bo_types.h | 7 ++
drivers/gpu/drm/xe/xe_dma_buf.c | 3 +-
include/drm/ttm/ttm_pool.h | 2 +
include/drm/ttm/ttm_tt.h | 2 +
include/uapi/drm/xe_drm.h | 7 ++
13 files changed, 238 insertions(+), 49 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:26 ` sashiko-bot
2026-11-02 10:50 ` Christian König
2026-11-02 10:18 ` [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers Himal Prasad Ghimiray
` (8 subsequent siblings)
9 siblings, 2 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
ttm_pool_alloc() always allocates on the pool's default node, although
the internal TTM helpers (__ttm_pool_alloc(), ttm_pool_alloc_page(),
ttm_pool_type_take()) already take a nid. Add ttm_pool_alloc_node() to
let a driver pass that nid for a specific tt.
ttm_pool_alloc() passes NUMA_NO_NODE, keeping current behaviour. An
explicit node on a dma_alloc pool returns -EOPNOTSUPP, as
dma_alloc_attrs() can't honor it.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/ttm/ttm_pool.c | 59 +++++++++++++++++++++++++++++-----
include/drm/ttm/ttm_pool.h | 2 ++
2 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 1bf37023fed6..54d2f6b5c229 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -158,9 +158,9 @@ static int ttm_pool_nid(struct ttm_pool *pool)
return nid;
}
-/* Allocate pages of size 1 << order with the given gfp_flags */
+/* Allocate pages of size 1 << order with the given gfp_flags on node @nid */
static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
- unsigned int order)
+ unsigned int order, int nid)
{
const unsigned int beneficial_order = ttm_pool_beneficial_order(pool);
unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
@@ -189,7 +189,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
}
if (!ttm_pool_uses_dma_alloc(pool)) {
- p = alloc_pages_node(pool->nid, gfp_flags, order);
+ p = alloc_pages_node(nid, gfp_flags, order);
if (p) {
p->private = order;
mod_lruvec_page_state(p, NR_GPU_ACTIVE, 1 << order);
@@ -783,7 +783,8 @@ static unsigned int ttm_pool_alloc_find_order(unsigned int highest,
static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx,
struct ttm_pool_alloc_state *alloc,
- struct ttm_pool_tt_restore *restore)
+ struct ttm_pool_tt_restore *restore,
+ int nid)
{
enum ttm_caching page_caching;
gfp_t gfp_flags = GFP_USER;
@@ -818,7 +819,7 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
p = NULL;
pt = ttm_pool_select_type(pool, page_caching, order);
if (pt && allow_pools)
- p = ttm_pool_type_take(pt, ttm_pool_nid(pool));
+ p = ttm_pool_type_take(pt, nid);
/*
* If that fails or previously failed, allocate from system.
@@ -829,7 +830,7 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
if (!p) {
page_caching = ttm_cached;
allow_pools = false;
- p = ttm_pool_alloc_page(pool, gfp_flags, order);
+ p = ttm_pool_alloc_page(pool, gfp_flags, order, nid);
}
/* If that fails, lower the order if possible and retry. */
if (!p) {
@@ -900,10 +901,52 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
ttm_pool_alloc_state_init(tt, &alloc);
- return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL);
+ return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, ttm_pool_nid(pool));
}
EXPORT_SYMBOL(ttm_pool_alloc);
+/**
+ * ttm_pool_alloc_node - Fill a ttm_tt object, placing pages on a given node
+ *
+ * @pool: ttm_pool to use
+ * @tt: ttm_tt object to fill
+ * @ctx: operation context
+ * @nid: NUMA node id to allocate the backing system pages from, or
+ * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
+ *
+ * Like ttm_pool_alloc(), but allows the caller to override the NUMA node the
+ * backing system pages are allocated from. This only affects the
+ * non-coherent (non dma-alloc) allocation path; coherent/dma pools continue
+ * to use the device-local node. Intended for drivers that expose a
+ * user-selectable host memory NUMA placement.
+ *
+ * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a coherent/dma
+ * pool, negative error code otherwise.
+ */
+int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+ struct ttm_operation_ctx *ctx, int nid)
+{
+ struct ttm_pool_alloc_state alloc;
+
+ if (WARN_ON(ttm_tt_is_backed_up(tt)))
+ return -EINVAL;
+
+ /*
+ * Coherent/dma pools allocate via dma_alloc_attrs(), which places pages
+ * per device DMA constraints and cannot honor a caller-requested node.
+ */
+ if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
+ return -EOPNOTSUPP;
+
+ if (nid == NUMA_NO_NODE)
+ nid = ttm_pool_nid(pool);
+
+ ttm_pool_alloc_state_init(tt, &alloc);
+
+ return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, nid);
+}
+EXPORT_SYMBOL(ttm_pool_alloc_node);
+
/**
* ttm_pool_restore_and_alloc - Fill a ttm_tt, restoring previously backed-up
* content.
@@ -964,7 +1007,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
}
}
- return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore);
+ return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, ttm_pool_nid(pool));
}
/**
diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h
index 26ee592e1994..6a0b14aca092 100644
--- a/include/drm/ttm/ttm_pool.h
+++ b/include/drm/ttm/ttm_pool.h
@@ -79,6 +79,8 @@ struct ttm_pool {
int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
struct ttm_operation_ctx *ctx);
+int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+ struct ttm_operation_ctx *ctx, int nid);
void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt);
void ttm_pool_init(struct ttm_pool *pool, struct device *dev,
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:26 ` sashiko-bot
2026-11-02 10:18 ` [RFC 3/7] drm/ttm/pool: enforce per-node cache limits on free Himal Prasad Ghimiray
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
Restore after shrinker backup always allocates on the pool's default
node, so a placement chosen with ttm_pool_alloc_node() is lost. The
internal restore path already uses __ttm_pool_alloc(), which takes a
nid; add ttm_tt_restore_node() to pass it through.
ttm_tt_restore() passes NUMA_NO_NODE, keeping current behaviour.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/ttm/ttm_pool.c | 32 ++++++++++++++++++++++++-
drivers/gpu/drm/ttm/ttm_pool_internal.h | 4 ++++
drivers/gpu/drm/ttm/ttm_tt.c | 20 ++++++++++++++--
include/drm/ttm/ttm_tt.h | 2 ++
4 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 54d2f6b5c229..2107dc6c69b3 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -962,6 +962,30 @@ EXPORT_SYMBOL(ttm_pool_alloc_node);
*/
int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx)
+{
+ return ttm_pool_restore_and_alloc_node(pool, tt, ctx, NUMA_NO_NODE);
+}
+EXPORT_SYMBOL(ttm_pool_restore_and_alloc);
+
+/**
+ * ttm_pool_restore_and_alloc_node - Fill a ttm_tt, restoring previously
+ * backed-up content, placing pages on a given node.
+ *
+ * @pool: ttm_pool to use
+ * @tt: ttm_tt object to fill
+ * @ctx: operation context
+ * @nid: NUMA node id to allocate the backing system pages from, or
+ * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
+ *
+ * Like ttm_pool_restore_and_alloc(), but allows the caller to keep the NUMA
+ * placement requested at ttm_pool_alloc_node() time across backup / restore.
+ *
+ * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a coherent/dma
+ * pool, negative error code otherwise.
+ */
+int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+ const struct ttm_operation_ctx *ctx,
+ int nid)
{
struct ttm_pool_tt_restore *restore = tt->restore;
struct ttm_pool_alloc_state alloc;
@@ -970,6 +994,12 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
if (WARN_ON(!ttm_tt_is_backed_up(tt)))
return -EINVAL;
+ if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
+ return -EOPNOTSUPP;
+
+ if (nid == NUMA_NO_NODE)
+ nid = ttm_pool_nid(pool);
+
if (!restore) {
gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
@@ -1007,7 +1037,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
}
}
- return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, ttm_pool_nid(pool));
+ return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, nid);
}
/**
diff --git a/drivers/gpu/drm/ttm/ttm_pool_internal.h b/drivers/gpu/drm/ttm/ttm_pool_internal.h
index cbb17a2129fe..66ee0e57cdeb 100644
--- a/drivers/gpu/drm/ttm/ttm_pool_internal.h
+++ b/drivers/gpu/drm/ttm/ttm_pool_internal.h
@@ -22,6 +22,10 @@ static inline unsigned int ttm_pool_beneficial_order(struct ttm_pool *pool)
return pool->alloc_flags & 0xff;
}
+int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+ const struct ttm_operation_ctx *ctx,
+ int nid);
+
/*
* Implemented in ttm_pool.c, used by ttm_backup.c. Returns true if a fault
* should be injected mid-compound to test the reactive split-and-retry
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index b645a1818184..775219ae5367 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -298,7 +298,23 @@ long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt,
int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx)
{
- int ret = ttm_pool_restore_and_alloc(&bdev->pool, tt, ctx);
+ return ttm_tt_restore_node(bdev, tt, ctx, NUMA_NO_NODE);
+}
+EXPORT_SYMBOL(ttm_tt_restore);
+
+/**
+ * ttm_tt_restore_node - Restore a backed-up tt, placing pages on a given node
+ * @bdev: The TTM device.
+ * @tt: The struct ttm_tt to restore.
+ * @ctx: The operation context.
+ * @nid: NUMA node for the restored pages, or NUMA_NO_NODE for the pool default.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int ttm_tt_restore_node(struct ttm_device *bdev, struct ttm_tt *tt,
+ const struct ttm_operation_ctx *ctx, int nid)
+{
+ int ret = ttm_pool_restore_and_alloc_node(&bdev->pool, tt, ctx, nid);
if (ret)
return ret;
@@ -307,7 +323,7 @@ int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
return 0;
}
-EXPORT_SYMBOL(ttm_tt_restore);
+EXPORT_SYMBOL(ttm_tt_restore_node);
/**
* ttm_tt_swapout - swap out tt object
diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
index 406437ad674b..7a75e22a7f70 100644
--- a/include/drm/ttm/ttm_tt.h
+++ b/include/drm/ttm/ttm_tt.h
@@ -297,6 +297,8 @@ long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt,
int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx);
+int ttm_tt_restore_node(struct ttm_device *bdev, struct ttm_tt *tt,
+ const struct ttm_operation_ctx *ctx, int nid);
int ttm_tt_setup_backup(struct ttm_tt *tt);
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 3/7] drm/ttm/pool: enforce per-node cache limits on free
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 4/7] drm/xe/bo: Plumb a per-BO host NUMA node hint into tt populate Himal Prasad Ghimiray
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
ttm_pool_free() only trims the cache of the pool's default node. With
pages allocated on other nodes, check each node's limit on free. The
per-node accounting and shrinker already exist in TTM.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/ttm/ttm_pool.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 2107dc6c69b3..faba20cef216 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -1050,13 +1050,20 @@ int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
*/
void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt)
{
- int nid = ttm_pool_nid(pool);
+ int nid;
ttm_pool_free_range(pool, tt, tt->caching, 0, tt->num_pages);
- while (atomic_long_read(&allocated_pages[nid]) > pool_node_limit[nid]) {
- unsigned long diff = atomic_long_read(&allocated_pages[nid]) - pool_node_limit[nid];
- ttm_pool_shrink(nid, diff);
+ /*
+ * ttm_pool_alloc_node() can place pages on a caller-requested node, so
+ * freed pages may land on any node's cache; enforce every node's limit.
+ */
+ for_each_node(nid) {
+ unsigned long cached;
+
+ while ((cached = atomic_long_read(&allocated_pages[nid])) >
+ pool_node_limit[nid])
+ ttm_pool_shrink(nid, cached - pool_node_limit[nid]);
}
}
EXPORT_SYMBOL(ttm_pool_free);
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 4/7] drm/xe/bo: Plumb a per-BO host NUMA node hint into tt populate
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (2 preceding siblings ...)
2026-11-02 10:18 ` [RFC 3/7] drm/ttm/pool: enforce per-node cache limits on free Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 5/7] drm/xe/bo: Preserve the host NUMA node across backup / restore Himal Prasad Ghimiray
` (5 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
Store a host NUMA node in the BO and its tt, and pass it to
ttm_pool_alloc_node() on populate. It defaults to NUMA_NO_NODE, so no
functional change.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_bo.c | 7 ++++++-
drivers/gpu/drm/xe/xe_bo_types.h | 7 +++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 42a6aa1a2e4a..b0760d5d6bad 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -394,6 +394,8 @@ struct xe_ttm_tt {
struct sg_table *sg;
/** @purgeable: Whether the content of the pages of @ttm is purgeable. */
bool purgeable;
+ /** @numa_node: Preferred host NUMA node for backing pages. */
+ s16 numa_node;
};
static int xe_tt_map_sg(struct xe_device *xe, struct ttm_tt *tt)
@@ -595,6 +597,7 @@ static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo,
return NULL;
tt = &xe_tt->ttm;
+ xe_tt->numa_node = bo->numa_node;
extra_pages = 0;
if (xe_bo_needs_ccs_pages(bo))
@@ -676,7 +679,8 @@ static int xe_ttm_tt_populate(struct ttm_device *ttm_dev, struct ttm_tt *tt,
err = ttm_tt_restore(ttm_dev, tt, ctx);
} else {
ttm_tt_clear_backed_up(tt);
- err = ttm_pool_alloc(&ttm_dev->pool, tt, ctx);
+ err = ttm_pool_alloc_node(&ttm_dev->pool, tt, ctx,
+ xe_tt->numa_node);
}
if (err)
return err;
@@ -2542,6 +2546,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
bo->tile = tile;
bo->flags = flags;
bo->cpu_caching = cpu_caching;
+ bo->numa_node = NUMA_NO_NODE;
bo->ttm.base.funcs = &xe_gem_object_funcs;
bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
INIT_LIST_HEAD(&bo->pinned_link);
diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
index 0265fb314c77..91e1c541b616 100644
--- a/drivers/gpu/drm/xe/xe_bo_types.h
+++ b/drivers/gpu/drm/xe/xe_bo_types.h
@@ -112,6 +112,13 @@ struct xe_bo {
*/
u16 cpu_caching;
+ /**
+ * @numa_node: Preferred host NUMA node for system-memory backing
+ * pages, or NUMA_NO_NODE to use the device-local node. Only honored
+ * for user objects with a system-memory placement.
+ */
+ s16 numa_node;
+
/** @devmem_allocation: SVM device memory allocation */
struct drm_pagemap_devmem devmem_allocation;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 5/7] drm/xe/bo: Preserve the host NUMA node across backup / restore
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (3 preceding siblings ...)
2026-11-02 10:18 ` [RFC 4/7] drm/xe/bo: Plumb a per-BO host NUMA node hint into tt populate Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property Himal Prasad Ghimiray
` (4 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
Use ttm_tt_restore_node() so a BO restored after shrinker backup comes
back on its requested node instead of the pool default.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_bo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index b0760d5d6bad..fc9bfb436b8e 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -676,7 +676,7 @@ static int xe_ttm_tt_populate(struct ttm_device *ttm_dev, struct ttm_tt *tt,
return 0;
if (ttm_tt_is_backed_up(tt) && !xe_tt->purgeable) {
- err = ttm_tt_restore(ttm_dev, tt, ctx);
+ err = ttm_tt_restore_node(ttm_dev, tt, ctx, xe_tt->numa_node);
} else {
ttm_tt_clear_backed_up(tt);
err = ttm_pool_alloc_node(&ttm_dev->pool, tt, ctx,
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (4 preceding siblings ...)
2026-11-02 10:18 ` [RFC 5/7] drm/xe/bo: Preserve the host NUMA node across backup / restore Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:27 ` sashiko-bot
2026-11-02 10:18 ` [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler Himal Prasad Ghimiray
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
Add DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE so userspace can choose
the host NUMA node backing a system memory BO. A negative value keeps
the default device-local placement.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
include/uapi/drm/xe_drm.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 578f0c1eb43e..0b39081330ee 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -843,6 +843,13 @@ struct drm_xe_device_query {
struct drm_xe_gem_create {
#define DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY 0
#define DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE 0
+ /*
+ * Host NUMA node (as a signed value) to allocate system-memory
+ * backing pages from. Only honored for objects with a system-memory
+ * placement; ignored for VRAM-only objects. Use a value < 0 to keep
+ * the default device-local placement.
+ */
+#define DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE 1
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (5 preceding siblings ...)
2026-11-02 10:18 ` [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property Himal Prasad Ghimiray
@ 2026-11-02 10:18 ` Himal Prasad Ghimiray
2026-11-02 10:29 ` sashiko-bot
2026-11-02 11:12 ` Matthew Auld
2026-11-02 12:44 ` ✓ CI.KUnit: success for drm/ttm, drm/xe: Per-BO host NUMA node placement Patchwork
` (2 subsequent siblings)
9 siblings, 2 replies; 19+ messages in thread
From: Himal Prasad Ghimiray @ 2026-11-02 10:18 UTC (permalink / raw)
To: Christian König, Huang Rui, Thomas Hellström,
Rodrigo Vivi
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe,
Himal Prasad Ghimiray
Parse the NUMA node property before BO creation and store it on the BO.
Offline or out of range nodes, and BOs without a system memory
placement, are rejected with -EINVAL.
Drop the explicit DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY check, already
covered by the property bounds check.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/tests/xe_bo.c | 12 +--
drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 +-
drivers/gpu/drm/xe/tests/xe_migrate.c | 8 +-
drivers/gpu/drm/xe/xe_bo.c | 102 +++++++++++++++++++++-----
drivers/gpu/drm/xe/xe_bo.h | 5 +-
drivers/gpu/drm/xe/xe_dma_buf.c | 3 +-
6 files changed, 100 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
index 6a17e13d58cf..6f61f5c618f1 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo.c
@@ -89,7 +89,7 @@ static void run_only_leaf(struct kunit *test,
bo = xe_bo_create_user(xe, NULL, li->alloc_size,
DRM_XE_GEM_CPU_CACHING_WC,
- XE_BO_FLAG_VRAM0, NULL);
+ XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
page_size_alloc_restore(xe, &saved);
if (PTR_ERR(bo) == -ENOSPC) {
@@ -183,7 +183,7 @@ static void xe_bo_page_size_alloc_mixed_bos(struct kunit *test)
*/
bo = xe_bo_create_user(xe, NULL, SZ_1G,
DRM_XE_GEM_CPU_CACHING_WC,
- XE_BO_FLAG_VRAM0, NULL);
+ XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
int err = PTR_ERR(bo);
@@ -366,7 +366,7 @@ static void ccs_test_run_tile(struct xe_device *xe, struct xe_tile *tile,
kunit_info(test, "Testing system memory\n");
bo = xe_bo_create_user(xe, NULL, SZ_1M, DRM_XE_GEM_CPU_CACHING_WC,
- bo_flags, exec);
+ bo_flags, NUMA_NO_NODE, exec);
if (IS_ERR(bo)) {
KUNIT_FAIL(test, "Failed to create bo.\n");
return;
@@ -445,7 +445,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
xe_vm_lock(vm, false);
bo = xe_bo_create_user(xe, vm, 0x10000,
DRM_XE_GEM_CPU_CACHING_WC,
- bo_flags, exec);
+ bo_flags, NUMA_NO_NODE, exec);
xe_vm_unlock(vm);
if (IS_ERR(bo)) {
KUNIT_FAIL(test, "bo create err=%pe\n", bo);
@@ -454,7 +454,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
external = xe_bo_create_user(xe, NULL, 0x10000,
DRM_XE_GEM_CPU_CACHING_WC,
- bo_flags, NULL);
+ bo_flags, NUMA_NO_NODE, NULL);
if (IS_ERR(external)) {
KUNIT_FAIL(test, "external bo create err=%pe\n", external);
goto cleanup_bo;
@@ -719,7 +719,7 @@ static int shrink_test_run_device(struct xe_device *xe)
/* We can create bos using WC caching here. But it is slower. */
bo = xe_bo_create_user(xe, NULL, XE_BO_SHRINK_SIZE,
DRM_XE_GEM_CPU_CACHING_WB,
- XE_BO_FLAG_SYSTEM, NULL);
+ XE_BO_FLAG_SYSTEM, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) &&
bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS))
diff --git a/drivers/gpu/drm/xe/tests/xe_dma_buf.c b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
index 792376e965f1..876ea545d1a7 100644
--- a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
@@ -127,7 +127,7 @@ static void xe_test_dmabuf_import_same_driver(struct xe_device *xe)
kunit_info(test, "running %s\n", __func__);
bo = xe_bo_create_user(xe, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
- params->mem_mask, NULL);
+ params->mem_mask, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
PTR_ERR(bo));
@@ -215,7 +215,7 @@ static void xe_test_dmabuf_move_notify_no_resource(struct xe_device *xe)
kunit_info(test, "running %s\n", __func__);
bo = xe_bo_create_user(xe, NULL, PAGE_SIZE, DRM_XE_GEM_CPU_CACHING_WC,
- params->mem_mask, NULL);
+ params->mem_mask, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
PTR_ERR(bo));
diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
index 56c49d8507d7..69b64e3a23b8 100644
--- a/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -649,7 +649,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
DRM_XE_GEM_CPU_CACHING_WC,
XE_BO_FLAG_SYSTEM |
XE_BO_FLAG_NEEDS_CPU_ACCESS |
- XE_BO_FLAG_PINNED, NULL);
+ XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
if (IS_ERR(sys_bo)) {
KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
@@ -675,7 +675,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
ccs_bo = xe_bo_create_user(xe, NULL, SZ_4M,
DRM_XE_GEM_CPU_CACHING_WC,
bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
- XE_BO_FLAG_PINNED, NULL);
+ XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
if (IS_ERR(ccs_bo)) {
KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
@@ -700,7 +700,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
vram_bo = xe_bo_create_user(xe, NULL, SZ_4M,
DRM_XE_GEM_CPU_CACHING_WC,
bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
- XE_BO_FLAG_PINNED, NULL);
+ XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
if (IS_ERR(vram_bo)) {
KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
PTR_ERR(vram_bo));
@@ -979,7 +979,7 @@ static void access_memory_test_run_tile(struct xe_device *xe,
bo = xe_bo_create_user(xe, NULL, ACCESS_MEM_BO_SIZE,
DRM_XE_GEM_CPU_CACHING_WC,
- bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS, NULL);
+ bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS, NUMA_NO_NODE, NULL);
if (IS_ERR(bo)) {
KUNIT_FAIL(test, "Failed to create bo: %pe\n", bo);
goto free_buf;
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index fc9bfb436b8e..bbbc33737264 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1538,7 +1538,7 @@ int xe_bo_notifier_prepare_pinned(struct xe_bo *bo)
backup = xe_bo_init_locked(xe, NULL, NULL, bo->ttm.base.resv, NULL, xe_bo_size(bo),
DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
- XE_BO_FLAG_PINNED, NULL, &exec);
+ XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE, &exec);
if (IS_ERR(backup)) {
drm_exec_retry_on_contention(&exec);
ret = PTR_ERR(backup);
@@ -1680,7 +1680,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
xe_bo_size(bo),
DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
- XE_BO_FLAG_PINNED, NULL, &exec);
+ XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE, &exec);
if (IS_ERR(backup)) {
drm_exec_retry_on_contention(&exec);
ret = PTR_ERR(backup);
@@ -2480,7 +2480,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
struct ttm_lru_bulk_move *bulk, size_t size,
u16 cpu_caching, enum ttm_bo_type type,
u32 flags, struct dma_buf *dma_buf,
- struct drm_exec *exec)
+ int numa_node, struct drm_exec *exec)
{
struct ttm_operation_ctx ctx = {
.interruptible = true,
@@ -2546,7 +2546,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
bo->tile = tile;
bo->flags = flags;
bo->cpu_caching = cpu_caching;
- bo->numa_node = NUMA_NO_NODE;
+ bo->numa_node = numa_node;
bo->ttm.base.funcs = &xe_gem_object_funcs;
bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
INIT_LIST_HEAD(&bo->pinned_link);
@@ -2681,7 +2681,7 @@ __xe_bo_create_locked(struct xe_device *xe,
struct xe_tile *tile, struct xe_vm *vm,
size_t size, u64 start, u64 end,
u16 cpu_caching, enum ttm_bo_type type, u32 flags,
- u64 alignment, struct drm_exec *exec)
+ u64 alignment, int numa_node, struct drm_exec *exec)
{
struct xe_bo *bo = NULL;
int err;
@@ -2706,7 +2706,7 @@ __xe_bo_create_locked(struct xe_device *xe,
vm && !xe_vm_in_fault_mode(vm) &&
flags & XE_BO_FLAG_USER ?
&vm->lru_bulk_move : NULL, size,
- cpu_caching, type, flags, NULL, exec);
+ cpu_caching, type, flags, NULL, numa_node, exec);
if (IS_ERR(bo))
return bo;
@@ -2781,13 +2781,13 @@ struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
struct drm_exec *exec)
{
return __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL, 0, type,
- flags, 0, exec);
+ flags, 0, NUMA_NO_NODE, exec);
}
static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *tile,
size_t size, u16 cpu_caching,
enum ttm_bo_type type, u32 flags,
- u64 alignment, bool intr)
+ u64 alignment, int numa_node, bool intr)
{
struct xe_validation_ctx ctx;
struct drm_exec exec;
@@ -2797,7 +2797,8 @@ static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *til
xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {.interruptible = intr},
ret) {
bo = __xe_bo_create_locked(xe, tile, NULL, size, 0, ~0ULL,
- cpu_caching, type, flags, alignment, &exec);
+ cpu_caching, type, flags, alignment,
+ numa_node, &exec);
drm_exec_retry_on_contention(&exec);
if (IS_ERR(bo)) {
ret = PTR_ERR(bo);
@@ -2966,7 +2967,8 @@ static void xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe,
struct xe_bo *xe_bo_create_user(struct xe_device *xe,
struct xe_vm *vm, size_t size,
u16 cpu_caching,
- u32 flags, struct drm_exec *exec)
+ u32 flags, int numa_node,
+ struct drm_exec *exec)
{
struct xe_bo *bo;
int err = 0;
@@ -2983,12 +2985,13 @@ struct xe_bo *xe_bo_create_user(struct xe_device *xe,
xe_assert(xe, exec);
bo = __xe_bo_create_locked(xe, NULL, vm, size, 0, ~0ULL,
cpu_caching, ttm_bo_type_device,
- flags, 0, exec);
+ flags, 0, numa_node, exec);
if (!IS_ERR(bo))
xe_bo_unlock_vm_held(bo);
} else {
bo = xe_bo_create_novm(xe, NULL, size, cpu_caching,
- ttm_bo_type_device, flags, 0, true);
+ ttm_bo_type_device, flags, 0,
+ numa_node, true);
}
return bo;
@@ -3022,7 +3025,7 @@ struct xe_bo *xe_bo_create_pin_range_novm(struct xe_device *xe, struct xe_tile *
xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {}, err) {
bo = __xe_bo_create_locked(xe, tile, NULL, size, start, end,
- 0, type, flags, 0, &exec);
+ 0, type, flags, 0, NUMA_NO_NODE, &exec);
if (IS_ERR(bo)) {
drm_exec_retry_on_contention(&exec);
err = PTR_ERR(bo);
@@ -3061,7 +3064,7 @@ static struct xe_bo *xe_bo_create_pin_map_at_aligned(struct xe_device *xe,
bo = __xe_bo_create_locked(xe, tile, vm, size, start, end, 0, type,
flags | XE_BO_FLAG_NEEDS_CPU_ACCESS | XE_BO_FLAG_PINNED,
- alignment, exec);
+ alignment, NUMA_NO_NODE, exec);
if (IS_ERR(bo))
return bo;
@@ -3604,10 +3607,15 @@ static int gem_create_user_ext_set_property(struct xe_device *xe,
if (XE_IOCTL_DBG(xe, err))
return -EFAULT;
+ if (XE_IOCTL_DBG(xe, ext.pad))
+ return -EINVAL;
+
+ /* The NUMA node property is parsed and applied before BO creation. */
+ if (ext.property == DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
+ return 0;
+
if (XE_IOCTL_DBG(xe, ext.property >=
- ARRAY_SIZE(gem_create_set_property_funcs)) ||
- XE_IOCTL_DBG(xe, ext.pad) ||
- XE_IOCTL_DBG(xe, ext.property != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY))
+ ARRAY_SIZE(gem_create_set_property_funcs)))
return -EINVAL;
idx = array_index_nospec(ext.property, ARRAY_SIZE(gem_create_set_property_funcs));
@@ -3658,6 +3666,56 @@ static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
return 0;
}
+/*
+ * Parse a host NUMA node request from the extension chain. The node must be
+ * known before the BO is created, because the backing pages are allocated
+ * during creation. Returns the requested node in @numa_node (NUMA_NO_NODE if
+ * none or a negative value is given) or a negative errno on an invalid request.
+ */
+static int gem_create_parse_numa_node(struct xe_device *xe, u64 extensions,
+ u32 bo_flags, int *numa_node)
+{
+ struct drm_xe_user_extension base;
+ struct drm_xe_ext_set_property ext;
+ unsigned int i = 0;
+
+ *numa_node = NUMA_NO_NODE;
+
+ while (extensions && i++ < MAX_USER_EXTENSIONS) {
+ u64 __user *address = u64_to_user_ptr(extensions);
+ s64 nid;
+
+ if (XE_IOCTL_DBG(xe, copy_from_user(&base, address, sizeof(base))))
+ return -EFAULT;
+
+ if (base.name != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY)
+ goto next;
+
+ if (XE_IOCTL_DBG(xe, copy_from_user(&ext, address, sizeof(ext))))
+ return -EFAULT;
+
+ if (ext.property != DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
+ goto next;
+
+ nid = (s64)ext.value;
+ *numa_node = NUMA_NO_NODE;
+ if (nid < 0)
+ goto next;
+
+ if (XE_IOCTL_DBG(xe, nid >= MAX_NUMNODES || !node_online(nid)))
+ return -EINVAL;
+
+ if (XE_IOCTL_DBG(xe, !(bo_flags & XE_BO_FLAG_SYSTEM)))
+ return -EINVAL;
+
+ *numa_node = nid;
+next:
+ extensions = base.next_extension;
+ }
+
+ return 0;
+}
+
int xe_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -3669,6 +3727,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
struct xe_vm *vm = NULL;
struct xe_bo *bo;
unsigned int bo_flags;
+ int numa_node;
u32 handle;
int err;
@@ -3744,6 +3803,11 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
args->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
return -EINVAL;
+ err = gem_create_parse_numa_node(xe, args->extensions, bo_flags,
+ &numa_node);
+ if (err)
+ return err;
+
if (args->vm_id) {
vm = xe_vm_lookup(xef, args->vm_id);
if (XE_IOCTL_DBG(xe, !vm))
@@ -3760,7 +3824,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
break;
}
bo = xe_bo_create_user(xe, vm, args->size, args->cpu_caching,
- bo_flags, &exec);
+ bo_flags, numa_node, &exec);
drm_exec_retry_on_contention(&exec);
if (IS_ERR(bo)) {
err = PTR_ERR(bo);
@@ -4231,7 +4295,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_NEEDS_CPU_ACCESS, NULL);
+ XE_BO_FLAG_NEEDS_CPU_ACCESS, NUMA_NO_NODE, 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 77b3a02e9b8e..225c6a8676a6 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -122,13 +122,14 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
struct ttm_lru_bulk_move *bulk, size_t size,
u16 cpu_caching, enum ttm_bo_type type,
u32 flags, struct dma_buf *dma_buf,
- struct drm_exec *exec);
+ int numa_node, struct drm_exec *exec);
struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
struct xe_vm *vm, size_t size,
enum ttm_bo_type type, u32 flags,
struct drm_exec *exec);
struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_vm *vm, size_t size,
- u16 cpu_caching, u32 flags, struct drm_exec *exec);
+ u16 cpu_caching, u32 flags, int numa_node,
+ struct drm_exec *exec);
struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct xe_tile *tile,
struct xe_vm *vm, size_t size,
enum ttm_bo_type type, u32 flags,
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index 5bf13dc4b61d..b5351310a07b 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -343,7 +343,8 @@ xe_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
bo = xe_bo_init_locked(xe, NULL, NULL, resv, NULL, dma_buf->size,
0, /* Will require 1way or 2way for vm_bind */
- ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf, &exec);
+ ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf,
+ NUMA_NO_NODE, &exec);
drm_exec_retry_on_contention(&exec);
if (IS_ERR(bo)) {
ret = PTR_ERR(bo);
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers
2026-11-02 10:18 ` [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers Himal Prasad Ghimiray
@ 2026-11-02 10:26 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-11-02 10:26 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: dri-devel, intel-xe
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] drm/ttm: unused helper and EXPORT_SYMBOL() on ttm_pool_restore_and_alloc()
--
commit 8d0a6d62696c67cc37673b025155aa37dad8e6a7
Author: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
drm/ttm: Add NUMA node aware restore helpers
This commit introduces ttm_tt_restore_node() and
ttm_pool_restore_and_alloc_node() so callers can preserve a specific NUMA
node placement when restoring backed-up TTM pages.
> diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> index 54d2f6b5c229c..2107dc6c69b36 100644
> --- a/drivers/gpu/drm/ttm/ttm_pool.c
> +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> @@ -962,6 +962,30 @@ EXPORT_SYMBOL(ttm_pool_alloc_node);
> */
> int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> const struct ttm_operation_ctx *ctx)
> +{
> + return ttm_pool_restore_and_alloc_node(pool, tt, ctx, NUMA_NO_NODE);
> +}
> +EXPORT_SYMBOL(ttm_pool_restore_and_alloc);
[Severity: Low]
Is ttm_pool_restore_and_alloc() still needed now that ttm_tt_restore() in
drivers/gpu/drm/ttm/ttm_tt.c delegates to ttm_tt_restore_node(), which
calls ttm_pool_restore_and_alloc_node() directly?
Previously, ttm_pool_restore_and_alloc() was an unexported TTM-internal
helper whose only caller was ttm_tt_restore(), and external drivers cannot
call it directly because only ttm_tt_restore() and ttm_tt_restore_node()
clear TTM_TT_FLAG_BACKED_UP on tt->page_flags. With ttm_tt_restore()
switched over to ttm_tt_restore_node(), ttm_pool_restore_and_alloc() has no
remaining callers in the tree, yet it is kept and newly exported with
EXPORT_SYMBOL().
Should ttm_pool_restore_and_alloc() and its EXPORT_SYMBOL() be dropped (or
kept unexported if there is a planned internal user)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102101803.455921-9-himal.prasad.ghimiray@intel.com?part=2
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
@ 2026-11-02 10:26 ` sashiko-bot
2026-11-02 10:50 ` Christian König
1 sibling, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-11-02 10:26 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: dri-devel, intel-xe
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] drm/ttm: high-order alloc failure on memoryless nodes in ttm_pool_nid()
- [Low] drm/ttm: code duplication and doc mismatch in ttm_pool_alloc_node()
--
commit 7c445098356d9efa9b5af93394f82d04655f28ad
Author: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
This commit adds ttm_pool_alloc_node() to allow callers to specify a NUMA
node when allocating backing pages for a ttm_tt object, while rejecting
explicit NUMA node requests on pools that use dma_alloc_attrs().
> diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> index 1bf37023fed66..54d2f6b5c229c 100644
> --- a/drivers/gpu/drm/ttm/ttm_pool.c
> +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> @@ -158,9 +158,9 @@ static int ttm_pool_nid(struct ttm_pool *pool)
> return nid;
> }
>
> -/* Allocate pages of size 1 << order with the given gfp_flags */
> +/* Allocate pages of size 1 << order with the given gfp_flags on node @nid */
> static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
> - unsigned int order)
> + unsigned int order, int nid)
> {
> const unsigned int beneficial_order = ttm_pool_beneficial_order(pool);
> unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
> @@ -189,7 +189,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
> }
>
> if (!ttm_pool_uses_dma_alloc(pool)) {
> - p = alloc_pages_node(pool->nid, gfp_flags, order);
> + p = alloc_pages_node(nid, gfp_flags, order);
[Severity: Medium]
Can resolving NUMA_NO_NODE via ttm_pool_nid() before calling
alloc_pages_node() cause higher-order allocations to fail on memoryless CPU
NUMA nodes (CONFIG_HAVE_MEMORYLESS_NODES)?
Previously, ttm_pool_alloc_page() passed pool->nid directly to
alloc_pages_node(). When pool->nid was NUMA_NO_NODE,
alloc_pages_node_noprof() translated NUMA_NO_NODE to numa_mem_id() (the
nearest NUMA node with memory).
With this change, ttm_pool_alloc(), ttm_pool_alloc_node() (when nid is
NUMA_NO_NODE), and ttm_pool_restore_and_alloc() resolve nid up front via
ttm_pool_nid():
drivers/gpu/drm/ttm/ttm_pool.c:ttm_pool_nid() {
int nid = NUMA_NO_NODE;
if (pool)
nid = pool->nid;
if (nid == NUMA_NO_NODE)
nid = numa_node_id();
return nid;
}
In ttm_pool_alloc_page(), allocations with order > 0 set __GFP_THISNODE in
gfp_flags:
if (order)
gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN |
__GFP_THISNODE;
Because alloc_pages_node() now receives numa_node_id() instead of
NUMA_NO_NODE, it no longer substitutes numa_mem_id(). When running on a CPU
attached to a memoryless NUMA node, ZONELIST_NOFALLBACK has no memory zones,
causing all order > 0 allocations to fail and fall back to order 0.
In addition, any order-0 WC/UC pages allocated via fallback will reside on a
memory-bearing node (page_to_nid(p) != numa_node_id()), so
ttm_pool_type_give() places them on page_to_nid(p)'s list_lru while
ttm_pool_type_take(pt, nid) searches the empty list_lru of the memoryless
numa_node_id().
Should ttm_pool_nid() use numa_mem_id() instead of numa_node_id() when nid is
NUMA_NO_NODE?
[ ... ]
> @@ -900,10 +901,52 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
>
> ttm_pool_alloc_state_init(tt, &alloc);
>
> - return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL);
> + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, ttm_pool_nid(pool));
> }
> EXPORT_SYMBOL(ttm_pool_alloc);
>
> +/**
> + * ttm_pool_alloc_node - Fill a ttm_tt object, placing pages on a given node
> + *
> + * @pool: ttm_pool to use
> + * @tt: ttm_tt object to fill
> + * @ctx: operation context
> + * @nid: NUMA node id to allocate the backing system pages from, or
> + * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
> + *
> + * Like ttm_pool_alloc(), but allows the caller to override the NUMA node the
> + * backing system pages are allocated from. This only affects the
> + * non-coherent (non dma-alloc) allocation path; coherent/dma pools continue
> + * to use the device-local node. Intended for drivers that expose a
> + * user-selectable host memory NUMA placement.
> + *
> + * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a coherent/dma
> + * pool, negative error code otherwise.
> + */
> +int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
> + struct ttm_operation_ctx *ctx, int nid)
> +{
> + struct ttm_pool_alloc_state alloc;
> +
> + if (WARN_ON(ttm_tt_is_backed_up(tt)))
> + return -EINVAL;
> +
> + /*
> + * Coherent/dma pools allocate via dma_alloc_attrs(), which places pages
> + * per device DMA constraints and cannot honor a caller-requested node.
> + */
> + if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
> + return -EOPNOTSUPP;
> +
> + if (nid == NUMA_NO_NODE)
> + nid = ttm_pool_nid(pool);
> +
> + ttm_pool_alloc_state_init(tt, &alloc);
> +
> + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, nid);
> +}
> +EXPORT_SYMBOL(ttm_pool_alloc_node);
[Severity: Low]
This isn't a bug, but there are a couple of inconsistencies between the
documentation, the commit message, and the implementation here.
First, the kernel-doc description for ttm_pool_alloc_node() states that
"coherent/dma pools continue to use the device-local node", which contradicts
both the Returns section ("-EOPNOTSUPP if @nid is specified on a coherent/dma
pool") and the implementation when nid != NUMA_NO_NODE.
Second, the commit message mentions that "ttm_pool_alloc() passes
NUMA_NO_NODE, keeping current behaviour" and that "__ttm_pool_alloc(),
ttm_pool_alloc_page(), ttm_pool_type_take() already take a nid", whereas this
patch adds the nid parameter to __ttm_pool_alloc() and ttm_pool_alloc_page(),
and ttm_pool_alloc() duplicates the setup and calls __ttm_pool_alloc()
directly.
Could ttm_pool_alloc() simply call ttm_pool_alloc_node(pool, tt, ctx,
NUMA_NO_NODE), and the kernel-doc and commit message be updated to match?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102101803.455921-9-himal.prasad.ghimiray@intel.com?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property
2026-11-02 10:18 ` [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property Himal Prasad Ghimiray
@ 2026-11-02 10:27 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-11-02 10:27 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: dri-devel, intel-xe
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] drm/xe/uapi: inaccurate comment and missing kernel-doc for NUMA_NODE property
--
commit 3afc5386219df9a82a534e249ba21444e34868d6
Author: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
drm/xe/uapi: Add GEM_CREATE NUMA node placement property
This commit adds the DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE property to
struct drm_xe_gem_create so userspace can specify the host NUMA node for
system-memory buffer objects.
> diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
> index 578f0c1eb43e8..0b39081330eeb 100644
> --- a/include/uapi/drm/xe_drm.h
> +++ b/include/uapi/drm/xe_drm.h
> @@ -843,6 +843,13 @@ struct drm_xe_device_query {
> struct drm_xe_gem_create {
> #define DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY 0
> #define DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE 0
> + /*
> + * Host NUMA node (as a signed value) to allocate system-memory
> + * backing pages from. Only honored for objects with a system-memory
> + * placement; ignored for VRAM-only objects. Use a value < 0 to keep
> + * the default device-local placement.
> + */
> +#define DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE 1
[Severity: Low]
In the follow-up commit ("drm/xe/uapi: Wire up GEM_CREATE NUMA node placement
handler"), gem_create_parse_numa_node() in drivers/gpu/drm/xe/xe_bo.c checks
whether XE_BO_FLAG_SYSTEM is set and returns -EINVAL when a non-negative NUMA
node is requested on a VRAM-only BO, rather than ignoring the property. Should
this comment say that specifying a NUMA node is rejected for VRAM-only objects
instead of ignored?
Also, struct drm_xe_gem_create documents its
DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY properties in the kernel-doc comment
block above the struct definition alongside
DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE so that they are included in
Documentation/gpu/driver-uapi.rst. Should the description for
DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE be moved into that kernel-doc list
above struct drm_xe_gem_create?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102101803.455921-9-himal.prasad.ghimiray@intel.com?part=6
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
2026-11-02 10:18 ` [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler Himal Prasad Ghimiray
@ 2026-11-02 10:29 ` sashiko-bot
2026-11-02 11:12 ` Matthew Auld
1 sibling, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-11-02 10:29 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: dri-devel, intel-xe
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] drm/xe: UAPI mismatch for VRAM-only BOs in gem_create_parse_numa_node()
- [Low] drm/xe: missing numa_node kernel-doc in xe_bo_init_locked()
--
commit 4dfdcc93fc9d778a45958834231a36c288d379fc
Author: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
This commit parses the DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE user
extension prior to BO creation in xe_gem_create_ioctl() and passes the
requested NUMA node ID down through the BO creation helpers to store on
the xe_bo.
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index fc9bfb436b8e7..bbbc337372641 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
[ ... ]
> @@ -2480,7 +2480,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
> struct ttm_lru_bulk_move *bulk, size_t size,
> u16 cpu_caching, enum ttm_bo_type type,
> u32 flags, struct dma_buf *dma_buf,
> - struct drm_exec *exec)
> + int numa_node, struct drm_exec *exec)
> {
[ ... ]
> @@ -2966,7 +2967,8 @@ static void xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe,
> struct xe_bo *xe_bo_create_user(struct xe_device *xe,
> struct xe_vm *vm, size_t size,
> u16 cpu_caching,
> - u32 flags, struct drm_exec *exec)
> + u32 flags, int numa_node,
> + struct drm_exec *exec)
> {
[Severity: Low]
This isn't a bug, but both xe_bo_init_locked() and xe_bo_create_user() have
kernel-doc comment blocks immediately above their definitions. Should
@numa_node be added to both kernel-doc blocks to avoid W=1 kernel-doc
warnings for undescribed function parameters?
[ ... ]
> @@ -3658,6 +3666,56 @@ static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
> return 0;
> }
>
> +/*
> + * Parse a host NUMA node request from the extension chain. The node must be
> + * known before the BO is created, because the backing pages are allocated
> + * during creation. Returns the requested node in @numa_node (NUMA_NO_NODE if
> + * none or a negative value is given) or a negative errno on an invalid request.
> + */
> +static int gem_create_parse_numa_node(struct xe_device *xe, u64 extensions,
> + u32 bo_flags, int *numa_node)
> +{
> + struct drm_xe_user_extension base;
> + struct drm_xe_ext_set_property ext;
> + unsigned int i = 0;
> +
> + *numa_node = NUMA_NO_NODE;
> +
> + while (extensions && i++ < MAX_USER_EXTENSIONS) {
> + u64 __user *address = u64_to_user_ptr(extensions);
> + s64 nid;
> +
> + if (XE_IOCTL_DBG(xe, copy_from_user(&base, address, sizeof(base))))
> + return -EFAULT;
> +
> + if (base.name != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY)
> + goto next;
> +
> + if (XE_IOCTL_DBG(xe, copy_from_user(&ext, address, sizeof(ext))))
> + return -EFAULT;
> +
> + if (ext.property != DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
> + goto next;
> +
> + nid = (s64)ext.value;
> + *numa_node = NUMA_NO_NODE;
> + if (nid < 0)
> + goto next;
> +
> + if (XE_IOCTL_DBG(xe, nid >= MAX_NUMNODES || !node_online(nid)))
> + return -EINVAL;
> +
> + if (XE_IOCTL_DBG(xe, !(bo_flags & XE_BO_FLAG_SYSTEM)))
> + return -EINVAL;
> +
> + *numa_node = nid;
> +next:
> + extensions = base.next_extension;
> + }
> +
> + return 0;
> +}
[Severity: Medium]
Does rejecting !(bo_flags & XE_BO_FLAG_SYSTEM) with -EINVAL in
xe_gem_create_ioctl() -> gem_create_parse_numa_node() match the UAPI
contract in include/uapi/drm/xe_drm.h?
In struct drm_xe_gem_create, the comment for
DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE states:
/*
* Host NUMA node (as a signed value) to allocate system-memory
* backing pages from. Only honored for objects with a system-memory
* placement; ignored for VRAM-only objects. Use a value < 0 to keep
* the default device-local placement.
*/
#define DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE 1
However, gem_create_parse_numa_node() returns -EINVAL when nid >= 0 and
!(bo_flags & XE_BO_FLAG_SYSTEM) instead of ignoring the property on
VRAM-only objects.
In addition, because nid < 0 jumps to next before reaching the
!(bo_flags & XE_BO_FLAG_SYSTEM) check, a VRAM-only BO with nid < 0 is
accepted while nid >= 0 fails with -EINVAL, and an extension chain on a
VRAM-only BO that sets nid >= 0 followed by a later extension resetting
nid = -1 will fail on the first extension.
Should the UAPI comment and gem_create_parse_numa_node() be aligned on
whether VRAM-only BOs ignore DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE or
reject it with -EINVAL?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102101803.455921-9-himal.prasad.ghimiray@intel.com?part=7
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
2026-11-02 10:26 ` sashiko-bot
@ 2026-11-02 10:50 ` Christian König
2026-11-02 12:46 ` Thomas Hellström
1 sibling, 1 reply; 19+ messages in thread
From: Christian König @ 2026-11-02 10:50 UTC (permalink / raw)
To: Himal Prasad Ghimiray, Huang Rui, Thomas Hellström,
Rodrigo Vivi, Natalie Vock, Paneer Selvam, Arunpravin
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe
First of all please add Natalie and Arun on TTM patches, they are the maintainers of that component now.
On 11/2/26 11:18, Himal Prasad Ghimiray wrote:
> ttm_pool_alloc() always allocates on the pool's default node, although
> the internal TTM helpers (__ttm_pool_alloc(), ttm_pool_alloc_page(),
> ttm_pool_type_take()) already take a nid. Add ttm_pool_alloc_node() to
> let a driver pass that nid for a specific tt.
>
> ttm_pool_alloc() passes NUMA_NO_NODE, keeping current behaviour. An
> explicit node on a dma_alloc pool returns -EOPNOTSUPP, as
> dma_alloc_attrs() can't honor it.
We already have an interface for NUMA node aware allocations in the TTM pool.
I don't mind changing/improving that when necessary, but that here is only adding a second path and therfore a clear NO-GO from my side.
If you want to change the nid from ttm_pool_init() to ttm_pool_alloc() then change all existing users.
Regards,
Christian.
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/ttm/ttm_pool.c | 59 +++++++++++++++++++++++++++++-----
> include/drm/ttm/ttm_pool.h | 2 ++
> 2 files changed, 53 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
> index 1bf37023fed6..54d2f6b5c229 100644
> --- a/drivers/gpu/drm/ttm/ttm_pool.c
> +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> @@ -158,9 +158,9 @@ static int ttm_pool_nid(struct ttm_pool *pool)
> return nid;
> }
>
> -/* Allocate pages of size 1 << order with the given gfp_flags */
> +/* Allocate pages of size 1 << order with the given gfp_flags on node @nid */
> static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
> - unsigned int order)
> + unsigned int order, int nid)
> {
> const unsigned int beneficial_order = ttm_pool_beneficial_order(pool);
> unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
> @@ -189,7 +189,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
> }
>
> if (!ttm_pool_uses_dma_alloc(pool)) {
> - p = alloc_pages_node(pool->nid, gfp_flags, order);
> + p = alloc_pages_node(nid, gfp_flags, order);
> if (p) {
> p->private = order;
> mod_lruvec_page_state(p, NR_GPU_ACTIVE, 1 << order);
> @@ -783,7 +783,8 @@ static unsigned int ttm_pool_alloc_find_order(unsigned int highest,
> static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> const struct ttm_operation_ctx *ctx,
> struct ttm_pool_alloc_state *alloc,
> - struct ttm_pool_tt_restore *restore)
> + struct ttm_pool_tt_restore *restore,
> + int nid)
> {
> enum ttm_caching page_caching;
> gfp_t gfp_flags = GFP_USER;
> @@ -818,7 +819,7 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> p = NULL;
> pt = ttm_pool_select_type(pool, page_caching, order);
> if (pt && allow_pools)
> - p = ttm_pool_type_take(pt, ttm_pool_nid(pool));
> + p = ttm_pool_type_take(pt, nid);
>
> /*
> * If that fails or previously failed, allocate from system.
> @@ -829,7 +830,7 @@ static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> if (!p) {
> page_caching = ttm_cached;
> allow_pools = false;
> - p = ttm_pool_alloc_page(pool, gfp_flags, order);
> + p = ttm_pool_alloc_page(pool, gfp_flags, order, nid);
> }
> /* If that fails, lower the order if possible and retry. */
> if (!p) {
> @@ -900,10 +901,52 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
>
> ttm_pool_alloc_state_init(tt, &alloc);
>
> - return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL);
> + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, ttm_pool_nid(pool));
> }
> EXPORT_SYMBOL(ttm_pool_alloc);
>
> +/**
> + * ttm_pool_alloc_node - Fill a ttm_tt object, placing pages on a given node
> + *
> + * @pool: ttm_pool to use
> + * @tt: ttm_tt object to fill
> + * @ctx: operation context
> + * @nid: NUMA node id to allocate the backing system pages from, or
> + * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
> + *
> + * Like ttm_pool_alloc(), but allows the caller to override the NUMA node the
> + * backing system pages are allocated from. This only affects the
> + * non-coherent (non dma-alloc) allocation path; coherent/dma pools continue
> + * to use the device-local node. Intended for drivers that expose a
> + * user-selectable host memory NUMA placement.
> + *
> + * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a coherent/dma
> + * pool, negative error code otherwise.
> + */
> +int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
> + struct ttm_operation_ctx *ctx, int nid)
> +{
> + struct ttm_pool_alloc_state alloc;
> +
> + if (WARN_ON(ttm_tt_is_backed_up(tt)))
> + return -EINVAL;
> +
> + /*
> + * Coherent/dma pools allocate via dma_alloc_attrs(), which places pages
> + * per device DMA constraints and cannot honor a caller-requested node.
> + */
> + if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
> + return -EOPNOTSUPP;
> +
> + if (nid == NUMA_NO_NODE)
> + nid = ttm_pool_nid(pool);
> +
> + ttm_pool_alloc_state_init(tt, &alloc);
> +
> + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, nid);
> +}
> +EXPORT_SYMBOL(ttm_pool_alloc_node);
> +
> /**
> * ttm_pool_restore_and_alloc - Fill a ttm_tt, restoring previously backed-up
> * content.
> @@ -964,7 +1007,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> }
> }
>
> - return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore);
> + return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, ttm_pool_nid(pool));
> }
>
> /**
> diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h
> index 26ee592e1994..6a0b14aca092 100644
> --- a/include/drm/ttm/ttm_pool.h
> +++ b/include/drm/ttm/ttm_pool.h
> @@ -79,6 +79,8 @@ struct ttm_pool {
>
> int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> struct ttm_operation_ctx *ctx);
> +int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
> + struct ttm_operation_ctx *ctx, int nid);
> void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt);
>
> void ttm_pool_init(struct ttm_pool *pool, struct device *dev,
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
2026-11-02 10:18 ` [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler Himal Prasad Ghimiray
2026-11-02 10:29 ` sashiko-bot
@ 2026-11-02 11:12 ` Matthew Auld
2026-11-02 18:24 ` Himal prasad Ghimiray
1 sibling, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2026-11-02 11:12 UTC (permalink / raw)
To: Himal Prasad Ghimiray, Christian König, Huang Rui,
Thomas Hellström, Rodrigo Vivi
Cc: Matthew Brost, dri-devel, intel-xe
On 02/11/2026 10:18, Himal Prasad Ghimiray wrote:
> Parse the NUMA node property before BO creation and store it on the BO.
> Offline or out of range nodes, and BOs without a system memory
> placement, are rejected with -EINVAL.
>
> Drop the explicit DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY check, already
> covered by the property bounds check.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/tests/xe_bo.c | 12 +--
> drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 +-
> drivers/gpu/drm/xe/tests/xe_migrate.c | 8 +-
> drivers/gpu/drm/xe/xe_bo.c | 102 +++++++++++++++++++++-----
> drivers/gpu/drm/xe/xe_bo.h | 5 +-
> drivers/gpu/drm/xe/xe_dma_buf.c | 3 +-
> 6 files changed, 100 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
> index 6a17e13d58cf..6f61f5c618f1 100644
> --- a/drivers/gpu/drm/xe/tests/xe_bo.c
> +++ b/drivers/gpu/drm/xe/tests/xe_bo.c
> @@ -89,7 +89,7 @@ static void run_only_leaf(struct kunit *test,
>
> bo = xe_bo_create_user(xe, NULL, li->alloc_size,
> DRM_XE_GEM_CPU_CACHING_WC,
> - XE_BO_FLAG_VRAM0, NULL);
> + XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> page_size_alloc_restore(xe, &saved);
> if (PTR_ERR(bo) == -ENOSPC) {
> @@ -183,7 +183,7 @@ static void xe_bo_page_size_alloc_mixed_bos(struct kunit *test)
> */
> bo = xe_bo_create_user(xe, NULL, SZ_1G,
> DRM_XE_GEM_CPU_CACHING_WC,
> - XE_BO_FLAG_VRAM0, NULL);
> + XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> int err = PTR_ERR(bo);
>
> @@ -366,7 +366,7 @@ static void ccs_test_run_tile(struct xe_device *xe, struct xe_tile *tile,
> kunit_info(test, "Testing system memory\n");
>
> bo = xe_bo_create_user(xe, NULL, SZ_1M, DRM_XE_GEM_CPU_CACHING_WC,
> - bo_flags, exec);
> + bo_flags, NUMA_NO_NODE, exec);
> if (IS_ERR(bo)) {
> KUNIT_FAIL(test, "Failed to create bo.\n");
> return;
> @@ -445,7 +445,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
> xe_vm_lock(vm, false);
> bo = xe_bo_create_user(xe, vm, 0x10000,
> DRM_XE_GEM_CPU_CACHING_WC,
> - bo_flags, exec);
> + bo_flags, NUMA_NO_NODE, exec);
> xe_vm_unlock(vm);
> if (IS_ERR(bo)) {
> KUNIT_FAIL(test, "bo create err=%pe\n", bo);
> @@ -454,7 +454,7 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
>
> external = xe_bo_create_user(xe, NULL, 0x10000,
> DRM_XE_GEM_CPU_CACHING_WC,
> - bo_flags, NULL);
> + bo_flags, NUMA_NO_NODE, NULL);
> if (IS_ERR(external)) {
> KUNIT_FAIL(test, "external bo create err=%pe\n", external);
> goto cleanup_bo;
> @@ -719,7 +719,7 @@ static int shrink_test_run_device(struct xe_device *xe)
> /* We can create bos using WC caching here. But it is slower. */
> bo = xe_bo_create_user(xe, NULL, XE_BO_SHRINK_SIZE,
> DRM_XE_GEM_CPU_CACHING_WB,
> - XE_BO_FLAG_SYSTEM, NULL);
> + XE_BO_FLAG_SYSTEM, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) &&
> bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS))
> diff --git a/drivers/gpu/drm/xe/tests/xe_dma_buf.c b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
> index 792376e965f1..876ea545d1a7 100644
> --- a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
> +++ b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
> @@ -127,7 +127,7 @@ static void xe_test_dmabuf_import_same_driver(struct xe_device *xe)
>
> kunit_info(test, "running %s\n", __func__);
> bo = xe_bo_create_user(xe, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
> - params->mem_mask, NULL);
> + params->mem_mask, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
> PTR_ERR(bo));
> @@ -215,7 +215,7 @@ static void xe_test_dmabuf_move_notify_no_resource(struct xe_device *xe)
>
> kunit_info(test, "running %s\n", __func__);
> bo = xe_bo_create_user(xe, NULL, PAGE_SIZE, DRM_XE_GEM_CPU_CACHING_WC,
> - params->mem_mask, NULL);
> + params->mem_mask, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
> PTR_ERR(bo));
> diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
> index 56c49d8507d7..69b64e3a23b8 100644
> --- a/drivers/gpu/drm/xe/tests/xe_migrate.c
> +++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
> @@ -649,7 +649,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
> DRM_XE_GEM_CPU_CACHING_WC,
> XE_BO_FLAG_SYSTEM |
> XE_BO_FLAG_NEEDS_CPU_ACCESS |
> - XE_BO_FLAG_PINNED, NULL);
> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
>
> if (IS_ERR(sys_bo)) {
> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
> @@ -675,7 +675,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
> ccs_bo = xe_bo_create_user(xe, NULL, SZ_4M,
> DRM_XE_GEM_CPU_CACHING_WC,
> bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
> - XE_BO_FLAG_PINNED, NULL);
> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
>
> if (IS_ERR(ccs_bo)) {
> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
> @@ -700,7 +700,7 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
> vram_bo = xe_bo_create_user(xe, NULL, SZ_4M,
> DRM_XE_GEM_CPU_CACHING_WC,
> bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
> - XE_BO_FLAG_PINNED, NULL);
> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
> if (IS_ERR(vram_bo)) {
> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
> PTR_ERR(vram_bo));
> @@ -979,7 +979,7 @@ static void access_memory_test_run_tile(struct xe_device *xe,
>
> bo = xe_bo_create_user(xe, NULL, ACCESS_MEM_BO_SIZE,
> DRM_XE_GEM_CPU_CACHING_WC,
> - bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS, NULL);
> + bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS, NUMA_NO_NODE, NULL);
> if (IS_ERR(bo)) {
> KUNIT_FAIL(test, "Failed to create bo: %pe\n", bo);
> goto free_buf;
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index fc9bfb436b8e..bbbc33737264 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
> @@ -1538,7 +1538,7 @@ int xe_bo_notifier_prepare_pinned(struct xe_bo *bo)
> backup = xe_bo_init_locked(xe, NULL, NULL, bo->ttm.base.resv, NULL, xe_bo_size(bo),
> DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
> XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
> - XE_BO_FLAG_PINNED, NULL, &exec);
> + XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE, &exec);
> if (IS_ERR(backup)) {
> drm_exec_retry_on_contention(&exec);
> ret = PTR_ERR(backup);
> @@ -1680,7 +1680,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
> xe_bo_size(bo),
> DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
> XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
> - XE_BO_FLAG_PINNED, NULL, &exec);
> + XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE, &exec);
> if (IS_ERR(backup)) {
> drm_exec_retry_on_contention(&exec);
> ret = PTR_ERR(backup);
> @@ -2480,7 +2480,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
> struct ttm_lru_bulk_move *bulk, size_t size,
> u16 cpu_caching, enum ttm_bo_type type,
> u32 flags, struct dma_buf *dma_buf,
> - struct drm_exec *exec)
> + int numa_node, struct drm_exec *exec)
> {
> struct ttm_operation_ctx ctx = {
> .interruptible = true,
> @@ -2546,7 +2546,7 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
> bo->tile = tile;
> bo->flags = flags;
> bo->cpu_caching = cpu_caching;
> - bo->numa_node = NUMA_NO_NODE;
> + bo->numa_node = numa_node;
> bo->ttm.base.funcs = &xe_gem_object_funcs;
> bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
> INIT_LIST_HEAD(&bo->pinned_link);
> @@ -2681,7 +2681,7 @@ __xe_bo_create_locked(struct xe_device *xe,
> struct xe_tile *tile, struct xe_vm *vm,
> size_t size, u64 start, u64 end,
> u16 cpu_caching, enum ttm_bo_type type, u32 flags,
> - u64 alignment, struct drm_exec *exec)
> + u64 alignment, int numa_node, struct drm_exec *exec)
> {
> struct xe_bo *bo = NULL;
> int err;
> @@ -2706,7 +2706,7 @@ __xe_bo_create_locked(struct xe_device *xe,
> vm && !xe_vm_in_fault_mode(vm) &&
> flags & XE_BO_FLAG_USER ?
> &vm->lru_bulk_move : NULL, size,
> - cpu_caching, type, flags, NULL, exec);
> + cpu_caching, type, flags, NULL, numa_node, exec);
> if (IS_ERR(bo))
> return bo;
>
> @@ -2781,13 +2781,13 @@ struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
> struct drm_exec *exec)
> {
> return __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL, 0, type,
> - flags, 0, exec);
> + flags, 0, NUMA_NO_NODE, exec);
> }
>
> static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *tile,
> size_t size, u16 cpu_caching,
> enum ttm_bo_type type, u32 flags,
> - u64 alignment, bool intr)
> + u64 alignment, int numa_node, bool intr)
> {
> struct xe_validation_ctx ctx;
> struct drm_exec exec;
> @@ -2797,7 +2797,8 @@ static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *til
> xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {.interruptible = intr},
> ret) {
> bo = __xe_bo_create_locked(xe, tile, NULL, size, 0, ~0ULL,
> - cpu_caching, type, flags, alignment, &exec);
> + cpu_caching, type, flags, alignment,
> + numa_node, &exec);
> drm_exec_retry_on_contention(&exec);
> if (IS_ERR(bo)) {
> ret = PTR_ERR(bo);
> @@ -2966,7 +2967,8 @@ static void xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe,
> struct xe_bo *xe_bo_create_user(struct xe_device *xe,
> struct xe_vm *vm, size_t size,
> u16 cpu_caching,
> - u32 flags, struct drm_exec *exec)
> + u32 flags, int numa_node,
> + struct drm_exec *exec)
> {
> struct xe_bo *bo;
> int err = 0;
> @@ -2983,12 +2985,13 @@ struct xe_bo *xe_bo_create_user(struct xe_device *xe,
> xe_assert(xe, exec);
> bo = __xe_bo_create_locked(xe, NULL, vm, size, 0, ~0ULL,
> cpu_caching, ttm_bo_type_device,
> - flags, 0, exec);
> + flags, 0, numa_node, exec);
> if (!IS_ERR(bo))
> xe_bo_unlock_vm_held(bo);
> } else {
> bo = xe_bo_create_novm(xe, NULL, size, cpu_caching,
> - ttm_bo_type_device, flags, 0, true);
> + ttm_bo_type_device, flags, 0,
> + numa_node, true);
> }
>
> return bo;
> @@ -3022,7 +3025,7 @@ struct xe_bo *xe_bo_create_pin_range_novm(struct xe_device *xe, struct xe_tile *
>
> xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {}, err) {
> bo = __xe_bo_create_locked(xe, tile, NULL, size, start, end,
> - 0, type, flags, 0, &exec);
> + 0, type, flags, 0, NUMA_NO_NODE, &exec);
> if (IS_ERR(bo)) {
> drm_exec_retry_on_contention(&exec);
> err = PTR_ERR(bo);
> @@ -3061,7 +3064,7 @@ static struct xe_bo *xe_bo_create_pin_map_at_aligned(struct xe_device *xe,
>
> bo = __xe_bo_create_locked(xe, tile, vm, size, start, end, 0, type,
> flags | XE_BO_FLAG_NEEDS_CPU_ACCESS | XE_BO_FLAG_PINNED,
> - alignment, exec);
> + alignment, NUMA_NO_NODE, exec);
> if (IS_ERR(bo))
> return bo;
>
> @@ -3604,10 +3607,15 @@ static int gem_create_user_ext_set_property(struct xe_device *xe,
> if (XE_IOCTL_DBG(xe, err))
> return -EFAULT;
>
> + if (XE_IOCTL_DBG(xe, ext.pad))
> + return -EINVAL;
> +
> + /* The NUMA node property is parsed and applied before BO creation. */
> + if (ext.property == DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
> + return 0;
> +
> if (XE_IOCTL_DBG(xe, ext.property >=
> - ARRAY_SIZE(gem_create_set_property_funcs)) ||
> - XE_IOCTL_DBG(xe, ext.pad) ||
> - XE_IOCTL_DBG(xe, ext.property != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY))
> + ARRAY_SIZE(gem_create_set_property_funcs)))
> return -EINVAL;
>
> idx = array_index_nospec(ext.property, ARRAY_SIZE(gem_create_set_property_funcs));
> @@ -3658,6 +3666,56 @@ static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
> return 0;
> }
>
> +/*
> + * Parse a host NUMA node request from the extension chain. The node must be
> + * known before the BO is created, because the backing pages are allocated
> + * during creation. Returns the requested node in @numa_node (NUMA_NO_NODE if
> + * none or a negative value is given) or a negative errno on an invalid request.
Would it make sense to rework this and have something like:
struct gem_create_extension_data {
u32 pxp_key_instance;
int numa_node;
}
Which is parsed up front before the bo create? And then in some way we
just pass that along to create_user() or manual bo init after? Otherwise
here we look to be open coding a duplicate extension parser flow, rather
than using gem_create_set_property_funcs? I think parsing before bo
create make more sense anyway, like you do here?
> + */
> +static int gem_create_parse_numa_node(struct xe_device *xe, u64 extensions,
> + u32 bo_flags, int *numa_node)
> +{
> + struct drm_xe_user_extension base;
> + struct drm_xe_ext_set_property ext;
> + unsigned int i = 0;
> +
> + *numa_node = NUMA_NO_NODE;
> +
> + while (extensions && i++ < MAX_USER_EXTENSIONS) {
> + u64 __user *address = u64_to_user_ptr(extensions);
> + s64 nid;
> +
> + if (XE_IOCTL_DBG(xe, copy_from_user(&base, address, sizeof(base))))
> + return -EFAULT;
> +
> + if (base.name != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY)
> + goto next;
> +
> + if (XE_IOCTL_DBG(xe, copy_from_user(&ext, address, sizeof(ext))))
> + return -EFAULT;
> +
> + if (ext.property != DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
> + goto next;
> +
> + nid = (s64)ext.value;
> + *numa_node = NUMA_NO_NODE;
> + if (nid < 0)
> + goto next;
> +
> + if (XE_IOCTL_DBG(xe, nid >= MAX_NUMNODES || !node_online(nid)))
I think needs nospec dance for nid?
> + return -EINVAL;
> +
> + if (XE_IOCTL_DBG(xe, !(bo_flags & XE_BO_FLAG_SYSTEM)))
> + return -EINVAL;
> +
> + *numa_node = nid;
> +next:
> + extensions = base.next_extension;
> + }
> +
> + return 0;
> +}
> +
> int xe_gem_create_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file)
> {
> @@ -3669,6 +3727,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
> struct xe_vm *vm = NULL;
> struct xe_bo *bo;
> unsigned int bo_flags;
> + int numa_node;
> u32 handle;
> int err;
>
> @@ -3744,6 +3803,11 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
> args->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
> return -EINVAL;
>
> + err = gem_create_parse_numa_node(xe, args->extensions, bo_flags,
> + &numa_node);
> + if (err)
> + return err;
> +
> if (args->vm_id) {
> vm = xe_vm_lookup(xef, args->vm_id);
> if (XE_IOCTL_DBG(xe, !vm))
> @@ -3760,7 +3824,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
> break;
> }
> bo = xe_bo_create_user(xe, vm, args->size, args->cpu_caching,
> - bo_flags, &exec);
> + bo_flags, numa_node, &exec);
> drm_exec_retry_on_contention(&exec);
> if (IS_ERR(bo)) {
> err = PTR_ERR(bo);
> @@ -4231,7 +4295,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_NEEDS_CPU_ACCESS, NULL);
> + XE_BO_FLAG_NEEDS_CPU_ACCESS, NUMA_NO_NODE, 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 77b3a02e9b8e..225c6a8676a6 100644
> --- a/drivers/gpu/drm/xe/xe_bo.h
> +++ b/drivers/gpu/drm/xe/xe_bo.h
> @@ -122,13 +122,14 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
> struct ttm_lru_bulk_move *bulk, size_t size,
> u16 cpu_caching, enum ttm_bo_type type,
> u32 flags, struct dma_buf *dma_buf,
> - struct drm_exec *exec);
> + int numa_node, struct drm_exec *exec);
> struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
> struct xe_vm *vm, size_t size,
> enum ttm_bo_type type, u32 flags,
> struct drm_exec *exec);
> struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_vm *vm, size_t size,
> - u16 cpu_caching, u32 flags, struct drm_exec *exec);
> + u16 cpu_caching, u32 flags, int numa_node,
> + struct drm_exec *exec);
> struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct xe_tile *tile,
> struct xe_vm *vm, size_t size,
> enum ttm_bo_type type, u32 flags,
> diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
> index 5bf13dc4b61d..b5351310a07b 100644
> --- a/drivers/gpu/drm/xe/xe_dma_buf.c
> +++ b/drivers/gpu/drm/xe/xe_dma_buf.c
> @@ -343,7 +343,8 @@ xe_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
>
> bo = xe_bo_init_locked(xe, NULL, NULL, resv, NULL, dma_buf->size,
> 0, /* Will require 1way or 2way for vm_bind */
> - ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf, &exec);
> + ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf,
> + NUMA_NO_NODE, &exec);
> drm_exec_retry_on_contention(&exec);
> if (IS_ERR(bo)) {
> ret = PTR_ERR(bo);
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ CI.KUnit: success for drm/ttm, drm/xe: Per-BO host NUMA node placement
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (6 preceding siblings ...)
2026-11-02 10:18 ` [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler Himal Prasad Ghimiray
@ 2026-11-02 12:44 ` Patchwork
2026-11-02 13:22 ` ✓ Xe.CI.BAT: " Patchwork
2026-11-02 14:55 ` ✓ Xe.CI.FULL: " Patchwork
9 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-11-02 12:44 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe
== Series Details ==
Series: drm/ttm, drm/xe: Per-BO host NUMA node placement
URL : https://patchwork.freedesktop.org/series/177437/
State : success
== Summary ==
+ trap cleanup EXIT
+ kunitconfigs=('/kernel/drivers/gpu/tests/.kunitconfig' '/kernel/drivers/gpu/drm/xe/.kunitconfig' '/kernel/drivers/gpu/drm/tests/.kunitconfig' '/kernel/drivers/gpu/drm/ttm/tests/.kunitconfig' '/kernel/drivers/dma-buf/.kunitconfig')
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/tests/.kunitconfig
[12:41:57] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:42:02] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:42:22] Starting KUnit Kernel (1/1)...
[12:42:22] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:42:22] ================= gpu_buddy (14 subtests) ==================
[12:42:22] [PASSED] gpu_test_buddy_alloc_limit
[12:42:22] [PASSED] gpu_test_buddy_alloc_optimistic
[12:42:22] [PASSED] gpu_test_buddy_alloc_pessimistic
[12:42:22] [PASSED] gpu_test_buddy_alloc_pathological
[12:42:22] [PASSED] gpu_test_buddy_alloc_contiguous
[12:42:22] [PASSED] gpu_test_buddy_alloc_clear
[12:42:22] [PASSED] gpu_test_buddy_alloc_range
[12:42:22] [PASSED] gpu_test_buddy_alloc_range_bias
[12:42:23] [PASSED] gpu_test_buddy_fragmentation_performance
[12:42:24] [PASSED] gpu_test_buddy_dirty_tracker_performance
[12:42:24] [PASSED] gpu_test_buddy_alloc_exceeds_max_order
[12:42:24] [PASSED] gpu_test_buddy_offset_aligned_allocation
[12:42:24] [PASSED] gpu_test_buddy_subtree_offset_alignment_stress
[12:42:24] [PASSED] gpu_test_buddy_addr_to_block
[12:42:24] ==================== [PASSED] gpu_buddy ====================
[12:42:24] ============================================================
[12:42:24] Testing complete. Ran 14 tests: passed: 14
[12:42:24] Elapsed time: 26.796s total, 5.049s configuring, 19.880s building, 1.819s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/xe/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
[12:42:24] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:42:26] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:43:05] Starting KUnit Kernel (1/1)...
[12:43:05] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:43:05] ================== guc_buf (11 subtests) ===================
[12:43:05] [PASSED] test_smallest
[12:43:05] [PASSED] test_largest
[12:43:05] [PASSED] test_granular
[12:43:05] [PASSED] test_unique
[12:43:05] [PASSED] test_overlap
[12:43:05] [PASSED] test_reusable
[12:43:05] [PASSED] test_too_big
[12:43:05] [PASSED] test_flush
[12:43:05] [PASSED] test_lookup
[12:43:05] [PASSED] test_data
[12:43:05] [PASSED] test_class
[12:43:05] ===================== [PASSED] guc_buf =====================
[12:43:05] =================== guc_dbm (7 subtests) ===================
[12:43:05] [PASSED] test_empty
[12:43:05] [PASSED] test_default
[12:43:05] ======================== test_size ========================
[12:43:05] [PASSED] 4
[12:43:05] [PASSED] 8
[12:43:05] [PASSED] 32
[12:43:05] [PASSED] 256
[12:43:05] ==================== [PASSED] test_size ====================
[12:43:05] ======================= test_reuse ========================
[12:43:05] [PASSED] 4
[12:43:05] [PASSED] 8
[12:43:05] [PASSED] 32
[12:43:05] [PASSED] 256
[12:43:05] =================== [PASSED] test_reuse ====================
[12:43:05] =================== test_range_overlap ====================
[12:43:05] [PASSED] 4
[12:43:05] [PASSED] 8
[12:43:05] [PASSED] 32
[12:43:05] [PASSED] 256
[12:43:05] =============== [PASSED] test_range_overlap ================
[12:43:05] =================== test_range_compact ====================
[12:43:05] [PASSED] 4
[12:43:05] [PASSED] 8
[12:43:05] [PASSED] 32
[12:43:05] [PASSED] 256
[12:43:05] =============== [PASSED] test_range_compact ================
[12:43:05] ==================== test_range_spare =====================
[12:43:05] [PASSED] 4
[12:43:05] [PASSED] 8
[12:43:05] [PASSED] 32
[12:43:05] [PASSED] 256
[12:43:05] ================ [PASSED] test_range_spare =================
[12:43:05] ===================== [PASSED] guc_dbm =====================
[12:43:05] ================== guc_idm (22 subtests) ===================
[12:43:05] [PASSED] bad_init
[12:43:05] [PASSED] no_init
[12:43:05] [PASSED] init_fini
[12:43:05] [PASSED] check_init_small
[12:43:05] [PASSED] check_init_shared
[12:43:05] [PASSED] check_used
[12:43:05] [PASSED] check_quota
[12:43:05] [PASSED] check_all
[12:43:05] [PASSED] check_limits
[12:43:05] [PASSED] check_overlap
[12:43:05] [PASSED] check_overlap_alloc
[12:43:05] [PASSED] check_overlap_release
[12:43:05] [PASSED] check_overlap_partial_init
[12:43:05] [PASSED] check_overlap_partial_shared_range_blocking
[12:43:05] [PASSED] check_used_usable
[12:43:05] [PASSED] check_used_shareable
[12:43:05] [PASSED] check_used_mixed
[12:43:05] [PASSED] check_release_usable_range
[12:43:05] [PASSED] check_release_shareable_range
[12:43:05] [PASSED] check_split_boundaries
[12:43:05] [PASSED] check_shareable_spare
[12:43:05] [PASSED] check_shareable_spare_fragmented_tail
[12:43:05] ===================== [PASSED] guc_idm =====================
[12:43:05] ============== guc_klv_helpers (13 subtests) ===============
[12:43:05] [PASSED] test_count
[12:43:05] [PASSED] test_encode_u32
[12:43:05] [PASSED] test_encode_u64
[12:43:05] [PASSED] test_encode_string
[12:43:05] [PASSED] test_encode_object_raw
[12:43:05] [PASSED] test_encode_object_klv
[12:43:05] [PASSED] test_encode_object_nested
[12:43:05] [PASSED] test_encode_object_basic
[12:43:05] ===================== test_decode_u16 =====================
[12:43:05] [PASSED] empty
[12:43:05] [PASSED] valid
[12:43:05] [PASSED] max
[12:43:05] [PASSED] big
[12:43:05] [PASSED] long
[12:43:05] ================= [PASSED] test_decode_u16 =================
[12:43:05] ===================== test_decode_u32 =====================
[12:43:05] [PASSED] empty
[12:43:05] [PASSED] valid
[12:43:05] [PASSED] max
[12:43:05] [PASSED] long
[12:43:05] ================= [PASSED] test_decode_u32 =================
[12:43:05] ===================== test_decode_u64 =====================
[12:43:05] [PASSED] empty
[12:43:05] [PASSED] short
[12:43:05] [PASSED] valid
[12:43:05] [PASSED] max
[12:43:05] [PASSED] long
[12:43:05] ================= [PASSED] test_decode_u64 =================
[12:43:05] ===================== test_decode_str =====================
[12:43:05] [PASSED] empty
[12:43:05] [PASSED] one
[12:43:05] [PASSED] one_trash
[12:43:05] [PASSED] two
[12:43:05] [PASSED] two_trash
[12:43:05] [PASSED] three
[12:43:05] [PASSED] dword
[12:43:05] [PASSED] four
[12:43:05] [PASSED] five
[12:43:05] [PASSED] six
[12:43:05] [PASSED] seven
[12:43:05] [PASSED] qword
[12:43:05] ================= [PASSED] test_decode_str =================
[12:43:05] [PASSED] test_print
[12:43:05] ================= [PASSED] guc_klv_helpers =================
[12:43:05] =================== xe_log (4 subtests) ====================
[12:43:05] [PASSED] demo_cper
[12:43:05] [PASSED] demo_dmesg
[12:43:05] ======================= test_dmesg ========================
[12:43:05] [PASSED] test_fatal
[12:43:05] [PASSED] test_fatal_tile
[12:43:05] [PASSED] test_fatal_gt
[12:43:05] [PASSED] test_fatal_comp
[12:43:05] [PASSED] test_fatal_comp_tile
[12:43:05] [PASSED] test_fatal_comp_gt
[12:43:05] [PASSED] test_fatal_all
[12:43:05] [PASSED] test_recoverable
[12:43:05] [PASSED] test_recoverable_tile
[12:43:05] [PASSED] test_recoverable_gt
[12:43:05] [PASSED] test_recoverable_comp
[12:43:05] [PASSED] test_recoverable_comp_tile
[12:43:05] [PASSED] test_recoverable_comp_gt
[12:43:05] [PASSED] test_recoverable_all
[12:43:05] [PASSED] test_info
[12:43:05] [PASSED] test_info_tile
[12:43:05] [PASSED] test_info_gt
[12:43:05] [PASSED] test_info_err
[12:43:05] [PASSED] test_info_comp
[12:43:05] [PASSED] test_info_comp_tile
[12:43:05] [PASSED] test_info_comp_gt
[12:43:05] [PASSED] test_info_all
[12:43:05] [PASSED] test_hw_fatal
[12:43:05] [PASSED] test_hw_recoverable
[12:43:05] [PASSED] test_hw_corrected
[12:43:05] [PASSED] test_hw_informational
[12:43:05] =================== [PASSED] test_dmesg ====================
[12:43:05] ====================== test_invalid =======================
[12:43:05] [SKIPPED] no-component no-location no-warn (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] reserved location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] unknown location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] nonzero-device-id location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] invalid-tile-id location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] invalid-gt-id location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] unknown component class (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] unknown system component (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] unknown hardware component (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] [SKIPPED] unknown component and location (requires CONFIG_DRM_XE_DEBUG)
[12:43:05] ================== [SKIPPED] test_invalid ==================
[12:43:05] ===================== [PASSED] xe_log ======================
[12:43:05] ================== no_relay (3 subtests) ===================
[12:43:05] [PASSED] xe_drops_guc2pf_if_not_ready
[12:43:05] [PASSED] xe_drops_guc2vf_if_not_ready
[12:43:05] [PASSED] xe_rejects_send_if_not_ready
[12:43:05] ==================== [PASSED] no_relay =====================
[12:43:05] ================== pf_relay (14 subtests) ==================
[12:43:05] [PASSED] pf_rejects_guc2pf_too_short
[12:43:05] [PASSED] pf_rejects_guc2pf_too_long
[12:43:05] [PASSED] pf_rejects_guc2pf_no_payload
[12:43:05] [PASSED] pf_fails_no_payload
[12:43:05] [PASSED] pf_fails_bad_origin
[12:43:05] [PASSED] pf_fails_bad_type
[12:43:05] [PASSED] pf_txn_reports_error
[12:43:05] [PASSED] pf_txn_sends_pf2guc
[12:43:05] [PASSED] pf_sends_pf2guc
[12:43:05] [SKIPPED] pf_loopback_nop (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:43:05] [SKIPPED] pf_loopback_echo (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:43:05] [SKIPPED] pf_loopback_fail (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:43:05] [SKIPPED] pf_loopback_busy (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:43:05] [SKIPPED] pf_loopback_retry (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:43:05] ==================== [PASSED] pf_relay =====================
[12:43:05] ================== vf_relay (3 subtests) ===================
[12:43:05] [PASSED] vf_rejects_guc2vf_too_short
[12:43:05] [PASSED] vf_rejects_guc2vf_too_long
[12:43:05] [PASSED] vf_rejects_guc2vf_no_payload
[12:43:05] ==================== [PASSED] vf_relay =====================
[12:43:05] ================ pf_gt_config (9 subtests) =================
[12:43:05] [PASSED] fair_contexts_1vf
[12:43:05] [PASSED] fair_doorbells_1vf
[12:43:05] [PASSED] fair_ggtt_1vf
[12:43:05] ====================== fair_vram_1vf ======================
[12:43:05] [PASSED] 3.50 GiB
[12:43:05] [PASSED] 11.5 GiB
[12:43:05] [PASSED] 15.5 GiB
[12:43:05] [PASSED] 31.5 GiB
[12:43:05] [PASSED] 63.5 GiB
[12:43:05] [PASSED] 1.91 GiB
[12:43:05] ================== [PASSED] fair_vram_1vf ==================
[12:43:05] ================ fair_vram_1vf_admin_only =================
[12:43:05] [PASSED] 3.50 GiB
[12:43:05] [PASSED] 11.5 GiB
[12:43:05] [PASSED] 15.5 GiB
[12:43:05] [PASSED] 31.5 GiB
[12:43:05] [PASSED] 63.5 GiB
[12:43:05] [PASSED] 1.91 GiB
[12:43:05] ============ [PASSED] fair_vram_1vf_admin_only =============
[12:43:05] ====================== fair_contexts ======================
[12:43:05] [PASSED] 1 VF
[12:43:05] [PASSED] 2 VFs
[12:43:05] [PASSED] 3 VFs
[12:43:05] [PASSED] 4 VFs
[12:43:05] [PASSED] 5 VFs
[12:43:05] [PASSED] 6 VFs
[12:43:05] [PASSED] 7 VFs
[12:43:05] [PASSED] 8 VFs
[12:43:05] [PASSED] 9 VFs
[12:43:05] [PASSED] 10 VFs
[12:43:05] [PASSED] 11 VFs
[12:43:05] [PASSED] 12 VFs
[12:43:05] [PASSED] 13 VFs
[12:43:05] [PASSED] 14 VFs
[12:43:05] [PASSED] 15 VFs
[12:43:05] [PASSED] 16 VFs
[12:43:05] [PASSED] 17 VFs
[12:43:05] [PASSED] 18 VFs
[12:43:05] [PASSED] 19 VFs
[12:43:05] [PASSED] 20 VFs
[12:43:05] [PASSED] 21 VFs
[12:43:05] [PASSED] 22 VFs
[12:43:05] [PASSED] 23 VFs
[12:43:05] [PASSED] 24 VFs
[12:43:05] [PASSED] 25 VFs
[12:43:05] [PASSED] 26 VFs
[12:43:05] [PASSED] 27 VFs
[12:43:05] [PASSED] 28 VFs
[12:43:05] [PASSED] 29 VFs
[12:43:05] [PASSED] 30 VFs
[12:43:05] [PASSED] 31 VFs
[12:43:05] [PASSED] 32 VFs
[12:43:05] [PASSED] 33 VFs
[12:43:05] [PASSED] 34 VFs
[12:43:05] [PASSED] 35 VFs
[12:43:05] [PASSED] 36 VFs
[12:43:05] [PASSED] 37 VFs
[12:43:05] [PASSED] 38 VFs
[12:43:05] [PASSED] 39 VFs
[12:43:05] [PASSED] 40 VFs
[12:43:05] [PASSED] 41 VFs
[12:43:05] [PASSED] 42 VFs
[12:43:05] [PASSED] 43 VFs
[12:43:05] [PASSED] 44 VFs
[12:43:05] [PASSED] 45 VFs
[12:43:05] [PASSED] 46 VFs
[12:43:05] [PASSED] 47 VFs
[12:43:05] [PASSED] 48 VFs
[12:43:05] [PASSED] 49 VFs
[12:43:05] [PASSED] 50 VFs
[12:43:05] [PASSED] 51 VFs
[12:43:05] [PASSED] 52 VFs
[12:43:05] [PASSED] 53 VFs
[12:43:05] [PASSED] 54 VFs
[12:43:05] [PASSED] 55 VFs
[12:43:05] [PASSED] 56 VFs
[12:43:05] [PASSED] 57 VFs
[12:43:05] [PASSED] 58 VFs
[12:43:05] [PASSED] 59 VFs
[12:43:05] [PASSED] 60 VFs
[12:43:05] [PASSED] 61 VFs
[12:43:05] [PASSED] 62 VFs
[12:43:05] [PASSED] 63 VFs
[12:43:05] ================== [PASSED] fair_contexts ==================
[12:43:05] ===================== fair_doorbells ======================
[12:43:05] [PASSED] 1 VF
[12:43:05] [PASSED] 2 VFs
[12:43:05] [PASSED] 3 VFs
[12:43:05] [PASSED] 4 VFs
[12:43:05] [PASSED] 5 VFs
[12:43:05] [PASSED] 6 VFs
[12:43:05] [PASSED] 7 VFs
[12:43:05] [PASSED] 8 VFs
[12:43:05] [PASSED] 9 VFs
[12:43:05] [PASSED] 10 VFs
[12:43:05] [PASSED] 11 VFs
[12:43:05] [PASSED] 12 VFs
[12:43:05] [PASSED] 13 VFs
[12:43:05] [PASSED] 14 VFs
[12:43:05] [PASSED] 15 VFs
[12:43:05] [PASSED] 16 VFs
[12:43:05] [PASSED] 17 VFs
[12:43:05] [PASSED] 18 VFs
[12:43:05] [PASSED] 19 VFs
[12:43:05] [PASSED] 20 VFs
[12:43:05] [PASSED] 21 VFs
[12:43:05] [PASSED] 22 VFs
[12:43:05] [PASSED] 23 VFs
[12:43:05] [PASSED] 24 VFs
[12:43:05] [PASSED] 25 VFs
[12:43:05] [PASSED] 26 VFs
[12:43:05] [PASSED] 27 VFs
[12:43:05] [PASSED] 28 VFs
[12:43:05] [PASSED] 29 VFs
[12:43:05] [PASSED] 30 VFs
[12:43:05] [PASSED] 31 VFs
[12:43:05] [PASSED] 32 VFs
[12:43:05] [PASSED] 33 VFs
[12:43:05] [PASSED] 34 VFs
[12:43:05] [PASSED] 35 VFs
[12:43:05] [PASSED] 36 VFs
[12:43:05] [PASSED] 37 VFs
[12:43:05] [PASSED] 38 VFs
[12:43:05] [PASSED] 39 VFs
[12:43:05] [PASSED] 40 VFs
[12:43:05] [PASSED] 41 VFs
[12:43:05] [PASSED] 42 VFs
[12:43:05] [PASSED] 43 VFs
[12:43:05] [PASSED] 44 VFs
[12:43:05] [PASSED] 45 VFs
[12:43:05] [PASSED] 46 VFs
[12:43:05] [PASSED] 47 VFs
[12:43:05] [PASSED] 48 VFs
[12:43:05] [PASSED] 49 VFs
[12:43:05] [PASSED] 50 VFs
[12:43:05] [PASSED] 51 VFs
[12:43:05] [PASSED] 52 VFs
[12:43:05] [PASSED] 53 VFs
[12:43:05] [PASSED] 54 VFs
[12:43:05] [PASSED] 55 VFs
[12:43:05] [PASSED] 56 VFs
[12:43:05] [PASSED] 57 VFs
[12:43:05] [PASSED] 58 VFs
[12:43:05] [PASSED] 59 VFs
[12:43:05] [PASSED] 60 VFs
[12:43:05] [PASSED] 61 VFs
[12:43:05] [PASSED] 62 VFs
[12:43:05] [PASSED] 63 VFs
[12:43:05] ================= [PASSED] fair_doorbells ==================
[12:43:05] ======================== fair_ggtt ========================
[12:43:05] [PASSED] 1 VF
[12:43:05] [PASSED] 2 VFs
[12:43:05] [PASSED] 3 VFs
[12:43:05] [PASSED] 4 VFs
[12:43:05] [PASSED] 5 VFs
[12:43:05] [PASSED] 6 VFs
[12:43:05] [PASSED] 7 VFs
[12:43:05] [PASSED] 8 VFs
[12:43:05] [PASSED] 9 VFs
[12:43:05] [PASSED] 10 VFs
[12:43:05] [PASSED] 11 VFs
[12:43:05] [PASSED] 12 VFs
[12:43:05] [PASSED] 13 VFs
[12:43:05] [PASSED] 14 VFs
[12:43:05] [PASSED] 15 VFs
[12:43:05] [PASSED] 16 VFs
[12:43:05] [PASSED] 17 VFs
[12:43:05] [PASSED] 18 VFs
[12:43:05] [PASSED] 19 VFs
[12:43:05] [PASSED] 20 VFs
[12:43:05] [PASSED] 21 VFs
[12:43:05] [PASSED] 22 VFs
[12:43:05] [PASSED] 23 VFs
[12:43:05] [PASSED] 24 VFs
[12:43:05] [PASSED] 25 VFs
[12:43:05] [PASSED] 26 VFs
[12:43:05] [PASSED] 27 VFs
[12:43:05] [PASSED] 28 VFs
[12:43:05] [PASSED] 29 VFs
[12:43:05] [PASSED] 30 VFs
[12:43:05] [PASSED] 31 VFs
[12:43:05] [PASSED] 32 VFs
[12:43:05] [PASSED] 33 VFs
[12:43:05] [PASSED] 34 VFs
[12:43:05] [PASSED] 35 VFs
[12:43:05] [PASSED] 36 VFs
[12:43:05] [PASSED] 37 VFs
[12:43:05] [PASSED] 38 VFs
[12:43:05] [PASSED] 39 VFs
[12:43:05] [PASSED] 40 VFs
[12:43:05] [PASSED] 41 VFs
[12:43:05] [PASSED] 42 VFs
[12:43:05] [PASSED] 43 VFs
[12:43:05] [PASSED] 44 VFs
[12:43:05] [PASSED] 45 VFs
[12:43:05] [PASSED] 46 VFs
[12:43:05] [PASSED] 47 VFs
[12:43:05] [PASSED] 48 VFs
[12:43:05] [PASSED] 49 VFs
[12:43:05] [PASSED] 50 VFs
[12:43:06] [PASSED] 51 VFs
[12:43:06] [PASSED] 52 VFs
[12:43:06] [PASSED] 53 VFs
[12:43:06] [PASSED] 54 VFs
[12:43:06] [PASSED] 55 VFs
[12:43:06] [PASSED] 56 VFs
[12:43:06] [PASSED] 57 VFs
[12:43:06] [PASSED] 58 VFs
[12:43:06] [PASSED] 59 VFs
[12:43:06] [PASSED] 60 VFs
[12:43:06] [PASSED] 61 VFs
[12:43:06] [PASSED] 62 VFs
[12:43:06] [PASSED] 63 VFs
[12:43:06] ==================== [PASSED] fair_ggtt ====================
[12:43:06] ======================== fair_vram ========================
[12:43:06] [PASSED] 1 VF
[12:43:06] [PASSED] 2 VFs
[12:43:06] [PASSED] 3 VFs
[12:43:06] [PASSED] 4 VFs
[12:43:06] [PASSED] 5 VFs
[12:43:06] [PASSED] 6 VFs
[12:43:06] [PASSED] 7 VFs
[12:43:06] [PASSED] 8 VFs
[12:43:06] [PASSED] 9 VFs
[12:43:06] [PASSED] 10 VFs
[12:43:06] [PASSED] 11 VFs
[12:43:06] [PASSED] 12 VFs
[12:43:06] [PASSED] 13 VFs
[12:43:06] [PASSED] 14 VFs
[12:43:06] [PASSED] 15 VFs
[12:43:06] [PASSED] 16 VFs
[12:43:06] [PASSED] 17 VFs
[12:43:06] [PASSED] 18 VFs
[12:43:06] [PASSED] 19 VFs
[12:43:06] [PASSED] 20 VFs
[12:43:06] [PASSED] 21 VFs
[12:43:06] [PASSED] 22 VFs
[12:43:06] [PASSED] 23 VFs
[12:43:06] [PASSED] 24 VFs
[12:43:06] [PASSED] 25 VFs
[12:43:06] [PASSED] 26 VFs
[12:43:06] [PASSED] 27 VFs
[12:43:06] [PASSED] 28 VFs
[12:43:06] [PASSED] 29 VFs
[12:43:06] [PASSED] 30 VFs
[12:43:06] [PASSED] 31 VFs
[12:43:06] [PASSED] 32 VFs
[12:43:06] [PASSED] 33 VFs
[12:43:06] [PASSED] 34 VFs
[12:43:06] [PASSED] 35 VFs
[12:43:06] [PASSED] 36 VFs
[12:43:06] [PASSED] 37 VFs
[12:43:06] [PASSED] 38 VFs
[12:43:06] [PASSED] 39 VFs
[12:43:06] [PASSED] 40 VFs
[12:43:06] [PASSED] 41 VFs
[12:43:06] [PASSED] 42 VFs
[12:43:06] [PASSED] 43 VFs
[12:43:06] [PASSED] 44 VFs
[12:43:06] [PASSED] 45 VFs
[12:43:06] [PASSED] 46 VFs
[12:43:06] [PASSED] 47 VFs
[12:43:06] [PASSED] 48 VFs
[12:43:06] [PASSED] 49 VFs
[12:43:06] [PASSED] 50 VFs
[12:43:06] [PASSED] 51 VFs
[12:43:06] [PASSED] 52 VFs
[12:43:06] [PASSED] 53 VFs
[12:43:06] [PASSED] 54 VFs
[12:43:06] [PASSED] 55 VFs
[12:43:06] [PASSED] 56 VFs
[12:43:06] [PASSED] 57 VFs
[12:43:06] [PASSED] 58 VFs
[12:43:06] [PASSED] 59 VFs
[12:43:06] [PASSED] 60 VFs
[12:43:06] [PASSED] 61 VFs
[12:43:06] [PASSED] 62 VFs
[12:43:06] [PASSED] 63 VFs
[12:43:06] ==================== [PASSED] fair_vram ====================
[12:43:06] ================== [PASSED] pf_gt_config ===================
[12:43:06] ===================== lmtt (1 subtest) =====================
[12:43:06] ======================== test_ops =========================
[12:43:06] [PASSED] 2-level
[12:43:06] [PASSED] multi-level
[12:43:06] ==================== [PASSED] test_ops =====================
[12:43:06] ====================== [PASSED] lmtt =======================
[12:43:06] ================= sriov_packet (1 subtest) =================
[12:43:06] [PASSED] test_descriptor_init
[12:43:06] ================== [PASSED] sriov_packet ===================
[12:43:06] ================= pf_service (11 subtests) =================
[12:43:06] [PASSED] pf_negotiate_any
[12:43:06] [PASSED] pf_negotiate_base_match
[12:43:06] [PASSED] pf_negotiate_base_newer
[12:43:06] [PASSED] pf_negotiate_base_next
[12:43:06] [SKIPPED] pf_negotiate_base_older (no older minor)
[12:43:06] [PASSED] pf_negotiate_base_prev
[12:43:06] [PASSED] pf_negotiate_latest_match
[12:43:06] [PASSED] pf_negotiate_latest_newer
[12:43:06] [PASSED] pf_negotiate_latest_next
[12:43:06] [SKIPPED] pf_negotiate_latest_older (no older minor)
[12:43:06] [SKIPPED] pf_negotiate_latest_prev (no prev major)
[12:43:06] =================== [PASSED] pf_service ====================
[12:43:06] ================= xe_guc_g2g (2 subtests) ==================
[12:43:06] ============== xe_live_guc_g2g_kunit_default ==============
[12:43:06] ========= [SKIPPED] xe_live_guc_g2g_kunit_default ==========
[12:43:06] ============== xe_live_guc_g2g_kunit_allmem ===============
[12:43:06] ========== [SKIPPED] xe_live_guc_g2g_kunit_allmem ==========
[12:43:06] =================== [SKIPPED] xe_guc_g2g ===================
[12:43:06] =================== xe_mocs (2 subtests) ===================
[12:43:06] ================ xe_live_mocs_kernel_kunit ================
[12:43:06] =========== [SKIPPED] xe_live_mocs_kernel_kunit ============
[12:43:06] ================ xe_live_mocs_reset_kunit =================
[12:43:06] ============ [SKIPPED] xe_live_mocs_reset_kunit ============
[12:43:06] ==================== [SKIPPED] xe_mocs =====================
[12:43:06] ================= xe_migrate (3 subtests) ==================
[12:43:06] ================= xe_migrate_sanity_kunit =================
[12:43:06] ============ [SKIPPED] xe_migrate_sanity_kunit =============
[12:43:06] ================== xe_validate_ccs_kunit ==================
[12:43:06] ============= [SKIPPED] xe_validate_ccs_kunit ==============
[12:43:06] ============= xe_migrate_access_memory_kunit ==============
[12:43:06] ========= [SKIPPED] xe_migrate_access_memory_kunit =========
[12:43:06] =================== [SKIPPED] xe_migrate ===================
[12:43:06] ================== xe_dma_buf (1 subtest) ==================
[12:43:06] ==================== xe_dma_buf_kunit =====================
[12:43:06] ================ [SKIPPED] xe_dma_buf_kunit ================
[12:43:06] =================== [SKIPPED] xe_dma_buf ===================
[12:43:06] ================= xe_bo_shrink (1 subtest) =================
[12:43:06] =================== xe_bo_shrink_kunit ====================
[12:43:06] =============== [SKIPPED] xe_bo_shrink_kunit ===============
[12:43:06] ================== [SKIPPED] xe_bo_shrink ==================
[12:43:06] ==================== xe_bo (2 subtests) ====================
[12:43:06] ================== xe_ccs_migrate_kunit ===================
[12:43:06] ============== [SKIPPED] xe_ccs_migrate_kunit ==============
[12:43:06] ==================== xe_bo_evict_kunit ====================
[12:43:06] =============== [SKIPPED] xe_bo_evict_kunit ================
[12:43:06] ===================== [SKIPPED] xe_bo ======================
[12:43:06] =================== xe_any (9 subtests) ====================
[12:43:06] [PASSED] test_to_xe
[12:43:06] [PASSED] test_to_dev
[12:43:06] [PASSED] test_to_pdev
[12:43:06] [PASSED] test_to_drm
[12:43:06] [PASSED] test_if_pdev
[12:43:06] [PASSED] test_if_xe
[12:43:06] [PASSED] test_if_tile
[12:43:06] [PASSED] test_if_gt
[12:43:06] [PASSED] test_to_id
[12:43:06] ===================== [PASSED] xe_any ======================
[12:43:06] ==================== args (13 subtests) ====================
[12:43:06] [PASSED] count_args_test
[12:43:06] [PASSED] call_args_example
[12:43:06] [PASSED] call_args_test
[12:43:06] [PASSED] drop_first_arg_example
[12:43:06] [PASSED] drop_first_arg_test
[12:43:06] [PASSED] first_arg_example
[12:43:06] [PASSED] first_arg_test
[12:43:06] [PASSED] last_arg_example
[12:43:06] [PASSED] last_arg_test
[12:43:06] [PASSED] pick_arg_example
[12:43:06] [PASSED] if_args_example
[12:43:06] [PASSED] if_args_test
[12:43:06] [PASSED] sep_comma_example
[12:43:06] ====================== [PASSED] args =======================
[12:43:06] =================== xe_pci (3 subtests) ====================
[12:43:06] ==================== check_graphics_ip ====================
[12:43:06] [PASSED] 12.00 Xe_LP
[12:43:06] [PASSED] 12.10 Xe_LP+
[12:43:06] [PASSED] 12.55 Xe_HPG
[12:43:06] [PASSED] 12.60 Xe_HPC
[12:43:06] [PASSED] 12.70 Xe_LPG
[12:43:06] [PASSED] 12.71 Xe_LPG
[12:43:06] [PASSED] 12.74 Xe_LPG+
[12:43:06] [PASSED] 20.01 Xe2_HPG
[12:43:06] [PASSED] 20.02 Xe2_HPG
[12:43:06] [PASSED] 20.04 Xe2_LPG
[12:43:06] [PASSED] 30.00 Xe3_LPG
[12:43:06] [PASSED] 30.01 Xe3_LPG
[12:43:06] [PASSED] 30.03 Xe3_LPG
[12:43:06] [PASSED] 30.04 Xe3_LPG
[12:43:06] [PASSED] 30.05 Xe3_LPG
[12:43:06] [PASSED] 35.10 Xe3p_LPG
[12:43:06] [PASSED] 35.11 Xe3p_XPC
[12:43:06] ================ [PASSED] check_graphics_ip ================
[12:43:06] ===================== check_media_ip ======================
[12:43:06] [PASSED] 12.00 Xe_M
[12:43:06] [PASSED] 12.55 Xe_HPM
[12:43:06] [PASSED] 13.00 Xe_LPM+
[12:43:06] [PASSED] 13.01 Xe2_HPM
[12:43:06] [PASSED] 20.00 Xe2_LPM
[12:43:06] [PASSED] 30.00 Xe3_LPM
[12:43:06] [PASSED] 30.02 Xe3_LPM
[12:43:06] [PASSED] 35.00 Xe3p_LPM
[12:43:06] [PASSED] 35.03 Xe3p_HPM
[12:43:06] ================= [PASSED] check_media_ip ==================
[12:43:06] =================== check_platform_desc ===================
[12:43:06] [PASSED] 0x9A60 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A68 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A70 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A40 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A49 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A59 (TIGERLAKE)
[12:43:06] [PASSED] 0x9A78 (TIGERLAKE)
[12:43:06] [PASSED] 0x9AC0 (TIGERLAKE)
[12:43:06] [PASSED] 0x9AC9 (TIGERLAKE)
[12:43:06] [PASSED] 0x9AD9 (TIGERLAKE)
[12:43:06] [PASSED] 0x9AF8 (TIGERLAKE)
[12:43:06] [PASSED] 0x4C80 (ROCKETLAKE)
[12:43:06] [PASSED] 0x4C8A (ROCKETLAKE)
[12:43:06] [PASSED] 0x4C8B (ROCKETLAKE)
[12:43:06] [PASSED] 0x4C8C (ROCKETLAKE)
[12:43:06] [PASSED] 0x4C90 (ROCKETLAKE)
[12:43:06] [PASSED] 0x4C9A (ROCKETLAKE)
[12:43:06] [PASSED] 0x4680 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4682 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4688 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x468A (ALDERLAKE_S)
[12:43:06] [PASSED] 0x468B (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4690 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4692 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4693 (ALDERLAKE_S)
[12:43:06] [PASSED] 0x46A0 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46A1 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46A2 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46A3 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46A6 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46A8 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46AA (ALDERLAKE_P)
[12:43:06] [PASSED] 0x462A (ALDERLAKE_P)
[12:43:06] [PASSED] 0x4626 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x4628 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46B0 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46B1 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46B2 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46B3 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46C0 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46C1 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46C2 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46C3 (ALDERLAKE_P)
[12:43:06] [PASSED] 0x46D0 (ALDERLAKE_N)
[12:43:06] [PASSED] 0x46D1 (ALDERLAKE_N)
[12:43:06] [PASSED] 0x46D2 (ALDERLAKE_N)
[12:43:06] [PASSED] 0x46D3 (ALDERLAKE_N)
[12:43:06] [PASSED] 0x46D4 (ALDERLAKE_N)
[12:43:06] [PASSED] 0xA721 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7A1 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7A9 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7AC (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7AD (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA720 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7A0 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7A8 (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7AA (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA7AB (ALDERLAKE_P)
[12:43:06] [PASSED] 0xA780 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA781 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA782 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA783 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA788 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA789 (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA78A (ALDERLAKE_S)
[12:43:06] [PASSED] 0xA78B (ALDERLAKE_S)
[12:43:06] [PASSED] 0x4905 (DG1)
[12:43:06] [PASSED] 0x4906 (DG1)
[12:43:06] [PASSED] 0x4907 (DG1)
[12:43:06] [PASSED] 0x4908 (DG1)
[12:43:06] [PASSED] 0x4909 (DG1)
[12:43:06] [PASSED] 0x56C0 (DG2)
[12:43:06] [PASSED] 0x56C2 (DG2)
[12:43:06] [PASSED] 0x56C1 (DG2)
[12:43:06] [PASSED] 0x7D51 (METEORLAKE)
[12:43:06] [PASSED] 0x7DD1 (METEORLAKE)
[12:43:06] [PASSED] 0x7D41 (METEORLAKE)
[12:43:06] [PASSED] 0x7D67 (METEORLAKE)
[12:43:06] [PASSED] 0xB640 (METEORLAKE)
[12:43:06] [PASSED] 0x56A0 (DG2)
[12:43:06] [PASSED] 0x56A1 (DG2)
[12:43:06] [PASSED] 0x56A2 (DG2)
[12:43:06] [PASSED] 0x56BE (DG2)
[12:43:06] [PASSED] 0x56BF (DG2)
[12:43:06] [PASSED] 0x5690 (DG2)
[12:43:06] [PASSED] 0x5691 (DG2)
[12:43:06] [PASSED] 0x5692 (DG2)
[12:43:06] [PASSED] 0x56A5 (DG2)
[12:43:06] [PASSED] 0x56A6 (DG2)
[12:43:06] [PASSED] 0x56B0 (DG2)
[12:43:06] [PASSED] 0x56B1 (DG2)
[12:43:06] [PASSED] 0x56BA (DG2)
[12:43:06] [PASSED] 0x56BB (DG2)
[12:43:06] [PASSED] 0x56BC (DG2)
[12:43:06] [PASSED] 0x56BD (DG2)
[12:43:06] [PASSED] 0x5693 (DG2)
[12:43:06] [PASSED] 0x5694 (DG2)
[12:43:06] [PASSED] 0x5695 (DG2)
[12:43:06] [PASSED] 0x56A3 (DG2)
[12:43:06] [PASSED] 0x56A4 (DG2)
[12:43:06] [PASSED] 0x56B2 (DG2)
[12:43:06] [PASSED] 0x56B3 (DG2)
[12:43:06] [PASSED] 0x5696 (DG2)
[12:43:06] [PASSED] 0x5697 (DG2)
[12:43:06] [PASSED] 0xB69 (PVC)
[12:43:06] [PASSED] 0xB6E (PVC)
[12:43:06] [PASSED] 0xBD4 (PVC)
[12:43:06] [PASSED] 0xBD5 (PVC)
[12:43:06] [PASSED] 0xBD6 (PVC)
[12:43:06] [PASSED] 0xBD7 (PVC)
[12:43:06] [PASSED] 0xBD8 (PVC)
[12:43:06] [PASSED] 0xBD9 (PVC)
[12:43:06] [PASSED] 0xBDA (PVC)
[12:43:06] [PASSED] 0xBDB (PVC)
[12:43:06] [PASSED] 0xBE0 (PVC)
[12:43:06] [PASSED] 0xBE1 (PVC)
[12:43:06] [PASSED] 0xBE5 (PVC)
[12:43:06] [PASSED] 0x7D40 (METEORLAKE)
[12:43:06] [PASSED] 0x7D45 (METEORLAKE)
[12:43:06] [PASSED] 0x7D55 (METEORLAKE)
[12:43:06] [PASSED] 0x7D60 (METEORLAKE)
[12:43:06] [PASSED] 0x7DD5 (METEORLAKE)
[12:43:06] [PASSED] 0x6420 (LUNARLAKE)
[12:43:06] [PASSED] 0x64A0 (LUNARLAKE)
[12:43:06] [PASSED] 0x64B0 (LUNARLAKE)
[12:43:06] [PASSED] 0xE202 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE209 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE20B (BATTLEMAGE)
[12:43:06] [PASSED] 0xE20C (BATTLEMAGE)
[12:43:06] [PASSED] 0xE20D (BATTLEMAGE)
[12:43:06] [PASSED] 0xE210 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE211 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE212 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE216 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE220 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE221 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE222 (BATTLEMAGE)
[12:43:06] [PASSED] 0xE223 (BATTLEMAGE)
[12:43:06] [PASSED] 0xB080 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB081 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB082 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB083 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB084 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB085 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB086 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB087 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB08F (PANTHERLAKE)
[12:43:06] [PASSED] 0xB090 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB0A0 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB0A1 (PANTHERLAKE)
[12:43:06] [PASSED] 0xB0B0 (PANTHERLAKE)
[12:43:06] [PASSED] 0xFD80 (PANTHERLAKE)
[12:43:06] [PASSED] 0xFD81 (PANTHERLAKE)
[12:43:06] [PASSED] 0xD740 (NOVALAKE_S)
[12:43:06] [PASSED] 0xD741 (NOVALAKE_S)
[12:43:06] [PASSED] 0xD742 (NOVALAKE_S)
[12:43:06] [PASSED] 0xD743 (NOVALAKE_S)
[12:43:06] [PASSED] 0xD745 (NOVALAKE_S)
[12:43:06] [PASSED] 0xD74A (NOVALAKE_S)
[12:43:06] [PASSED] 0xD74B (NOVALAKE_S)
[12:43:06] [PASSED] 0x674C (CRESCENTISLAND)
[12:43:06] [PASSED] 0x674D (CRESCENTISLAND)
[12:43:06] [PASSED] 0x674E (CRESCENTISLAND)
[12:43:06] [PASSED] 0x674F (CRESCENTISLAND)
[12:43:06] [PASSED] 0x6750 (CRESCENTISLAND)
[12:43:06] [PASSED] 0x6751 (CRESCENTISLAND)
[12:43:06] [PASSED] 0x6752 (CRESCENTISLAND)
[12:43:06] [PASSED] 0xD750 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD751 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD752 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD753 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD754 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD755 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD756 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD757 (NOVALAKE_P)
[12:43:06] [PASSED] 0xD75F (NOVALAKE_P)
[12:43:06] =============== [PASSED] check_platform_desc ===============
[12:43:06] ===================== [PASSED] xe_pci ======================
[12:43:06] ============= xe_rtp_tables_test (5 subtests) ==============
[12:43:06] ================== xe_rtp_table_gt_test ===================
[12:43:06] [PASSED] gt_was/14011060649
[12:43:06] [PASSED] gt_was/14011059788
[12:43:06] [PASSED] gt_was/14015795083
[12:43:06] [PASSED] gt_was/16021867713
[12:43:06] [PASSED] gt_was/14019449301
[12:43:06] [PASSED] gt_was/16028005424
[12:43:06] [PASSED] gt_was/14026578760
[12:43:06] [PASSED] gt_was/1409420604
[12:43:06] [PASSED] gt_was/1408615072
[12:43:06] [PASSED] gt_was/22010523718
[12:43:06] [PASSED] gt_was/14011006942
[12:43:06] [PASSED] gt_was/14014830051
[12:43:06] [PASSED] gt_was/18018781329
[12:43:06] [PASSED] gt_was/1509235366
[12:43:06] [PASSED] gt_was/18018781329
[12:43:06] [PASSED] gt_was/16016694945
[12:43:06] [PASSED] gt_was/14018575942
[12:43:06] [PASSED] gt_was/22016670082
[12:43:06] [PASSED] gt_was/22016670082
[12:43:06] [PASSED] gt_was/14017421178
[12:43:06] [PASSED] gt_was/16025250150
[12:43:06] [PASSED] gt_was/14021871409
[12:43:06] [PASSED] gt_was/16021865536
[12:43:06] [PASSED] gt_was/14021486841
[12:43:06] [PASSED] gt_was/14025160223
[12:43:06] [PASSED] gt_was/14026144927, 16029437861, 14026127056
[12:43:06] [PASSED] gt_was/14025635424
[12:43:06] [PASSED] gt_was/16028005424
[12:43:06] ============== [PASSED] xe_rtp_table_gt_test ===============
[12:43:06] ================== xe_rtp_table_gt_test ===================
[12:43:06] [PASSED] gt_tunings/Tuning: Blend Fill Caching Optimization Disable
[12:43:06] [PASSED] gt_tunings/Tuning: 32B Access Enable
[12:43:06] [PASSED] gt_tunings/Tuning: L3 cache
[12:43:06] [PASSED] gt_tunings/Tuning: L3 cache - media
[12:43:06] [PASSED] gt_tunings/Tuning: Compression Overfetch
[12:43:06] [PASSED] gt_tunings/Tuning: Compression Overfetch - media
[12:43:06] [PASSED] gt_tunings/Tuning: Enable compressible partial write overfetch in L3
[12:43:06] [PASSED] gt_tunings/Tuning: Enable compressible partial write overfetch in L3 - media
[12:43:06] [PASSED] gt_tunings/Tuning: L2 Overfetch Compressible Only
[12:43:06] [PASSED] gt_tunings/Tuning: L2 Overfetch Compressible Only - media
[12:43:06] [PASSED] gt_tunings/Tuning: Stateless compression control
[12:43:06] [PASSED] gt_tunings/Tuning: Stateless compression control - media
[12:43:06] [PASSED] gt_tunings/Tuning: L3 RW flush all Cache
[12:43:06] [PASSED] gt_tunings/Tuning: L3 RW flush all cache - media
[12:43:06] [PASSED] gt_tunings/Tuning: Set STLB Bank Hash Mode to 4KB
[12:43:06] [PASSED] gt_tunings/Tuning: Force All Non-Compressible Memory Reads to be 256B Overfetches
[12:43:06] ============== [PASSED] xe_rtp_table_gt_test ===============
[12:43:06] ================== xe_rtp_table_oob_test ==================
[12:43:06] [PASSED] oob_was/1607983814
[12:43:06] [PASSED] oob_was/16010904313
[12:43:06] [PASSED] oob_was/18022495364
[12:43:06] [PASSED] oob_was/22012773006
[12:43:06] [PASSED] oob_was/14014475959
[12:43:06] [PASSED] oob_was/22011391025
[12:43:06] [PASSED] oob_was/22012727170
[12:43:06] [PASSED] oob_was/22012727685
[12:43:06] [PASSED] oob_was/22016596838
[12:43:06] [PASSED] oob_was/18020744125
[12:43:06] [PASSED] oob_was/1409600907
[12:43:06] [PASSED] oob_was/22014953428
[12:43:06] [PASSED] oob_was/16017236439
[12:43:06] [PASSED] oob_was/14019821291
[12:43:06] [PASSED] oob_was/14015076503
[12:43:06] [PASSED] oob_was/22016122933
[12:43:06] [PASSED] oob_was/14018913170
[12:43:06] [PASSED] oob_was/14018094691
[12:43:06] [PASSED] oob_was/18024947630
[12:43:06] [PASSED] oob_was/16022287689
[12:43:06] [PASSED] oob_was/13011645652
[12:43:06] [PASSED] oob_was/14022293748
[12:43:06] [PASSED] oob_was/22019794406
[12:43:06] [PASSED] oob_was/22019338487
[12:43:06] [PASSED] oob_was/16023588340
[12:43:06] [PASSED] oob_was/14019789679
[12:43:06] [PASSED] oob_was/14022866841
[12:43:06] [PASSED] oob_was/16021333562
[12:43:06] [PASSED] oob_was/14016712196
[12:43:06] [PASSED] oob_was/14015568240
[12:43:06] [PASSED] oob_was/18013179988
[12:43:06] [PASSED] oob_was/1508761755
[12:43:06] [PASSED] oob_was/16023105232
[12:43:06] [PASSED] oob_was/16026508708
[12:43:06] [PASSED] oob_was/14020001231
[12:43:06] [PASSED] oob_was/16023683509
[12:43:06] [PASSED] oob_was/14025515070
[12:43:06] [PASSED] oob_was/15015404425_disable
[12:43:06] [PASSED] oob_was/16026007364
[12:43:06] [PASSED] oob_was/14020316580
[12:43:06] [PASSED] oob_was/14025883347
[12:43:06] [PASSED] oob_was/16029380221
[12:43:06] [PASSED] oob_was/22022079272
[12:43:06] [PASSED] oob_was/16029897822
[12:43:06] [PASSED] oob_was/14026539277
[12:43:06] [PASSED] oob_was/14027054324
[12:43:06] [PASSED] oob_was/14025941587
[12:43:06] [PASSED] oob_was/16030224309
[12:43:06] ============== [PASSED] xe_rtp_table_oob_test ==============
[12:43:06] ================ xe_rtp_table_dev_oob_test ================
[12:43:06] [PASSED] device_oob_was/22010954014
[12:43:06] [PASSED] device_oob_was/15015404425
[12:43:06] [PASSED] device_oob_was/22019338487_display
[12:43:06] [PASSED] device_oob_was/14022085890
[12:43:06] [PASSED] device_oob_was/14026633728
[12:43:06] [PASSED] device_oob_was/14026746987
[12:43:06] [PASSED] device_oob_was/14026779378
[12:43:06] ============ [PASSED] xe_rtp_table_dev_oob_test ============
[12:43:06] ========== xe_rtp_table_missing_upper_bound_test ==========
[12:43:06] [PASSED] register_whitelist/WaAllowPMDepthAndInvocationCountAccessFromUMD, 1408556865
[12:43:06] [PASSED] register_whitelist/1508744258, 14012131227, 1808121037
[12:43:06] [PASSED] register_whitelist/1806527549
[12:43:06] [PASSED] register_whitelist/allow_read_ctx_timestamp
[12:43:06] [PASSED] register_whitelist/allow_read_queue_timestamp
[12:43:06] [PASSED] register_whitelist/16014440446
[12:43:06] [PASSED] register_whitelist/16017236439
[12:43:06] [PASSED] register_whitelist/16020183090
[12:43:06] [PASSED] register_whitelist/14024997852
[12:43:06] [PASSED] register_whitelist/14024997852
[12:43:06] ====== [PASSED] xe_rtp_table_missing_upper_bound_test ======
[12:43:06] =============== [PASSED] xe_rtp_tables_test ================
[12:43:06] =================== xe_rtp (3 subtests) ====================
[12:43:06] =================== xe_rtp_rules_tests ====================
[12:43:06] [PASSED] no
[12:43:06] [PASSED] yes
[12:43:06] [PASSED] no-and-no
[12:43:06] [PASSED] no-and-yes
[12:43:06] [PASSED] yes-and-no
[12:43:06] [PASSED] yes-and-yes
[12:43:06] [PASSED] no-or-no
[12:43:06] [PASSED] no-or-yes
[12:43:06] [PASSED] yes-or-no
[12:43:06] [PASSED] yes-or-yes
[12:43:06] [PASSED] no-yes-or-yes-no
[12:43:06] [PASSED] no-yes-or-yes-yes
[12:43:06] [PASSED] yes-yes-or-no-yes
[12:43:06] [PASSED] yes-yes-or-yes-yes
[12:43:06] [PASSED] no-no-or-yes-or-no
[12:43:06] [PASSED] or
[12:43:06] [PASSED] or-yes
[12:43:06] [PASSED] or-no
[12:43:06] [PASSED] yes-or
[12:43:06] [PASSED] no-or
[12:43:06] [PASSED] no-or-or-yes
[12:43:06] [PASSED] yes-or-or-no
[12:43:06] [PASSED] no-or-or-no
[12:43:06] [PASSED] missing-context-engine-class
[12:43:06] [PASSED] missing-context-engine-class-or-yes
[12:43:06] [PASSED] missing-context-engine-class-or-or-yes
[12:43:06] =============== [PASSED] xe_rtp_rules_tests ================
[12:43:06] =============== xe_rtp_process_to_sr_tests ================
[12:43:06] [PASSED] coalesce-same-reg
[12:43:06] [PASSED] coalesce-same-reg-literal-and-func
[12:43:06] [PASSED] no-match-no-add
[12:43:06] [PASSED] two-regs-two-entries
[12:43:06] [PASSED] clr-one-set-other
[12:43:06] [PASSED] set-field
[12:43:06] [PASSED] conflict-duplicate
[12:43:06] [PASSED] conflict-not-disjoint
[12:43:06] [PASSED] conflict-not-disjoint-literal-and-func
[12:43:06] [PASSED] conflict-reg-type
[12:43:06] [PASSED] bad-mcr-reg-forced-to-regular
[12:43:06] [PASSED] bad-regular-reg-forced-to-mcr
[12:43:06] =========== [PASSED] xe_rtp_process_to_sr_tests ============
[12:43:06] ================== xe_rtp_process_tests ===================
[12:43:06] [PASSED] active1
[12:43:06] [PASSED] active2
[12:43:06] [PASSED] active-inactive
[12:43:06] [PASSED] inactive-active
[12:43:06] [PASSED] inactive-active-inactive
[12:43:06] [PASSED] inactive-inactive-inactive
[12:43:06] ============== [PASSED] xe_rtp_process_tests ===============
[12:43:06] ===================== [PASSED] xe_rtp ======================
[12:43:06] ==================== xe_wa (1 subtest) =====================
[12:43:06] ======================== xe_wa_gt =========================
[12:43:06] [PASSED] TIGERLAKE B0
[12:43:06] [PASSED] DG1 A0
[12:43:06] [PASSED] DG1 B0
[12:43:06] [PASSED] ALDERLAKE_S A0
[12:43:06] [PASSED] ALDERLAKE_S B0
[12:43:06] [PASSED] ALDERLAKE_S C0
[12:43:06] [PASSED] ALDERLAKE_S D0
[12:43:06] [PASSED] ALDERLAKE_P A0
[12:43:06] [PASSED] ALDERLAKE_P B0
[12:43:06] [PASSED] ALDERLAKE_P C0
[12:43:06] [PASSED] ALDERLAKE_S RPLS D0
[12:43:06] [PASSED] ALDERLAKE_P RPLU E0
[12:43:06] [PASSED] DG2 G10 C0
[12:43:06] [PASSED] DG2 G11 B1
[12:43:06] [PASSED] DG2 G12 A1
[12:43:06] [PASSED] METEORLAKE 12.70(Xe_LPG) A0 13.00(Xe_LPM+) A0
[12:43:06] [PASSED] METEORLAKE 12.71(Xe_LPG) A0 13.00(Xe_LPM+) A0
[12:43:06] [PASSED] METEORLAKE 12.74(Xe_LPG+) A0 13.00(Xe_LPM+) A0
[12:43:06] [PASSED] LUNARLAKE 20.04(Xe2_LPG) A0 20.00(Xe2_LPM) A0
[12:43:06] [PASSED] LUNARLAKE 20.04(Xe2_LPG) B0 20.00(Xe2_LPM) A0
[12:43:06] [PASSED] BATTLEMAGE 20.01(Xe2_HPG) A0 13.01(Xe2_HPM) A1
[12:43:06] [PASSED] PANTHERLAKE 30.00(Xe3_LPG) A0 30.00(Xe3_LPM) A0
[12:43:06] ==================== [PASSED] xe_wa_gt =====================
[12:43:06] ====================== [PASSED] xe_wa ======================
[12:43:06] ============================================================
[12:43:06] Testing complete. Ran 839 tests: passed: 810, skipped: 29
[12:43:06] Elapsed time: 42.025s total, 2.521s configuring, 38.737s building, 0.727s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/tests/.kunitconfig
[12:43:06] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:43:08] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:43:33] Starting KUnit Kernel (1/1)...
[12:43:33] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:43:33] ============ drm_test_pick_cmdline (2 subtests) ============
[12:43:33] [PASSED] drm_test_pick_cmdline_res_1920_1080_60
[12:43:33] =============== drm_test_pick_cmdline_named ===============
[12:43:33] [PASSED] NTSC
[12:43:33] [PASSED] NTSC-J
[12:43:33] [PASSED] PAL
[12:43:33] [PASSED] PAL-M
[12:43:33] =========== [PASSED] drm_test_pick_cmdline_named ===========
[12:43:33] ============== [PASSED] drm_test_pick_cmdline ==============
[12:43:33] == drm_test_atomic_get_connector_for_encoder (1 subtest) ===
[12:43:33] [PASSED] drm_test_drm_atomic_get_connector_for_encoder
[12:43:33] ==== [PASSED] drm_test_atomic_get_connector_for_encoder ====
[12:43:33] =========== drm_validate_clone_mode (2 subtests) ===========
[12:43:33] ============== drm_test_check_in_clone_mode ===============
[12:43:33] [PASSED] in_clone_mode
[12:43:33] [PASSED] not_in_clone_mode
[12:43:33] ========== [PASSED] drm_test_check_in_clone_mode ===========
[12:43:33] =============== drm_test_check_valid_clones ===============
[12:43:33] [PASSED] not_in_clone_mode
[12:43:33] [PASSED] valid_clone
[12:43:33] [PASSED] invalid_clone
[12:43:33] =========== [PASSED] drm_test_check_valid_clones ===========
[12:43:33] ============= [PASSED] drm_validate_clone_mode =============
[12:43:33] ============= drm_validate_modeset (1 subtest) =============
[12:43:33] [PASSED] drm_test_check_connector_changed_modeset
[12:43:33] ============== [PASSED] drm_validate_modeset ===============
[12:43:33] ====== drm_test_bridge_get_current_state (1 subtest) =======
[12:43:33] [PASSED] drm_test_drm_bridge_get_current_state_atomic
[12:43:33] ======== [PASSED] drm_test_bridge_get_current_state ========
[12:43:33] ====== drm_test_bridge_helper_reset_crtc (3 subtests) ======
[12:43:33] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic
[12:43:33] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic_disabled
[12:43:33] [PASSED] drm_test_drm_bridge_helper_hdmi_output_bus_fmts
[12:43:33] ======== [PASSED] drm_test_bridge_helper_reset_crtc ========
[12:43:33] ============== drm_bridge_alloc (2 subtests) ===============
[12:43:33] [PASSED] drm_test_drm_bridge_alloc_basic
[12:43:33] [PASSED] drm_test_drm_bridge_alloc_get_put
[12:43:33] ================ [PASSED] drm_bridge_alloc =================
[12:43:33] ============= drm_bridge_bus_fmt (5 subtests) ==============
[12:43:33] [PASSED] drm_test_bridge_rgb_yuv_rgb
[12:43:33] [PASSED] drm_test_bridge_must_convert_to_yuv444
[12:43:33] [PASSED] drm_test_bridge_hdmi_auto_rgb
[12:43:33] [PASSED] drm_test_bridge_auto_first
[12:43:33] [PASSED] drm_test_bridge_rgb_yuv_no_path
[12:43:33] =============== [PASSED] drm_bridge_bus_fmt ================
[12:43:33] ============= drm_cmdline_parser (40 subtests) =============
[12:43:33] [PASSED] drm_test_cmdline_force_d_only
[12:43:33] [PASSED] drm_test_cmdline_force_D_only_dvi
[12:43:33] [PASSED] drm_test_cmdline_force_D_only_hdmi
[12:43:33] [PASSED] drm_test_cmdline_force_D_only_not_digital
[12:43:33] [PASSED] drm_test_cmdline_force_e_only
[12:43:33] [PASSED] drm_test_cmdline_res
[12:43:33] [PASSED] drm_test_cmdline_res_vesa
[12:43:33] [PASSED] drm_test_cmdline_res_vesa_rblank
[12:43:33] [PASSED] drm_test_cmdline_res_rblank
[12:43:33] [PASSED] drm_test_cmdline_res_bpp
[12:43:33] [PASSED] drm_test_cmdline_res_refresh
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_margins
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_force_off
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_analog
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_digital
[12:43:33] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on
[12:43:33] [PASSED] drm_test_cmdline_res_margins_force_on
[12:43:33] [PASSED] drm_test_cmdline_res_vesa_margins
[12:43:33] [PASSED] drm_test_cmdline_name
[12:43:33] [PASSED] drm_test_cmdline_name_bpp
[12:43:33] [PASSED] drm_test_cmdline_name_option
[12:43:33] [PASSED] drm_test_cmdline_name_bpp_option
[12:43:33] [PASSED] drm_test_cmdline_rotate_0
[12:43:33] [PASSED] drm_test_cmdline_rotate_90
[12:43:33] [PASSED] drm_test_cmdline_rotate_180
[12:43:33] [PASSED] drm_test_cmdline_rotate_270
[12:43:33] [PASSED] drm_test_cmdline_hmirror
[12:43:33] [PASSED] drm_test_cmdline_vmirror
[12:43:33] [PASSED] drm_test_cmdline_margin_options
[12:43:33] [PASSED] drm_test_cmdline_multiple_options
[12:43:33] [PASSED] drm_test_cmdline_bpp_extra_and_option
[12:43:33] [PASSED] drm_test_cmdline_extra_and_option
[12:43:33] [PASSED] drm_test_cmdline_freestanding_options
[12:43:33] [PASSED] drm_test_cmdline_freestanding_force_e_and_options
[12:43:33] [PASSED] drm_test_cmdline_panel_orientation
[12:43:33] ================ drm_test_cmdline_invalid =================
[12:43:33] [PASSED] margin_only
[12:43:33] [PASSED] interlace_only
[12:43:33] [PASSED] res_missing_x
[12:43:33] [PASSED] res_missing_y
[12:43:33] [PASSED] res_bad_y
[12:43:33] [PASSED] res_missing_y_bpp
[12:43:33] [PASSED] res_bad_bpp
[12:43:33] [PASSED] res_bad_refresh
[12:43:33] [PASSED] res_bpp_refresh_force_on_off
[12:43:33] [PASSED] res_invalid_mode
[12:43:33] [PASSED] res_bpp_wrong_place_mode
[12:43:33] [PASSED] name_bpp_refresh
[12:43:33] [PASSED] name_refresh
[12:43:33] [PASSED] name_refresh_wrong_mode
[12:43:33] [PASSED] name_refresh_invalid_mode
[12:43:33] [PASSED] rotate_multiple
[12:43:33] [PASSED] rotate_invalid_val
[12:43:33] [PASSED] rotate_truncated
[12:43:33] [PASSED] invalid_option
[12:43:33] [PASSED] invalid_tv_option
[12:43:33] [PASSED] truncated_tv_option
[12:43:33] ============ [PASSED] drm_test_cmdline_invalid =============
[12:43:33] =============== drm_test_cmdline_tv_options ===============
[12:43:33] [PASSED] NTSC
[12:43:33] [PASSED] NTSC_443
[12:43:33] [PASSED] NTSC_J
[12:43:33] [PASSED] PAL
[12:43:33] [PASSED] PAL_M
[12:43:33] [PASSED] PAL_N
[12:43:33] [PASSED] SECAM
[12:43:33] [PASSED] MONO_525
[12:43:33] [PASSED] MONO_625
[12:43:33] =========== [PASSED] drm_test_cmdline_tv_options ===========
[12:43:33] =============== [PASSED] drm_cmdline_parser ================
[12:43:33] ========== drmm_connector_hdmi_init (20 subtests) ==========
[12:43:33] [PASSED] drm_test_connector_hdmi_init_valid
[12:43:33] [PASSED] drm_test_connector_hdmi_init_bpc_8
[12:43:33] [PASSED] drm_test_connector_hdmi_init_bpc_10
[12:43:33] [PASSED] drm_test_connector_hdmi_init_bpc_12
[12:43:33] [PASSED] drm_test_connector_hdmi_init_bpc_invalid
[12:43:33] [PASSED] drm_test_connector_hdmi_init_bpc_null
[12:43:33] [PASSED] drm_test_connector_hdmi_init_formats_empty
[12:43:33] [PASSED] drm_test_connector_hdmi_init_formats_no_rgb
[12:43:33] === drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[12:43:33] [PASSED] supported_formats=0x9 yuv420_allowed=1
[12:43:33] [PASSED] supported_formats=0x9 yuv420_allowed=0
[12:43:33] [PASSED] supported_formats=0x5 yuv420_allowed=1
[12:43:33] [PASSED] supported_formats=0x5 yuv420_allowed=0
[12:43:33] === [PASSED] drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[12:43:33] [PASSED] drm_test_connector_hdmi_init_null_ddc
[12:43:33] [PASSED] drm_test_connector_hdmi_init_null_product
[12:43:33] [PASSED] drm_test_connector_hdmi_init_null_vendor
[12:43:33] [PASSED] drm_test_connector_hdmi_init_product_length_exact
[12:43:33] [PASSED] drm_test_connector_hdmi_init_product_length_too_long
[12:43:33] [PASSED] drm_test_connector_hdmi_init_product_valid
[12:43:33] [PASSED] drm_test_connector_hdmi_init_vendor_length_exact
[12:43:33] [PASSED] drm_test_connector_hdmi_init_vendor_length_too_long
[12:43:33] [PASSED] drm_test_connector_hdmi_init_vendor_valid
[12:43:33] ========= drm_test_connector_hdmi_init_type_valid =========
[12:43:33] [PASSED] HDMI-A
[12:43:33] [PASSED] HDMI-B
[12:43:33] ===== [PASSED] drm_test_connector_hdmi_init_type_valid =====
[12:43:33] ======== drm_test_connector_hdmi_init_type_invalid ========
[12:43:33] [PASSED] Unknown
[12:43:33] [PASSED] VGA
[12:43:33] [PASSED] DVI-I
[12:43:33] [PASSED] DVI-D
[12:43:33] [PASSED] DVI-A
[12:43:33] [PASSED] Composite
[12:43:33] [PASSED] SVIDEO
[12:43:33] [PASSED] LVDS
[12:43:33] [PASSED] Component
[12:43:33] [PASSED] DIN
[12:43:33] [PASSED] DP
[12:43:33] [PASSED] TV
[12:43:33] [PASSED] eDP
[12:43:33] [PASSED] Virtual
[12:43:33] [PASSED] DSI
[12:43:33] [PASSED] DPI
[12:43:33] [PASSED] Writeback
[12:43:33] [PASSED] SPI
[12:43:33] [PASSED] USB
[12:43:33] ==== [PASSED] drm_test_connector_hdmi_init_type_invalid ====
[12:43:33] ============ [PASSED] drmm_connector_hdmi_init =============
[12:43:33] ============= drmm_connector_init (3 subtests) =============
[12:43:33] [PASSED] drm_test_drmm_connector_init
[12:43:33] [PASSED] drm_test_drmm_connector_init_null_ddc
[12:43:33] ========= drm_test_drmm_connector_init_type_valid =========
[12:43:33] [PASSED] Unknown
[12:43:33] [PASSED] VGA
[12:43:33] [PASSED] DVI-I
[12:43:33] [PASSED] DVI-D
[12:43:33] [PASSED] DVI-A
[12:43:33] [PASSED] Composite
[12:43:33] [PASSED] SVIDEO
[12:43:33] [PASSED] LVDS
[12:43:33] [PASSED] Component
[12:43:33] [PASSED] DIN
[12:43:33] [PASSED] DP
[12:43:33] [PASSED] HDMI-A
[12:43:33] [PASSED] HDMI-B
[12:43:33] [PASSED] TV
[12:43:33] [PASSED] eDP
[12:43:33] [PASSED] Virtual
[12:43:33] [PASSED] DSI
[12:43:33] [PASSED] DPI
[12:43:33] [PASSED] Writeback
[12:43:33] [PASSED] SPI
[12:43:33] [PASSED] USB
[12:43:33] ===== [PASSED] drm_test_drmm_connector_init_type_valid =====
[12:43:33] =============== [PASSED] drmm_connector_init ===============
[12:43:33] ========= drm_connector_dynamic_init (6 subtests) ==========
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_init
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_init_null_ddc
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_init_not_added
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_init_properties
[12:43:33] ===== drm_test_drm_connector_dynamic_init_type_valid ======
[12:43:33] [PASSED] Unknown
[12:43:33] [PASSED] VGA
[12:43:33] [PASSED] DVI-I
[12:43:33] [PASSED] DVI-D
[12:43:33] [PASSED] DVI-A
[12:43:33] [PASSED] Composite
[12:43:33] [PASSED] SVIDEO
[12:43:33] [PASSED] LVDS
[12:43:33] [PASSED] Component
[12:43:33] [PASSED] DIN
[12:43:33] [PASSED] DP
[12:43:33] [PASSED] HDMI-A
[12:43:33] [PASSED] HDMI-B
[12:43:33] [PASSED] TV
[12:43:33] [PASSED] eDP
[12:43:33] [PASSED] Virtual
[12:43:33] [PASSED] DSI
[12:43:33] [PASSED] DPI
[12:43:33] [PASSED] Writeback
[12:43:33] [PASSED] SPI
[12:43:33] [PASSED] USB
[12:43:33] = [PASSED] drm_test_drm_connector_dynamic_init_type_valid ==
[12:43:33] ======== drm_test_drm_connector_dynamic_init_name =========
[12:43:33] [PASSED] Unknown
[12:43:33] [PASSED] VGA
[12:43:33] [PASSED] DVI-I
[12:43:33] [PASSED] DVI-D
[12:43:33] [PASSED] DVI-A
[12:43:33] [PASSED] Composite
[12:43:33] [PASSED] SVIDEO
[12:43:33] [PASSED] LVDS
[12:43:33] [PASSED] Component
[12:43:33] [PASSED] DIN
[12:43:33] [PASSED] DP
[12:43:33] [PASSED] HDMI-A
[12:43:33] [PASSED] HDMI-B
[12:43:33] [PASSED] TV
[12:43:33] [PASSED] eDP
[12:43:33] [PASSED] Virtual
[12:43:33] [PASSED] DSI
[12:43:33] [PASSED] DPI
[12:43:33] [PASSED] Writeback
[12:43:33] [PASSED] SPI
[12:43:33] [PASSED] USB
[12:43:33] ==== [PASSED] drm_test_drm_connector_dynamic_init_name =====
[12:43:33] =========== [PASSED] drm_connector_dynamic_init ============
[12:43:33] ==== drm_connector_dynamic_register_early (4 subtests) =====
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_early_on_list
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_early_defer
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_early_no_init
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_early_no_mode_object
[12:43:33] ====== [PASSED] drm_connector_dynamic_register_early =======
[12:43:33] ======= drm_connector_dynamic_register (7 subtests) ========
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_on_list
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_no_defer
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_no_init
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_mode_object
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_sysfs
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_sysfs_name
[12:43:33] [PASSED] drm_test_drm_connector_dynamic_register_debugfs
[12:43:33] ========= [PASSED] drm_connector_dynamic_register ==========
[12:43:33] = drm_connector_attach_broadcast_rgb_property (2 subtests) =
[12:43:33] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property
[12:43:33] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector
[12:43:33] === [PASSED] drm_connector_attach_broadcast_rgb_property ===
[12:43:33] ========== drm_get_tv_mode_from_name (2 subtests) ==========
[12:43:33] ========== drm_test_get_tv_mode_from_name_valid ===========
[12:43:33] [PASSED] NTSC
[12:43:33] [PASSED] NTSC-443
[12:43:33] [PASSED] NTSC-J
[12:43:33] [PASSED] PAL
[12:43:33] [PASSED] PAL-M
[12:43:33] [PASSED] PAL-N
[12:43:33] [PASSED] SECAM
[12:43:33] [PASSED] Mono
[12:43:33] ====== [PASSED] drm_test_get_tv_mode_from_name_valid =======
[12:43:33] [PASSED] drm_test_get_tv_mode_from_name_truncated
[12:43:33] ============ [PASSED] drm_get_tv_mode_from_name ============
[12:43:33] = drm_test_connector_hdmi_compute_mode_clock (12 subtests) =
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1
[12:43:33] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_double
[12:43:33] = drm_test_connector_hdmi_compute_mode_clock_yuv420_valid =
[12:43:33] [PASSED] VIC 96
[12:43:33] [PASSED] VIC 97
[12:43:33] [PASSED] VIC 101
[12:43:33] [PASSED] VIC 102
[12:43:33] [PASSED] VIC 106
[12:43:33] [PASSED] VIC 107
[12:43:33] === [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_valid ===
[12:43:33] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc
[12:43:33] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc
[12:43:33] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc
[12:43:33] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc
[12:43:33] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc
[12:43:33] === [PASSED] drm_test_connector_hdmi_compute_mode_clock ====
[12:43:33] == drm_hdmi_connector_get_broadcast_rgb_name (2 subtests) ==
[12:43:33] === drm_test_drm_hdmi_connector_get_broadcast_rgb_name ====
[12:43:33] [PASSED] Automatic
[12:43:33] [PASSED] Full
[12:43:33] [PASSED] Limited 16:235
[12:43:33] === [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name ===
[12:43:33] [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid
[12:43:33] ==== [PASSED] drm_hdmi_connector_get_broadcast_rgb_name ====
[12:43:33] == drm_hdmi_connector_get_output_format_name (2 subtests) ==
[12:43:33] === drm_test_drm_hdmi_connector_get_output_format_name ====
[12:43:33] [PASSED] RGB
[12:43:33] [PASSED] YUV 4:2:0
[12:43:33] [PASSED] YUV 4:2:2
[12:43:33] [PASSED] YUV 4:4:4
[12:43:33] === [PASSED] drm_test_drm_hdmi_connector_get_output_format_name ===
[12:43:33] [PASSED] drm_test_drm_hdmi_connector_get_output_format_name_invalid
[12:43:33] ==== [PASSED] drm_hdmi_connector_get_output_format_name ====
[12:43:33] ============= drm_damage_helper (21 subtests) ==============
[12:43:33] [PASSED] drm_test_damage_iter_no_damage
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_fractional_src
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_src_moved
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_fractional_src_moved
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_not_visible
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_no_crtc
[12:43:33] [PASSED] drm_test_damage_iter_no_damage_no_fb
[12:43:33] [PASSED] drm_test_damage_iter_simple_damage
[12:43:33] [PASSED] drm_test_damage_iter_single_damage
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_intersect_src
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_outside_src
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_fractional_src
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_intersect_fractional_src
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_outside_fractional_src
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_src_moved
[12:43:33] [PASSED] drm_test_damage_iter_single_damage_fractional_src_moved
[12:43:33] [PASSED] drm_test_damage_iter_damage
[12:43:33] [PASSED] drm_test_damage_iter_damage_one_intersect
[12:43:33] [PASSED] drm_test_damage_iter_damage_one_outside
[12:43:33] [PASSED] drm_test_damage_iter_damage_src_moved
[12:43:33] [PASSED] drm_test_damage_iter_damage_not_visible
[12:43:33] ================ [PASSED] drm_damage_helper ================
[12:43:33] ============== drm_dp_mst_helper (3 subtests) ==============
[12:43:33] ============== drm_test_dp_mst_calc_pbn_mode ==============
[12:43:33] [PASSED] Clock 154000 BPP 30 DSC disabled
[12:43:33] [PASSED] Clock 234000 BPP 30 DSC disabled
[12:43:33] [PASSED] Clock 297000 BPP 24 DSC disabled
[12:43:33] [PASSED] Clock 332880 BPP 24 DSC enabled
[12:43:33] [PASSED] Clock 324540 BPP 24 DSC enabled
[12:43:33] ========== [PASSED] drm_test_dp_mst_calc_pbn_mode ==========
[12:43:33] ============== drm_test_dp_mst_calc_pbn_div ===============
[12:43:33] [PASSED] Link rate 2000000 lane count 4
[12:43:33] [PASSED] Link rate 2000000 lane count 2
[12:43:33] [PASSED] Link rate 2000000 lane count 1
[12:43:33] [PASSED] Link rate 1350000 lane count 4
[12:43:33] [PASSED] Link rate 1350000 lane count 2
[12:43:33] [PASSED] Link rate 1350000 lane count 1
[12:43:33] [PASSED] Link rate 1000000 lane count 4
[12:43:33] [PASSED] Link rate 1000000 lane count 2
[12:43:33] [PASSED] Link rate 1000000 lane count 1
[12:43:33] [PASSED] Link rate 810000 lane count 4
[12:43:33] [PASSED] Link rate 810000 lane count 2
[12:43:33] [PASSED] Link rate 810000 lane count 1
[12:43:33] [PASSED] Link rate 540000 lane count 4
[12:43:33] [PASSED] Link rate 540000 lane count 2
[12:43:33] [PASSED] Link rate 540000 lane count 1
[12:43:33] [PASSED] Link rate 270000 lane count 4
[12:43:33] [PASSED] Link rate 270000 lane count 2
[12:43:33] [PASSED] Link rate 270000 lane count 1
[12:43:33] [PASSED] Link rate 162000 lane count 4
[12:43:33] [PASSED] Link rate 162000 lane count 2
[12:43:33] [PASSED] Link rate 162000 lane count 1
[12:43:33] ========== [PASSED] drm_test_dp_mst_calc_pbn_div ===========
[12:43:33] ========= drm_test_dp_mst_sideband_msg_req_decode =========
[12:43:33] [PASSED] DP_ENUM_PATH_RESOURCES with port number
[12:43:33] [PASSED] DP_POWER_UP_PHY with port number
[12:43:33] [PASSED] DP_POWER_DOWN_PHY with port number
[12:43:33] [PASSED] DP_ALLOCATE_PAYLOAD with SDP stream sinks
[12:43:33] [PASSED] DP_ALLOCATE_PAYLOAD with port number
[12:43:33] [PASSED] DP_ALLOCATE_PAYLOAD with VCPI
[12:43:33] [PASSED] DP_ALLOCATE_PAYLOAD with PBN
[12:43:33] [PASSED] DP_QUERY_PAYLOAD with port number
[12:43:33] [PASSED] DP_QUERY_PAYLOAD with VCPI
[12:43:33] [PASSED] DP_REMOTE_DPCD_READ with port number
[12:43:33] [PASSED] DP_REMOTE_DPCD_READ with DPCD address
[12:43:33] [PASSED] DP_REMOTE_DPCD_READ with max number of bytes
[12:43:33] [PASSED] DP_REMOTE_DPCD_WRITE with port number
[12:43:33] [PASSED] DP_REMOTE_DPCD_WRITE with DPCD address
[12:43:33] [PASSED] DP_REMOTE_DPCD_WRITE with data array
[12:43:33] [PASSED] DP_REMOTE_I2C_READ with port number
[12:43:33] [PASSED] DP_REMOTE_I2C_READ with I2C device ID
[12:43:33] [PASSED] DP_REMOTE_I2C_READ with transactions array
[12:43:33] [PASSED] DP_REMOTE_I2C_WRITE with port number
[12:43:33] [PASSED] DP_REMOTE_I2C_WRITE with I2C device ID
[12:43:33] [PASSED] DP_REMOTE_I2C_WRITE with data array
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream ID
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with client ID
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream event
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with valid stream event
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream behavior
[12:43:33] [PASSED] DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior
[12:43:33] ===== [PASSED] drm_test_dp_mst_sideband_msg_req_decode =====
[12:43:33] ================ [PASSED] drm_dp_mst_helper ================
[12:43:33] ================== drm_exec (7 subtests) ===================
[12:43:33] [PASSED] sanitycheck
[12:43:33] [PASSED] test_lock
[12:43:33] [PASSED] test_lock_unlock
[12:43:33] [PASSED] test_duplicates
[12:43:33] [PASSED] test_prepare
[12:43:33] [PASSED] test_prepare_array
[12:43:33] [PASSED] test_multiple_loops
[12:43:33] ==================== [PASSED] drm_exec =====================
[12:43:33] =========== drm_format_helper_test (17 subtests) ===========
[12:43:33] ============== drm_test_fb_xrgb8888_to_gray8 ==============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========== [PASSED] drm_test_fb_xrgb8888_to_gray8 ==========
[12:43:33] ============= drm_test_fb_xrgb8888_to_rgb332 ==============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb332 ==========
[12:43:33] ============= drm_test_fb_xrgb8888_to_rgb565 ==============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb565 ==========
[12:43:33] ============ drm_test_fb_xrgb8888_to_xrgb1555 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_xrgb1555 =========
[12:43:33] ============ drm_test_fb_xrgb8888_to_argb1555 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_argb1555 =========
[12:43:33] ============ drm_test_fb_xrgb8888_to_rgba5551 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_rgba5551 =========
[12:43:33] ============= drm_test_fb_xrgb8888_to_rgb888 ==============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb888 ==========
[12:43:33] ============= drm_test_fb_xrgb8888_to_bgr888 ==============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========= [PASSED] drm_test_fb_xrgb8888_to_bgr888 ==========
[12:43:33] ============ drm_test_fb_xrgb8888_to_argb8888 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_argb8888 =========
[12:43:33] =========== drm_test_fb_xrgb8888_to_xrgb2101010 ===========
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======= [PASSED] drm_test_fb_xrgb8888_to_xrgb2101010 =======
[12:43:33] =========== drm_test_fb_xrgb8888_to_argb2101010 ===========
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======= [PASSED] drm_test_fb_xrgb8888_to_argb2101010 =======
[12:43:33] ============== drm_test_fb_xrgb8888_to_mono ===============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ========== [PASSED] drm_test_fb_xrgb8888_to_mono ===========
[12:43:33] ==================== drm_test_fb_swab =====================
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ================ [PASSED] drm_test_fb_swab =================
[12:43:33] ============ drm_test_fb_xrgb8888_to_xbgr8888 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_xbgr8888 =========
[12:43:33] ============ drm_test_fb_xrgb8888_to_abgr8888 =============
[12:43:33] [PASSED] single_pixel_source_buffer
[12:43:33] [PASSED] single_pixel_clip_rectangle
[12:43:33] [PASSED] well_known_colors
[12:43:33] [PASSED] destination_pitch
[12:43:33] ======== [PASSED] drm_test_fb_xrgb8888_to_abgr8888 =========
[12:43:33] ================= drm_test_fb_clip_offset =================
[12:43:33] [PASSED] pass through
[12:43:33] [PASSED] horizontal offset
[12:43:33] [PASSED] vertical offset
[12:43:33] [PASSED] horizontal and vertical offset
[12:43:33] [PASSED] horizontal offset (custom pitch)
[12:43:33] [PASSED] vertical offset (custom pitch)
[12:43:33] [PASSED] horizontal and vertical offset (custom pitch)
[12:43:33] ============= [PASSED] drm_test_fb_clip_offset =============
[12:43:33] =================== drm_test_fb_memcpy ====================
[12:43:33] [PASSED] single_pixel_source_buffer: XR24 little-endian (0x34325258)
[12:43:33] [PASSED] single_pixel_source_buffer: XRA8 little-endian (0x38415258)
[12:43:33] [PASSED] single_pixel_source_buffer: YU24 little-endian (0x34325559)
[12:43:33] [PASSED] single_pixel_clip_rectangle: XB24 little-endian (0x34324258)
[12:43:33] [PASSED] single_pixel_clip_rectangle: XRA8 little-endian (0x38415258)
[12:43:33] [PASSED] single_pixel_clip_rectangle: YU24 little-endian (0x34325559)
[12:43:33] [PASSED] well_known_colors: XB24 little-endian (0x34324258)
[12:43:33] [PASSED] well_known_colors: XRA8 little-endian (0x38415258)
[12:43:33] [PASSED] well_known_colors: YU24 little-endian (0x34325559)
[12:43:33] [PASSED] destination_pitch: XB24 little-endian (0x34324258)
[12:43:33] [PASSED] destination_pitch: XRA8 little-endian (0x38415258)
[12:43:33] [PASSED] destination_pitch: YU24 little-endian (0x34325559)
[12:43:33] =============== [PASSED] drm_test_fb_memcpy ================
[12:43:33] ============= [PASSED] drm_format_helper_test ==============
[12:43:33] ================= drm_format (18 subtests) =================
[12:43:33] [PASSED] drm_test_format_block_width_invalid
[12:43:33] [PASSED] drm_test_format_block_width_one_plane
[12:43:33] [PASSED] drm_test_format_block_width_two_plane
[12:43:33] [PASSED] drm_test_format_block_width_three_plane
[12:43:33] [PASSED] drm_test_format_block_width_tiled
[12:43:33] [PASSED] drm_test_format_block_height_invalid
[12:43:33] [PASSED] drm_test_format_block_height_one_plane
[12:43:33] [PASSED] drm_test_format_block_height_two_plane
[12:43:33] [PASSED] drm_test_format_block_height_three_plane
[12:43:33] [PASSED] drm_test_format_block_height_tiled
[12:43:33] [PASSED] drm_test_format_min_pitch_invalid
[12:43:33] [PASSED] drm_test_format_min_pitch_one_plane_8bpp
[12:43:33] [PASSED] drm_test_format_min_pitch_one_plane_16bpp
[12:43:33] [PASSED] drm_test_format_min_pitch_one_plane_24bpp
[12:43:33] [PASSED] drm_test_format_min_pitch_one_plane_32bpp
[12:43:33] [PASSED] drm_test_format_min_pitch_two_plane
[12:43:33] [PASSED] drm_test_format_min_pitch_three_plane_8bpp
[12:43:33] [PASSED] drm_test_format_min_pitch_tiled
[12:43:33] =================== [PASSED] drm_format ====================
[12:43:33] ============== drm_framebuffer (10 subtests) ===============
[12:43:33] ========== drm_test_framebuffer_check_src_coords ==========
[12:43:33] [PASSED] Success: source fits into fb
[12:43:33] [PASSED] Fail: overflowing fb with x-axis coordinate
[12:43:33] [PASSED] Fail: overflowing fb with y-axis coordinate
[12:43:33] [PASSED] Fail: overflowing fb with source width
[12:43:33] [PASSED] Fail: overflowing fb with source height
[12:43:33] ====== [PASSED] drm_test_framebuffer_check_src_coords ======
[12:43:33] [PASSED] drm_test_framebuffer_cleanup
[12:43:33] =============== drm_test_framebuffer_create ===============
[12:43:33] [PASSED] ABGR8888 normal sizes
[12:43:33] [PASSED] ABGR8888 max sizes
[12:43:33] [PASSED] ABGR8888 pitch greater than min required
[12:43:33] [PASSED] ABGR8888 pitch less than min required
[12:43:33] [PASSED] ABGR8888 Invalid width
[12:43:33] [PASSED] ABGR8888 Invalid buffer handle
[12:43:33] [PASSED] No pixel format
[12:43:33] [PASSED] ABGR8888 Width 0
[12:43:33] [PASSED] ABGR8888 Height 0
[12:43:33] [PASSED] ABGR8888 Out of bound height * pitch combination
[12:43:33] [PASSED] ABGR8888 Large buffer offset
[12:43:33] [PASSED] ABGR8888 Buffer offset for inexistent plane
[12:43:33] [PASSED] ABGR8888 Invalid flag
[12:43:33] [PASSED] ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers
[12:43:33] [PASSED] ABGR8888 Valid buffer modifier
[12:43:33] [PASSED] ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
[12:43:33] [PASSED] ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] NV12 Normal sizes
[12:43:33] [PASSED] NV12 Max sizes
[12:43:33] [PASSED] NV12 Invalid pitch
[12:43:33] [PASSED] NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag
[12:43:33] [PASSED] NV12 different modifier per-plane
[12:43:33] [PASSED] NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
[12:43:33] [PASSED] NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] NV12 Modifier for inexistent plane
[12:43:33] [PASSED] NV12 Handle for inexistent plane
[12:43:33] [PASSED] NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] YVU420 DRM_MODE_FB_MODIFIERS set without modifier
[12:43:33] [PASSED] YVU420 Normal sizes
[12:43:33] [PASSED] YVU420 Max sizes
[12:43:33] [PASSED] YVU420 Invalid pitch
[12:43:33] [PASSED] YVU420 Different pitches
[12:43:33] [PASSED] YVU420 Different buffer offsets/pitches
[12:43:33] [PASSED] YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS
[12:43:33] [PASSED] YVU420 Valid modifier
[12:43:33] [PASSED] YVU420 Different modifiers per plane
[12:43:33] [PASSED] YVU420 Modifier for inexistent plane
[12:43:33] [PASSED] YUV420_10BIT Invalid modifier(DRM_FORMAT_MOD_LINEAR)
[12:43:33] [PASSED] X0L2 Normal sizes
[12:43:33] [PASSED] X0L2 Max sizes
[12:43:33] [PASSED] X0L2 Invalid pitch
[12:43:33] [PASSED] X0L2 Pitch greater than minimum required
[12:43:33] [PASSED] X0L2 Handle for inexistent plane
[12:43:33] [PASSED] X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set
[12:43:33] [PASSED] X0L2 Modifier without DRM_MODE_FB_MODIFIERS set
[12:43:33] [PASSED] X0L2 Valid modifier
[12:43:33] [PASSED] X0L2 Modifier for inexistent plane
[12:43:33] =========== [PASSED] drm_test_framebuffer_create ===========
[12:43:33] [PASSED] drm_test_framebuffer_free
[12:43:33] [PASSED] drm_test_framebuffer_init
[12:43:33] [PASSED] drm_test_framebuffer_init_bad_format
[12:43:33] [PASSED] drm_test_framebuffer_init_dev_mismatch
[12:43:33] [PASSED] drm_test_framebuffer_lookup
[12:43:33] [PASSED] drm_test_framebuffer_lookup_inexistent
[12:43:33] [PASSED] drm_test_framebuffer_modifiers_not_supported
[12:43:33] ================= [PASSED] drm_framebuffer =================
[12:43:33] ================ drm_gem_shmem (8 subtests) ================
[12:43:33] [PASSED] drm_gem_shmem_test_obj_create
[12:43:33] [PASSED] drm_gem_shmem_test_obj_create_private
[12:43:33] [PASSED] drm_gem_shmem_test_pin_pages
[12:43:33] [PASSED] drm_gem_shmem_test_vmap
[12:43:33] [PASSED] drm_gem_shmem_test_get_sg_table
[12:43:33] [PASSED] drm_gem_shmem_test_get_pages_sgt
[12:43:33] [PASSED] drm_gem_shmem_test_madvise
[12:43:33] [PASSED] drm_gem_shmem_test_purge
[12:43:33] ================== [PASSED] drm_gem_shmem ==================
[12:43:33] === drm_atomic_helper_connector_hdmi_check (29 subtests) ===
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode_vic_1
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode_vic_1
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode_vic_1
[12:43:33] ====== drm_test_check_broadcast_rgb_cea_mode_yuv420 =======
[12:43:33] [PASSED] Automatic
[12:43:33] [PASSED] Full
[12:43:33] [PASSED] Limited 16:235
[12:43:33] == [PASSED] drm_test_check_broadcast_rgb_cea_mode_yuv420 ===
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_changed
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_not_changed
[12:43:33] [PASSED] drm_test_check_disable_connector
[12:43:33] [PASSED] drm_test_check_hdmi_funcs_reject_rate
[12:43:33] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_rgb
[12:43:33] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_yuv420
[12:43:33] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422
[12:43:33] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420
[12:43:33] [PASSED] drm_test_check_driver_unsupported_fallback_yuv420
[12:43:33] [PASSED] drm_test_check_output_bpc_crtc_mode_changed
[12:43:33] [PASSED] drm_test_check_output_bpc_crtc_mode_not_changed
[12:43:33] [PASSED] drm_test_check_output_bpc_dvi
[12:43:33] [PASSED] drm_test_check_output_bpc_format_vic_1
[12:43:33] [PASSED] drm_test_check_output_bpc_format_display_8bpc_only
[12:43:33] [PASSED] drm_test_check_output_bpc_format_display_rgb_only
[12:43:33] [PASSED] drm_test_check_output_bpc_format_driver_8bpc_only
[12:43:33] [PASSED] drm_test_check_output_bpc_format_driver_rgb_only
[12:43:33] [PASSED] drm_test_check_tmds_char_rate_rgb_8bpc
[12:43:33] [PASSED] drm_test_check_tmds_char_rate_rgb_10bpc
[12:43:33] [PASSED] drm_test_check_tmds_char_rate_rgb_12bpc
[12:43:33] ============ drm_test_check_hdmi_color_format =============
[12:43:33] [PASSED] AUTO -> RGB
[12:43:33] [PASSED] YCBCR422 -> YUV422
[12:43:33] [PASSED] YCBCR420 -> YUV420
[12:43:33] [PASSED] YCBCR444 -> YUV444
[12:43:33] [PASSED] RGB -> RGB
[12:43:33] ======== [PASSED] drm_test_check_hdmi_color_format =========
[12:43:33] ======== drm_test_check_hdmi_color_format_420_only ========
[12:43:33] [PASSED] RGB should fail
[12:43:33] [PASSED] YUV444 should fail
[12:43:33] [PASSED] YUV422 should fail
[12:43:33] [PASSED] YUV420 should work
[12:43:33] ==== [PASSED] drm_test_check_hdmi_color_format_420_only ====
[12:43:33] ===== [PASSED] drm_atomic_helper_connector_hdmi_check ======
[12:43:33] === drm_atomic_helper_connector_hdmi_reset (6 subtests) ====
[12:43:33] [PASSED] drm_test_check_broadcast_rgb_value
[12:43:33] [PASSED] drm_test_check_bpc_8_value
[12:43:33] [PASSED] drm_test_check_bpc_10_value
[12:43:33] [PASSED] drm_test_check_bpc_12_value
[12:43:33] [PASSED] drm_test_check_format_value
[12:43:33] [PASSED] drm_test_check_tmds_char_value
[12:43:33] ===== [PASSED] drm_atomic_helper_connector_hdmi_reset ======
[12:43:33] = drm_atomic_helper_connector_hdmi_mode_valid (7 subtests) =
[12:43:33] [PASSED] drm_test_check_mode_valid
[12:43:33] [PASSED] drm_test_check_mode_valid_reject
[12:43:33] [PASSED] drm_test_check_mode_valid_reject_rate
[12:43:33] [PASSED] drm_test_check_mode_valid_reject_max_clock
[12:43:33] [PASSED] drm_test_check_mode_valid_yuv420_only_max_clock
[12:43:33] [PASSED] drm_test_check_mode_valid_reject_yuv420_only_connector
[12:43:33] [PASSED] drm_test_check_mode_valid_accept_yuv420_also_connector_rgb
[12:43:33] === [PASSED] drm_atomic_helper_connector_hdmi_mode_valid ===
[12:43:33] = drm_atomic_helper_connector_hdmi_infoframes (5 subtests) =
[12:43:33] [PASSED] drm_test_check_infoframes
[12:43:33] [PASSED] drm_test_check_reject_avi_infoframe
[12:43:33] [PASSED] drm_test_check_reject_hdr_infoframe_bpc_8
[12:43:33] [PASSED] drm_test_check_reject_hdr_infoframe_bpc_10
[12:43:33] [PASSED] drm_test_check_reject_audio_infoframe
[12:43:33] === [PASSED] drm_atomic_helper_connector_hdmi_infoframes ===
[12:43:33] ================= drm_managed (2 subtests) =================
[12:43:33] [PASSED] drm_test_managed_release_action
[12:43:33] [PASSED] drm_test_managed_run_action
[12:43:33] =================== [PASSED] drm_managed ===================
[12:43:33] =================== drm_mm (6 subtests) ====================
[12:43:33] [PASSED] drm_test_mm_init
[12:43:33] [PASSED] drm_test_mm_debug
[12:43:33] [PASSED] drm_test_mm_align32
[12:43:33] [PASSED] drm_test_mm_align64
[12:43:33] [PASSED] drm_test_mm_lowest
[12:43:33] [PASSED] drm_test_mm_highest
[12:43:33] ===================== [PASSED] drm_mm ======================
[12:43:33] ============= drm_modes_analog_tv (5 subtests) =============
[12:43:33] [PASSED] drm_test_modes_analog_tv_mono_576i
[12:43:33] [PASSED] drm_test_modes_analog_tv_ntsc_480i
[12:43:33] [PASSED] drm_test_modes_analog_tv_ntsc_480i_inlined
[12:43:33] [PASSED] drm_test_modes_analog_tv_pal_576i
[12:43:33] [PASSED] drm_test_modes_analog_tv_pal_576i_inlined
[12:43:33] =============== [PASSED] drm_modes_analog_tv ===============
[12:43:33] ============== drm_panic_helper (3 subtests) ===============
[12:43:33] ============= drm_test_panic_screen_user_map ==============
[12:43:33] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] ========= [PASSED] drm_test_panic_screen_user_map ==========
[12:43:34] ============= drm_test_panic_screen_user_page =============
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] ========= [PASSED] drm_test_panic_screen_user_page =========
[12:43:34] ========== drm_test_panic_screen_user_set_pixel ===========
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:43:34] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:43:34] ====== [PASSED] drm_test_panic_screen_user_set_pixel =======
[12:43:34] ================ [PASSED] drm_panic_helper =================
[12:43:34] ============== drm_plane_helper (2 subtests) ===============
[12:43:34] =============== drm_test_check_plane_state ================
[12:43:34] [PASSED] clipping_simple
[12:43:34] [PASSED] clipping_rotate_reflect
[12:43:34] [PASSED] positioning_simple
[12:43:34] [PASSED] upscaling
[12:43:34] [PASSED] downscaling
[12:43:34] [PASSED] rounding1
[12:43:34] [PASSED] rounding2
[12:43:34] [PASSED] rounding3
[12:43:34] [PASSED] rounding4
[12:43:34] =========== [PASSED] drm_test_check_plane_state ============
[12:43:34] =========== drm_test_check_invalid_plane_state ============
[12:43:34] [PASSED] positioning_invalid
[12:43:34] [PASSED] upscaling_invalid
[12:43:34] [PASSED] downscaling_invalid
[12:43:34] ======= [PASSED] drm_test_check_invalid_plane_state ========
[12:43:34] ================ [PASSED] drm_plane_helper =================
[12:43:34] ====== drm_connector_helper_tv_get_modes (1 subtest) =======
[12:43:34] ====== drm_test_connector_helper_tv_get_modes_check =======
[12:43:34] [PASSED] None
[12:43:34] [PASSED] PAL
[12:43:34] [PASSED] NTSC
[12:43:34] [PASSED] Both, NTSC Default
[12:43:34] [PASSED] Both, PAL Default
[12:43:34] [PASSED] Both, NTSC Default, with PAL on command-line
[12:43:34] [PASSED] Both, PAL Default, with NTSC on command-line
[12:43:34] == [PASSED] drm_test_connector_helper_tv_get_modes_check ===
[12:43:34] ======== [PASSED] drm_connector_helper_tv_get_modes ========
[12:43:34] ================== drm_rect (9 subtests) ===================
[12:43:34] [PASSED] drm_test_rect_clip_scaled_div_by_zero
[12:43:34] [PASSED] drm_test_rect_clip_scaled_not_clipped
[12:43:34] [PASSED] drm_test_rect_clip_scaled_clipped
[12:43:34] [PASSED] drm_test_rect_clip_scaled_signed_vs_unsigned
[12:43:34] ================= drm_test_rect_intersect =================
[12:43:34] [PASSED] top-left x bottom-right: 2x2+1+1 x 2x2+0+0
[12:43:34] [PASSED] top-right x bottom-left: 2x2+0+0 x 2x2+1-1
[12:43:34] [PASSED] bottom-left x top-right: 2x2+1-1 x 2x2+0+0
[12:43:34] [PASSED] bottom-right x top-left: 2x2+0+0 x 2x2+1+1
[12:43:34] [PASSED] right x left: 2x1+0+0 x 3x1+1+0
[12:43:34] [PASSED] left x right: 3x1+1+0 x 2x1+0+0
[12:43:34] [PASSED] up x bottom: 1x2+0+0 x 1x3+0-1
[12:43:34] [PASSED] bottom x up: 1x3+0-1 x 1x2+0+0
[12:43:34] [PASSED] touching corner: 1x1+0+0 x 2x2+1+1
[12:43:34] [PASSED] touching side: 1x1+0+0 x 1x1+1+0
[12:43:34] [PASSED] equal rects: 2x2+0+0 x 2x2+0+0
[12:43:34] [PASSED] inside another: 2x2+0+0 x 1x1+1+1
[12:43:34] [PASSED] far away: 1x1+0+0 x 1x1+3+6
[12:43:34] [PASSED] points intersecting: 0x0+5+10 x 0x0+5+10
[12:43:34] [PASSED] points not intersecting: 0x0+0+0 x 0x0+5+10
[12:43:34] ============= [PASSED] drm_test_rect_intersect =============
[12:43:34] ================ drm_test_rect_calc_hscale ================
[12:43:34] [PASSED] normal use
[12:43:34] [PASSED] out of max range
[12:43:34] [PASSED] out of min range
[12:43:34] [PASSED] zero dst
[12:43:34] [PASSED] negative src
[12:43:34] [PASSED] negative dst
[12:43:34] ============ [PASSED] drm_test_rect_calc_hscale ============
[12:43:34] ================ drm_test_rect_calc_vscale ================
[12:43:34] [PASSED] normal use
[12:43:34] [PASSED] out of max range
[12:43:34] [PASSED] out of min range
[12:43:34] [PASSED] zero dst
[12:43:34] [PASSED] negative src
[12:43:34] [PASSED] negative dst
[12:43:34] ============ [PASSED] drm_test_rect_calc_vscale ============
[12:43:34] ================== drm_test_rect_rotate ===================
[12:43:34] [PASSED] reflect-x
[12:43:34] [PASSED] reflect-y
[12:43:34] [PASSED] rotate-0
[12:43:34] [PASSED] rotate-90
[12:43:34] [PASSED] rotate-180
[12:43:34] [PASSED] rotate-270
[12:43:34] ============== [PASSED] drm_test_rect_rotate ===============
[12:43:34] ================ drm_test_rect_rotate_inv =================
[12:43:34] [PASSED] reflect-x
[12:43:34] [PASSED] reflect-y
[12:43:34] [PASSED] rotate-0
[12:43:34] [PASSED] rotate-90
[12:43:34] [PASSED] rotate-180
[12:43:34] [PASSED] rotate-270
[12:43:34] ============ [PASSED] drm_test_rect_rotate_inv =============
[12:43:34] ==================== [PASSED] drm_rect =====================
[12:43:34] ============ drm_sysfb_modeset_test (1 subtest) ============
[12:43:34] ============ drm_test_sysfb_build_fourcc_list =============
[12:43:34] [PASSED] no native formats
[12:43:34] [PASSED] XRGB8888 as native format
[12:43:34] [PASSED] remove duplicates
[12:43:34] [PASSED] convert alpha formats
[12:43:34] [PASSED] random formats
[12:43:34] ======== [PASSED] drm_test_sysfb_build_fourcc_list =========
[12:43:34] ============= [PASSED] drm_sysfb_modeset_test ==============
[12:43:34] ================== drm_fixp (2 subtests) ===================
[12:43:34] [PASSED] drm_test_int2fixp
[12:43:34] [PASSED] drm_test_sm2fixp
[12:43:34] ==================== [PASSED] drm_fixp =====================
[12:43:34] ============================================================
[12:43:34] Testing complete. Ran 667 tests: passed: 667
[12:43:34] Elapsed time: 27.918s total, 2.529s configuring, 24.972s building, 0.405s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/ttm/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/ttm/tests/.kunitconfig
[12:43:34] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:43:36] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:43:47] Starting KUnit Kernel (1/1)...
[12:43:47] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:43:47] ================= ttm_device (5 subtests) ==================
[12:43:47] [PASSED] ttm_device_init_basic
[12:43:47] [PASSED] ttm_device_init_multiple
[12:43:47] [PASSED] ttm_device_fini_basic
[12:43:47] [PASSED] ttm_device_init_no_vma_man
[12:43:47] ================== ttm_device_init_pools ==================
[12:43:47] [PASSED] No DMA allocations, no DMA32 required
[12:43:47] [PASSED] DMA allocations, DMA32 required
[12:43:47] [PASSED] No DMA allocations, DMA32 required
[12:43:47] [PASSED] DMA allocations, no DMA32 required
[12:43:47] ============== [PASSED] ttm_device_init_pools ==============
[12:43:47] =================== [PASSED] ttm_device ====================
[12:43:47] ================== ttm_pool (8 subtests) ===================
[12:43:47] ================== ttm_pool_alloc_basic ===================
[12:43:47] [PASSED] One page
[12:43:47] [PASSED] More than one page
[12:43:47] [PASSED] Above the allocation limit
[12:43:47] [PASSED] One page, with coherent DMA mappings enabled
[12:43:47] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[12:43:47] ============== [PASSED] ttm_pool_alloc_basic ===============
[12:43:47] ============== ttm_pool_alloc_basic_dma_addr ==============
[12:43:47] [PASSED] One page
[12:43:47] [PASSED] More than one page
[12:43:47] [PASSED] Above the allocation limit
[12:43:47] [PASSED] One page, with coherent DMA mappings enabled
[12:43:47] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[12:43:47] ========== [PASSED] ttm_pool_alloc_basic_dma_addr ==========
[12:43:47] [PASSED] ttm_pool_alloc_order_caching_match
[12:43:47] [PASSED] ttm_pool_alloc_caching_mismatch
[12:43:47] [PASSED] ttm_pool_alloc_order_mismatch
[12:43:47] [PASSED] ttm_pool_free_dma_alloc
[12:43:47] [PASSED] ttm_pool_free_no_dma_alloc
[12:43:47] [PASSED] ttm_pool_fini_basic
[12:43:47] ==================== [PASSED] ttm_pool =====================
[12:43:47] ================ ttm_resource (8 subtests) =================
[12:43:47] ================= ttm_resource_init_basic =================
[12:43:47] [PASSED] Init resource in TTM_PL_SYSTEM
[12:43:47] [PASSED] Init resource in TTM_PL_VRAM
[12:43:47] [PASSED] Init resource in a private placement
[12:43:47] [PASSED] Init resource in TTM_PL_SYSTEM, set placement flags
[12:43:47] ============= [PASSED] ttm_resource_init_basic =============
[12:43:47] [PASSED] ttm_resource_init_pinned
[12:43:47] [PASSED] ttm_resource_fini_basic
[12:43:47] [PASSED] ttm_resource_manager_init_basic
[12:43:47] [PASSED] ttm_resource_manager_usage_basic
[12:43:47] [PASSED] ttm_resource_manager_set_used_basic
[12:43:47] [PASSED] ttm_sys_man_alloc_basic
[12:43:47] [PASSED] ttm_sys_man_free_basic
[12:43:47] ================== [PASSED] ttm_resource ===================
[12:43:47] =================== ttm_tt (15 subtests) ===================
[12:43:47] ==================== ttm_tt_init_basic ====================
[12:43:47] [PASSED] Page-aligned size
[12:43:47] [PASSED] Extra pages requested
[12:43:47] ================ [PASSED] ttm_tt_init_basic ================
[12:43:47] [PASSED] ttm_tt_init_misaligned
[12:43:47] [PASSED] ttm_tt_fini_basic
[12:43:47] [PASSED] ttm_tt_fini_sg
[12:43:47] [PASSED] ttm_tt_fini_shmem
[12:43:47] [PASSED] ttm_tt_create_basic
[12:43:47] [PASSED] ttm_tt_create_invalid_bo_type
[12:43:47] [PASSED] ttm_tt_create_ttm_exists
[12:43:47] [PASSED] ttm_tt_create_failed
[12:43:47] [PASSED] ttm_tt_destroy_basic
[12:43:47] [PASSED] ttm_tt_populate_null_ttm
[12:43:47] [PASSED] ttm_tt_populate_populated_ttm
[12:43:47] [PASSED] ttm_tt_unpopulate_basic
[12:43:47] [PASSED] ttm_tt_unpopulate_empty_ttm
[12:43:47] [PASSED] ttm_tt_swapin_basic
[12:43:47] ===================== [PASSED] ttm_tt ======================
[12:43:47] =================== ttm_bo (14 subtests) ===================
[12:43:47] =========== ttm_bo_reserve_optimistic_no_ticket ===========
[12:43:47] [PASSED] Cannot be interrupted and sleeps
[12:43:47] [PASSED] Cannot be interrupted, locks straight away
[12:43:47] [PASSED] Can be interrupted, sleeps
[12:43:47] ======= [PASSED] ttm_bo_reserve_optimistic_no_ticket =======
[12:43:47] [PASSED] ttm_bo_reserve_locked_no_sleep
[12:43:47] [PASSED] ttm_bo_reserve_no_wait_ticket
[12:43:47] [PASSED] ttm_bo_reserve_double_resv
[12:43:47] [PASSED] ttm_bo_reserve_interrupted
[12:43:47] [PASSED] ttm_bo_reserve_deadlock
[12:43:47] [PASSED] ttm_bo_unreserve_basic
[12:43:47] [PASSED] ttm_bo_unreserve_pinned
[12:43:47] [PASSED] ttm_bo_unreserve_bulk
[12:43:47] [PASSED] ttm_bo_fini_basic
[12:43:47] [PASSED] ttm_bo_fini_shared_resv
[12:43:47] [PASSED] ttm_bo_pin_basic
[12:43:47] [PASSED] ttm_bo_pin_unpin_resource
[12:43:47] [PASSED] ttm_bo_multiple_pin_one_unpin
[12:43:47] ===================== [PASSED] ttm_bo ======================
[12:43:47] ============== ttm_bo_validate (22 subtests) ===============
[12:43:47] ============== ttm_bo_init_reserved_sys_man ===============
[12:43:47] [PASSED] Buffer object for userspace
[12:43:47] [PASSED] Kernel buffer object
[12:43:47] [PASSED] Shared buffer object
[12:43:47] ========== [PASSED] ttm_bo_init_reserved_sys_man ===========
[12:43:47] ============== ttm_bo_init_reserved_mock_man ==============
[12:43:47] [PASSED] Buffer object for userspace
[12:43:47] [PASSED] Kernel buffer object
[12:43:47] [PASSED] Shared buffer object
[12:43:47] ========== [PASSED] ttm_bo_init_reserved_mock_man ==========
[12:43:47] [PASSED] ttm_bo_init_reserved_resv
[12:43:47] ================== ttm_bo_validate_basic ==================
[12:43:47] [PASSED] Buffer object for userspace
[12:43:47] [PASSED] Kernel buffer object
[12:43:47] [PASSED] Shared buffer object
[12:43:47] ============== [PASSED] ttm_bo_validate_basic ==============
[12:43:47] [PASSED] ttm_bo_validate_invalid_placement
[12:43:47] ============= ttm_bo_validate_same_placement ==============
[12:43:47] [PASSED] System manager
[12:43:47] [PASSED] VRAM manager
[12:43:47] ========= [PASSED] ttm_bo_validate_same_placement ==========
[12:43:47] [PASSED] ttm_bo_validate_failed_alloc
[12:43:47] [PASSED] ttm_bo_validate_pinned
[12:43:47] [PASSED] ttm_bo_validate_busy_placement
[12:43:47] ================ ttm_bo_validate_multihop =================
[12:43:47] [PASSED] Buffer object for userspace
[12:43:47] [PASSED] Kernel buffer object
[12:43:47] [PASSED] Shared buffer object
[12:43:47] ============ [PASSED] ttm_bo_validate_multihop =============
[12:43:47] ========== ttm_bo_validate_no_placement_signaled ==========
[12:43:47] [PASSED] Buffer object in system domain, no page vector
[12:43:47] [PASSED] Buffer object in system domain with an existing page vector
[12:43:47] ====== [PASSED] ttm_bo_validate_no_placement_signaled ======
[12:43:47] ======== ttm_bo_validate_no_placement_not_signaled ========
[12:43:47] [PASSED] Buffer object for userspace
[12:43:47] [PASSED] Kernel buffer object
[12:43:47] [PASSED] Shared buffer object
[12:43:47] ==== [PASSED] ttm_bo_validate_no_placement_not_signaled ====
[12:43:47] [PASSED] ttm_bo_validate_move_fence_signaled
[12:43:47] ========= ttm_bo_validate_move_fence_not_signaled =========
[12:43:47] [PASSED] Waits for GPU
[12:43:47] [PASSED] Tries to lock straight away
[12:43:47] ===== [PASSED] ttm_bo_validate_move_fence_not_signaled =====
[12:43:47] [PASSED] ttm_bo_validate_swapout
[12:43:47] [PASSED] ttm_bo_validate_happy_evict
[12:43:47] [PASSED] ttm_bo_validate_all_pinned_evict
[12:43:47] [PASSED] ttm_bo_validate_allowed_only_evict
[12:43:47] [PASSED] ttm_bo_validate_deleted_evict
[12:43:47] [PASSED] ttm_bo_validate_busy_domain_evict
[12:43:47] [PASSED] ttm_bo_validate_evict_gutting
[12:43:47] [PASSED] ttm_bo_validate_recrusive_evict
[12:43:47] ================= [PASSED] ttm_bo_validate =================
[12:43:47] ============================================================
[12:43:47] Testing complete. Ran 102 tests: passed: 102
[12:43:47] Elapsed time: 12.925s total, 2.438s configuring, 10.272s building, 0.177s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/dma-buf/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/dma-buf/.kunitconfig
[12:43:47] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:43:50] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:43:58] Starting KUnit Kernel (1/1)...
[12:43:58] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:43:58] =============== dma-buf-fence (12 subtests) ================
[12:43:58] [PASSED] test_sanitycheck
[12:43:58] [PASSED] test_signaling
[12:43:58] [PASSED] test_add_callback
[12:43:58] [PASSED] test_late_add_callback
[12:43:58] [PASSED] test_rm_callback
[12:43:58] [PASSED] test_late_rm_callback
[12:43:58] [PASSED] test_status
[12:43:58] [PASSED] test_error
[12:43:59] [PASSED] test_wait
[12:43:59] [PASSED] test_wait_timeout
[12:43:59] [PASSED] test_stub
[12:43:59] [SKIPPED] test_race_signal_callback (requires at least 2 CPUs)
[12:43:59] ================== [PASSED] dma-buf-fence ==================
[12:43:59] ============ dma-buf-fence-chain (11 subtests) =============
[12:43:59] [PASSED] test_sanitycheck
[12:43:59] [PASSED] test_find_seqno
[12:43:59] [PASSED] test_find_signaled
[12:43:59] [PASSED] test_find_out_of_order
[12:44:04] [PASSED] test_find_gap
[12:44:04] [PASSED] test_find_race
[12:44:04] [PASSED] test_signal_forward
[12:44:04] [PASSED] test_signal_backward
[12:44:04] [PASSED] test_wait_forward
[12:44:04] [PASSED] test_wait_backward
[12:44:04] [PASSED] test_wait_random
[12:44:04] =============== [PASSED] dma-buf-fence-chain ===============
[12:44:04] ============ dma-buf-fence-unwrap (11 subtests) ============
[12:44:04] [PASSED] test_sanitycheck
[12:44:04] [PASSED] test_unwrap_array
[12:44:04] [PASSED] test_unwrap_chain
[12:44:04] [PASSED] test_unwrap_chain_array
[12:44:04] [PASSED] test_unwrap_merge
[12:44:04] [PASSED] test_unwrap_merge_duplicate
[12:44:04] [PASSED] test_unwrap_merge_seqno
[12:44:04] [PASSED] test_unwrap_merge_order
[12:44:04] [PASSED] test_unwrap_merge_complex
[12:44:04] [PASSED] test_unwrap_merge_complex_seqno
[12:44:04] [PASSED] test_dedup_empty
[12:44:04] ============== [PASSED] dma-buf-fence-unwrap ===============
[12:44:04] ================ dma-buf-resv (5 subtests) =================
[12:44:04] [PASSED] test_sanitycheck
[12:44:04] ===================== test_signaling ======================
[12:44:04] [PASSED] kernel
[12:44:04] [PASSED] write
[12:44:04] [PASSED] read
[12:44:04] [PASSED] bookkeep
[12:44:04] ================= [PASSED] test_signaling ==================
[12:44:04] ====================== test_for_each ======================
[12:44:04] [PASSED] kernel
[12:44:04] [PASSED] write
[12:44:04] [PASSED] read
[12:44:04] [PASSED] bookkeep
[12:44:04] ================== [PASSED] test_for_each ==================
[12:44:04] ================= test_for_each_unlocked ==================
[12:44:04] [PASSED] kernel
[12:44:04] [PASSED] write
[12:44:04] [PASSED] read
[12:44:04] [PASSED] bookkeep
[12:44:04] ============= [PASSED] test_for_each_unlocked ==============
[12:44:04] ===================== test_get_fences =====================
[12:44:04] [PASSED] kernel
[12:44:04] [PASSED] write
[12:44:04] [PASSED] read
[12:44:04] [PASSED] bookkeep
[12:44:04] ================= [PASSED] test_get_fences =================
[12:44:04] ================== [PASSED] dma-buf-resv ===================
[12:44:04] ============================================================
[12:44:04] Testing complete. Ran 51 tests: passed: 50, skipped: 1
[12:44:04] Elapsed time: 16.701s total, 2.572s configuring, 8.858s building, 5.262s running
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node
2026-11-02 10:50 ` Christian König
@ 2026-11-02 12:46 ` Thomas Hellström
0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2026-11-02 12:46 UTC (permalink / raw)
To: Christian König, Himal Prasad Ghimiray, Huang Rui,
Rodrigo Vivi, Natalie Vock, Paneer Selvam, Arunpravin
Cc: Matthew Auld, Matthew Brost, dri-devel, intel-xe
Hi, Christian,
On Mon, 2026-11-02 at 11:50 +0100, Christian König wrote:
> First of all please add Natalie and Arun on TTM patches, they are the
> maintainers of that component now.
>
> On 11/2/26 11:18, Himal Prasad Ghimiray wrote:
> > ttm_pool_alloc() always allocates on the pool's default node,
> > although
> > the internal TTM helpers (__ttm_pool_alloc(),
> > ttm_pool_alloc_page(),
> > ttm_pool_type_take()) already take a nid. Add ttm_pool_alloc_node()
> > to
> > let a driver pass that nid for a specific tt.
> >
> > ttm_pool_alloc() passes NUMA_NO_NODE, keeping current behaviour. An
> > explicit node on a dma_alloc pool returns -EOPNOTSUPP, as
> > dma_alloc_attrs() can't honor it.
>
> We already have an interface for NUMA node aware allocations in the
> TTM pool.
>
> I don't mind changing/improving that when necessary, but that here is
> only adding a second path and therfore a clear NO-GO from my side.
What we were looking at moving forward is to possibly support
interleaving modes (and that would mean interleaving per folio).
>
> If you want to change the nid from ttm_pool_init() to
> ttm_pool_alloc() then change all existing users.
Point taken. Any specific reason ttm_pool_init() was initially chosen?
Thanks,
Thomas
>
> Regards,
> Christian.
>
> > Signed-off-by: Himal Prasad Ghimiray
> > <himal.prasad.ghimiray@intel.com>
> > ---
> > drivers/gpu/drm/ttm/ttm_pool.c | 59 +++++++++++++++++++++++++++++-
> > ----
> > include/drm/ttm/ttm_pool.h | 2 ++
> > 2 files changed, 53 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/ttm/ttm_pool.c
> > b/drivers/gpu/drm/ttm/ttm_pool.c
> > index 1bf37023fed6..54d2f6b5c229 100644
> > --- a/drivers/gpu/drm/ttm/ttm_pool.c
> > +++ b/drivers/gpu/drm/ttm/ttm_pool.c
> > @@ -158,9 +158,9 @@ static int ttm_pool_nid(struct ttm_pool *pool)
> > return nid;
> > }
> >
> > -/* Allocate pages of size 1 << order with the given gfp_flags */
> > +/* Allocate pages of size 1 << order with the given gfp_flags on
> > node @nid */
> > static struct page *ttm_pool_alloc_page(struct ttm_pool *pool,
> > gfp_t gfp_flags,
> > - unsigned int order)
> > + unsigned int order, int
> > nid)
> > {
> > const unsigned int beneficial_order =
> > ttm_pool_beneficial_order(pool);
> > unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
> > @@ -189,7 +189,7 @@ static struct page *ttm_pool_alloc_page(struct
> > ttm_pool *pool, gfp_t gfp_flags,
> > }
> >
> > if (!ttm_pool_uses_dma_alloc(pool)) {
> > - p = alloc_pages_node(pool->nid, gfp_flags, order);
> > + p = alloc_pages_node(nid, gfp_flags, order);
> > if (p) {
> > p->private = order;
> > mod_lruvec_page_state(p, NR_GPU_ACTIVE, 1
> > << order);
> > @@ -783,7 +783,8 @@ static unsigned int
> > ttm_pool_alloc_find_order(unsigned int highest,
> > static int __ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt
> > *tt,
> > const struct ttm_operation_ctx *ctx,
> > struct ttm_pool_alloc_state *alloc,
> > - struct ttm_pool_tt_restore *restore)
> > + struct ttm_pool_tt_restore *restore,
> > + int nid)
> > {
> > enum ttm_caching page_caching;
> > gfp_t gfp_flags = GFP_USER;
> > @@ -818,7 +819,7 @@ static int __ttm_pool_alloc(struct ttm_pool
> > *pool, struct ttm_tt *tt,
> > p = NULL;
> > pt = ttm_pool_select_type(pool, page_caching,
> > order);
> > if (pt && allow_pools)
> > - p = ttm_pool_type_take(pt,
> > ttm_pool_nid(pool));
> > + p = ttm_pool_type_take(pt, nid);
> >
> > /*
> > * If that fails or previously failed, allocate
> > from system.
> > @@ -829,7 +830,7 @@ static int __ttm_pool_alloc(struct ttm_pool
> > *pool, struct ttm_tt *tt,
> > if (!p) {
> > page_caching = ttm_cached;
> > allow_pools = false;
> > - p = ttm_pool_alloc_page(pool, gfp_flags,
> > order);
> > + p = ttm_pool_alloc_page(pool, gfp_flags,
> > order, nid);
> > }
> > /* If that fails, lower the order if possible and
> > retry. */
> > if (!p) {
> > @@ -900,10 +901,52 @@ int ttm_pool_alloc(struct ttm_pool *pool,
> > struct ttm_tt *tt,
> >
> > ttm_pool_alloc_state_init(tt, &alloc);
> >
> > - return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL);
> > + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL,
> > ttm_pool_nid(pool));
> > }
> > EXPORT_SYMBOL(ttm_pool_alloc);
> >
> > +/**
> > + * ttm_pool_alloc_node - Fill a ttm_tt object, placing pages on a
> > given node
> > + *
> > + * @pool: ttm_pool to use
> > + * @tt: ttm_tt object to fill
> > + * @ctx: operation context
> > + * @nid: NUMA node id to allocate the backing system pages from,
> > or
> > + * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
> > + *
> > + * Like ttm_pool_alloc(), but allows the caller to override the
> > NUMA node the
> > + * backing system pages are allocated from. This only affects the
> > + * non-coherent (non dma-alloc) allocation path; coherent/dma
> > pools continue
> > + * to use the device-local node. Intended for drivers that expose
> > a
> > + * user-selectable host memory NUMA placement.
> > + *
> > + * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a
> > coherent/dma
> > + * pool, negative error code otherwise.
> > + */
> > +int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
> > + struct ttm_operation_ctx *ctx, int nid)
> > +{
> > + struct ttm_pool_alloc_state alloc;
> > +
> > + if (WARN_ON(ttm_tt_is_backed_up(tt)))
> > + return -EINVAL;
> > +
> > + /*
> > + * Coherent/dma pools allocate via dma_alloc_attrs(),
> > which places pages
> > + * per device DMA constraints and cannot honor a caller-
> > requested node.
> > + */
> > + if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
> > + return -EOPNOTSUPP;
> > +
> > + if (nid == NUMA_NO_NODE)
> > + nid = ttm_pool_nid(pool);
> > +
> > + ttm_pool_alloc_state_init(tt, &alloc);
> > +
> > + return __ttm_pool_alloc(pool, tt, ctx, &alloc, NULL, nid);
> > +}
> > +EXPORT_SYMBOL(ttm_pool_alloc_node);
> > +
> > /**
> > * ttm_pool_restore_and_alloc - Fill a ttm_tt, restoring
> > previously backed-up
> > * content.
> > @@ -964,7 +1007,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool
> > *pool, struct ttm_tt *tt,
> > }
> > }
> >
> > - return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore);
> > + return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore,
> > ttm_pool_nid(pool));
> > }
> >
> > /**
> > diff --git a/include/drm/ttm/ttm_pool.h
> > b/include/drm/ttm/ttm_pool.h
> > index 26ee592e1994..6a0b14aca092 100644
> > --- a/include/drm/ttm/ttm_pool.h
> > +++ b/include/drm/ttm/ttm_pool.h
> > @@ -79,6 +79,8 @@ struct ttm_pool {
> >
> > int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
> > struct ttm_operation_ctx *ctx);
> > +int ttm_pool_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
> > + struct ttm_operation_ctx *ctx, int nid);
> > void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt);
> >
> > void ttm_pool_init(struct ttm_pool *pool, struct device *dev,
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ Xe.CI.BAT: success for drm/ttm, drm/xe: Per-BO host NUMA node placement
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (7 preceding siblings ...)
2026-11-02 12:44 ` ✓ CI.KUnit: success for drm/ttm, drm/xe: Per-BO host NUMA node placement Patchwork
@ 2026-11-02 13:22 ` Patchwork
2026-11-02 14:55 ` ✓ Xe.CI.FULL: " Patchwork
9 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-11-02 13:22 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 871 bytes --]
== Series Details ==
Series: drm/ttm, drm/xe: Per-BO host NUMA node placement
URL : https://patchwork.freedesktop.org/series/177437/
State : success
== Summary ==
CI Bug Log - changes from xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee_BAT -> xe-pw-177437v1_BAT
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (15 -> 15)
------------------------------
No changes in participating hosts
Changes
-------
No changes found
Build changes
-------------
* Linux: xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee -> xe-pw-177437v1
IGT_9173: 9173
xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee: 77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee
xe-pw-177437v1: 177437v1
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-177437v1/index.html
[-- Attachment #2: Type: text/html, Size: 1419 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ Xe.CI.FULL: success for drm/ttm, drm/xe: Per-BO host NUMA node placement
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
` (8 preceding siblings ...)
2026-11-02 13:22 ` ✓ Xe.CI.BAT: " Patchwork
@ 2026-11-02 14:55 ` Patchwork
9 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-11-02 14:55 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 871 bytes --]
== Series Details ==
Series: drm/ttm, drm/xe: Per-BO host NUMA node placement
URL : https://patchwork.freedesktop.org/series/177437/
State : success
== Summary ==
CI Bug Log - changes from xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee_FULL -> xe-pw-177437v1_FULL
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (3 -> 3)
------------------------------
No changes in participating hosts
Changes
-------
No changes found
Build changes
-------------
* Linux: xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee -> xe-pw-177437v1
IGT_9173: 9173
xe-6043-77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee: 77e9b8bc2afe3ad1cff8570dcae1bf0998fcffee
xe-pw-177437v1: 177437v1
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-177437v1/index.html
[-- Attachment #2: Type: text/html, Size: 1419 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler
2026-11-02 11:12 ` Matthew Auld
@ 2026-11-02 18:24 ` Himal prasad Ghimiray
0 siblings, 0 replies; 19+ messages in thread
From: Himal prasad Ghimiray @ 2026-11-02 18:24 UTC (permalink / raw)
To: Matthew Auld, Christian König, Huang Rui,
Thomas Hellström, Rodrigo Vivi
Cc: Matthew Brost, dri-devel, intel-xe
On 02-11-2026 16:42, Matthew Auld wrote:
> On 02/11/2026 10:18, Himal Prasad Ghimiray wrote:
>> Parse the NUMA node property before BO creation and store it on the BO.
>> Offline or out of range nodes, and BOs without a system memory
>> placement, are rejected with -EINVAL.
>>
>> Drop the explicit DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY check,
>> already
>> covered by the property bounds check.
>>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/tests/xe_bo.c | 12 +--
>> drivers/gpu/drm/xe/tests/xe_dma_buf.c | 4 +-
>> drivers/gpu/drm/xe/tests/xe_migrate.c | 8 +-
>> drivers/gpu/drm/xe/xe_bo.c | 102 +++++++++++++++++++++-----
>> drivers/gpu/drm/xe/xe_bo.h | 5 +-
>> drivers/gpu/drm/xe/xe_dma_buf.c | 3 +-
>> 6 files changed, 100 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c
>> b/drivers/gpu/drm/xe/tests/xe_bo.c
>> index 6a17e13d58cf..6f61f5c618f1 100644
>> --- a/drivers/gpu/drm/xe/tests/xe_bo.c
>> +++ b/drivers/gpu/drm/xe/tests/xe_bo.c
>> @@ -89,7 +89,7 @@ static void run_only_leaf(struct kunit *test,
>> bo = xe_bo_create_user(xe, NULL, li->alloc_size,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - XE_BO_FLAG_VRAM0, NULL);
>> + XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> page_size_alloc_restore(xe, &saved);
>> if (PTR_ERR(bo) == -ENOSPC) {
>> @@ -183,7 +183,7 @@ static void
>> xe_bo_page_size_alloc_mixed_bos(struct kunit *test)
>> */
>> bo = xe_bo_create_user(xe, NULL, SZ_1G,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - XE_BO_FLAG_VRAM0, NULL);
>> + XE_BO_FLAG_VRAM0, NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> int err = PTR_ERR(bo);
>> @@ -366,7 +366,7 @@ static void ccs_test_run_tile(struct xe_device
>> *xe, struct xe_tile *tile,
>> kunit_info(test, "Testing system memory\n");
>> bo = xe_bo_create_user(xe, NULL, SZ_1M,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - bo_flags, exec);
>> + bo_flags, NUMA_NO_NODE, exec);
>> if (IS_ERR(bo)) {
>> KUNIT_FAIL(test, "Failed to create bo.\n");
>> return;
>> @@ -445,7 +445,7 @@ static int evict_test_run_tile(struct xe_device
>> *xe, struct xe_tile *tile, struc
>> xe_vm_lock(vm, false);
>> bo = xe_bo_create_user(xe, vm, 0x10000,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - bo_flags, exec);
>> + bo_flags, NUMA_NO_NODE, exec);
>> xe_vm_unlock(vm);
>> if (IS_ERR(bo)) {
>> KUNIT_FAIL(test, "bo create err=%pe\n", bo);
>> @@ -454,7 +454,7 @@ static int evict_test_run_tile(struct xe_device
>> *xe, struct xe_tile *tile, struc
>> external = xe_bo_create_user(xe, NULL, 0x10000,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - bo_flags, NULL);
>> + bo_flags, NUMA_NO_NODE, NULL);
>> if (IS_ERR(external)) {
>> KUNIT_FAIL(test, "external bo create err=%pe\n",
>> external);
>> goto cleanup_bo;
>> @@ -719,7 +719,7 @@ static int shrink_test_run_device(struct
>> xe_device *xe)
>> /* We can create bos using WC caching here. But it is
>> slower. */
>> bo = xe_bo_create_user(xe, NULL, XE_BO_SHRINK_SIZE,
>> DRM_XE_GEM_CPU_CACHING_WB,
>> - XE_BO_FLAG_SYSTEM, NULL);
>> + XE_BO_FLAG_SYSTEM, NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) &&
>> bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS))
>> diff --git a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
>> b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
>> index 792376e965f1..876ea545d1a7 100644
>> --- a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
>> +++ b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
>> @@ -127,7 +127,7 @@ static void
>> xe_test_dmabuf_import_same_driver(struct xe_device *xe)
>> kunit_info(test, "running %s\n", __func__);
>> bo = xe_bo_create_user(xe, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
>> - params->mem_mask, NULL);
>> + params->mem_mask, NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
>> PTR_ERR(bo));
>> @@ -215,7 +215,7 @@ static void
>> xe_test_dmabuf_move_notify_no_resource(struct xe_device *xe)
>> kunit_info(test, "running %s\n", __func__);
>> bo = xe_bo_create_user(xe, NULL, PAGE_SIZE,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - params->mem_mask, NULL);
>> + params->mem_mask, NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
>> PTR_ERR(bo));
>> diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c
>> b/drivers/gpu/drm/xe/tests/xe_migrate.c
>> index 56c49d8507d7..69b64e3a23b8 100644
>> --- a/drivers/gpu/drm/xe/tests/xe_migrate.c
>> +++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
>> @@ -649,7 +649,7 @@ static void validate_ccs_test_run_tile(struct
>> xe_device *xe, struct xe_tile *til
>> DRM_XE_GEM_CPU_CACHING_WC,
>> XE_BO_FLAG_SYSTEM |
>> XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> - XE_BO_FLAG_PINNED, NULL);
>> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
>> if (IS_ERR(sys_bo)) {
>> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
>> @@ -675,7 +675,7 @@ static void validate_ccs_test_run_tile(struct
>> xe_device *xe, struct xe_tile *til
>> ccs_bo = xe_bo_create_user(xe, NULL, SZ_4M,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> - XE_BO_FLAG_PINNED, NULL);
>> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
>> if (IS_ERR(ccs_bo)) {
>> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
>> @@ -700,7 +700,7 @@ static void validate_ccs_test_run_tile(struct
>> xe_device *xe, struct xe_tile *til
>> vram_bo = xe_bo_create_user(xe, NULL, SZ_4M,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> - XE_BO_FLAG_PINNED, NULL);
>> + XE_BO_FLAG_PINNED, NUMA_NO_NODE, NULL);
>> if (IS_ERR(vram_bo)) {
>> KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
>> PTR_ERR(vram_bo));
>> @@ -979,7 +979,7 @@ static void access_memory_test_run_tile(struct
>> xe_device *xe,
>> bo = xe_bo_create_user(xe, NULL, ACCESS_MEM_BO_SIZE,
>> DRM_XE_GEM_CPU_CACHING_WC,
>> - bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS, NULL);
>> + bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS,
>> NUMA_NO_NODE, NULL);
>> if (IS_ERR(bo)) {
>> KUNIT_FAIL(test, "Failed to create bo: %pe\n", bo);
>> goto free_buf;
>> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
>> index fc9bfb436b8e..bbbc33737264 100644
>> --- a/drivers/gpu/drm/xe/xe_bo.c
>> +++ b/drivers/gpu/drm/xe/xe_bo.c
>> @@ -1538,7 +1538,7 @@ int xe_bo_notifier_prepare_pinned(struct xe_bo
>> *bo)
>> backup = xe_bo_init_locked(xe, NULL, NULL,
>> bo->ttm.base.resv, NULL, xe_bo_size(bo),
>> DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
>> XE_BO_FLAG_SYSTEM |
>> XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> - XE_BO_FLAG_PINNED, NULL, &exec);
>> + XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE, &exec);
>> if (IS_ERR(backup)) {
>> drm_exec_retry_on_contention(&exec);
>> ret = PTR_ERR(backup);
>> @@ -1680,7 +1680,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
>> xe_bo_size(bo),
>> DRM_XE_GEM_CPU_CACHING_WB,
>> ttm_bo_type_kernel,
>> XE_BO_FLAG_SYSTEM |
>> XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> - XE_BO_FLAG_PINNED, NULL, &exec);
>> + XE_BO_FLAG_PINNED, NULL, NUMA_NO_NODE,
>> &exec);
>> if (IS_ERR(backup)) {
>> drm_exec_retry_on_contention(&exec);
>> ret = PTR_ERR(backup);
>> @@ -2480,7 +2480,7 @@ struct xe_bo *xe_bo_init_locked(struct
>> xe_device *xe, struct xe_bo *bo,
>> struct ttm_lru_bulk_move *bulk, size_t size,
>> u16 cpu_caching, enum ttm_bo_type type,
>> u32 flags, struct dma_buf *dma_buf,
>> - struct drm_exec *exec)
>> + int numa_node, struct drm_exec *exec)
>> {
>> struct ttm_operation_ctx ctx = {
>> .interruptible = true,
>> @@ -2546,7 +2546,7 @@ struct xe_bo *xe_bo_init_locked(struct
>> xe_device *xe, struct xe_bo *bo,
>> bo->tile = tile;
>> bo->flags = flags;
>> bo->cpu_caching = cpu_caching;
>> - bo->numa_node = NUMA_NO_NODE;
>> + bo->numa_node = numa_node;
>> bo->ttm.base.funcs = &xe_gem_object_funcs;
>> bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
>> INIT_LIST_HEAD(&bo->pinned_link);
>> @@ -2681,7 +2681,7 @@ __xe_bo_create_locked(struct xe_device *xe,
>> struct xe_tile *tile, struct xe_vm *vm,
>> size_t size, u64 start, u64 end,
>> u16 cpu_caching, enum ttm_bo_type type, u32 flags,
>> - u64 alignment, struct drm_exec *exec)
>> + u64 alignment, int numa_node, struct drm_exec *exec)
>> {
>> struct xe_bo *bo = NULL;
>> int err;
>> @@ -2706,7 +2706,7 @@ __xe_bo_create_locked(struct xe_device *xe,
>> vm && !xe_vm_in_fault_mode(vm) &&
>> flags & XE_BO_FLAG_USER ?
>> &vm->lru_bulk_move : NULL, size,
>> - cpu_caching, type, flags, NULL, exec);
>> + cpu_caching, type, flags, NULL, numa_node, exec);
>> if (IS_ERR(bo))
>> return bo;
>> @@ -2781,13 +2781,13 @@ struct xe_bo *xe_bo_create_locked(struct
>> xe_device *xe, struct xe_tile *tile,
>> struct drm_exec *exec)
>> {
>> return __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL, 0,
>> type,
>> - flags, 0, exec);
>> + flags, 0, NUMA_NO_NODE, exec);
>> }
>> static struct xe_bo *xe_bo_create_novm(struct xe_device *xe,
>> struct xe_tile *tile,
>> size_t size, u16 cpu_caching,
>> enum ttm_bo_type type, u32 flags,
>> - u64 alignment, bool intr)
>> + u64 alignment, int numa_node, bool intr)
>> {
>> struct xe_validation_ctx ctx;
>> struct drm_exec exec;
>> @@ -2797,7 +2797,8 @@ static struct xe_bo *xe_bo_create_novm(struct
>> xe_device *xe, struct xe_tile *til
>> xe_validation_guard(&ctx, &xe->val, &exec, (struct
>> xe_val_flags) {.interruptible = intr},
>> ret) {
>> bo = __xe_bo_create_locked(xe, tile, NULL, size, 0, ~0ULL,
>> - cpu_caching, type, flags, alignment, &exec);
>> + cpu_caching, type, flags, alignment,
>> + numa_node, &exec);
>> drm_exec_retry_on_contention(&exec);
>> if (IS_ERR(bo)) {
>> ret = PTR_ERR(bo);
>> @@ -2966,7 +2967,8 @@ static void
>> xe_bo_debug_mixed_mode_cur_index_advance(struct xe_device *xe,
>> struct xe_bo *xe_bo_create_user(struct xe_device *xe,
>> struct xe_vm *vm, size_t size,
>> u16 cpu_caching,
>> - u32 flags, struct drm_exec *exec)
>> + u32 flags, int numa_node,
>> + struct drm_exec *exec)
>> {
>> struct xe_bo *bo;
>> int err = 0;
>> @@ -2983,12 +2985,13 @@ struct xe_bo *xe_bo_create_user(struct
>> xe_device *xe,
>> xe_assert(xe, exec);
>> bo = __xe_bo_create_locked(xe, NULL, vm, size, 0, ~0ULL,
>> cpu_caching, ttm_bo_type_device,
>> - flags, 0, exec);
>> + flags, 0, numa_node, exec);
>> if (!IS_ERR(bo))
>> xe_bo_unlock_vm_held(bo);
>> } else {
>> bo = xe_bo_create_novm(xe, NULL, size, cpu_caching,
>> - ttm_bo_type_device, flags, 0, true);
>> + ttm_bo_type_device, flags, 0,
>> + numa_node, true);
>> }
>> return bo;
>> @@ -3022,7 +3025,7 @@ struct xe_bo
>> *xe_bo_create_pin_range_novm(struct xe_device *xe, struct xe_tile *
>> xe_validation_guard(&ctx, &xe->val, &exec, (struct
>> xe_val_flags) {}, err) {
>> bo = __xe_bo_create_locked(xe, tile, NULL, size, start, end,
>> - 0, type, flags, 0, &exec);
>> + 0, type, flags, 0, NUMA_NO_NODE, &exec);
>> if (IS_ERR(bo)) {
>> drm_exec_retry_on_contention(&exec);
>> err = PTR_ERR(bo);
>> @@ -3061,7 +3064,7 @@ static struct xe_bo
>> *xe_bo_create_pin_map_at_aligned(struct xe_device *xe,
>> bo = __xe_bo_create_locked(xe, tile, vm, size, start, end, 0,
>> type,
>> flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
>> XE_BO_FLAG_PINNED,
>> - alignment, exec);
>> + alignment, NUMA_NO_NODE, exec);
>> if (IS_ERR(bo))
>> return bo;
>> @@ -3604,10 +3607,15 @@ static int
>> gem_create_user_ext_set_property(struct xe_device *xe,
>> if (XE_IOCTL_DBG(xe, err))
>> return -EFAULT;
>> + if (XE_IOCTL_DBG(xe, ext.pad))
>> + return -EINVAL;
>> +
>> + /* The NUMA node property is parsed and applied before BO
>> creation. */
>> + if (ext.property == DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
>> + return 0;
>> +
>> if (XE_IOCTL_DBG(xe, ext.property >=
>> - ARRAY_SIZE(gem_create_set_property_funcs)) ||
>> - XE_IOCTL_DBG(xe, ext.pad) ||
>> - XE_IOCTL_DBG(xe, ext.property !=
>> DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY))
>> + ARRAY_SIZE(gem_create_set_property_funcs)))
>> return -EINVAL;
>> idx = array_index_nospec(ext.property,
>> ARRAY_SIZE(gem_create_set_property_funcs));
>> @@ -3658,6 +3666,56 @@ static int gem_create_user_extensions(struct
>> xe_device *xe, struct xe_bo *bo,
>> return 0;
>> }
>> +/*
>> + * Parse a host NUMA node request from the extension chain. The node
>> must be
>> + * known before the BO is created, because the backing pages are
>> allocated
>> + * during creation. Returns the requested node in @numa_node
>> (NUMA_NO_NODE if
>> + * none or a negative value is given) or a negative errno on an
>> invalid request.
>
> Would it make sense to rework this and have something like:
>
> struct gem_create_extension_data {
> u32 pxp_key_instance;
> int numa_node;
> }
>
> Which is parsed up front before the bo create? And then in some way we
> just pass that along to create_user() or manual bo init after?
> Otherwise here we look to be open coding a duplicate extension parser
> flow, rather than using gem_create_set_property_funcs? I think parsing
> before bo create make more sense anyway, like you do here?
Makes sense, will explore this.
>
>> + */
>> +static int gem_create_parse_numa_node(struct xe_device *xe, u64
>> extensions,
>> + u32 bo_flags, int *numa_node)
>> +{
>> + struct drm_xe_user_extension base;
>> + struct drm_xe_ext_set_property ext;
>> + unsigned int i = 0;
>> +
>> + *numa_node = NUMA_NO_NODE;
>> +
>> + while (extensions && i++ < MAX_USER_EXTENSIONS) {
>> + u64 __user *address = u64_to_user_ptr(extensions);
>> + s64 nid;
>> +
>> + if (XE_IOCTL_DBG(xe, copy_from_user(&base, address,
>> sizeof(base))))
>> + return -EFAULT;
>> +
>> + if (base.name != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY)
>> + goto next;
>> +
>> + if (XE_IOCTL_DBG(xe, copy_from_user(&ext, address,
>> sizeof(ext))))
>> + return -EFAULT;
>> +
>> + if (ext.property != DRM_XE_GEM_CREATE_SET_PROPERTY_NUMA_NODE)
>> + goto next;
>> +
>> + nid = (s64)ext.value;
>> + *numa_node = NUMA_NO_NODE;
>> + if (nid < 0)
>> + goto next;
>> +
>> + if (XE_IOCTL_DBG(xe, nid >= MAX_NUMNODES || !node_online(nid)))
>
> I think needs nospec dance for nid?
sure
>
>> + return -EINVAL;
>> +
>> + if (XE_IOCTL_DBG(xe, !(bo_flags & XE_BO_FLAG_SYSTEM)))
>> + return -EINVAL;
>> +
>> + *numa_node = nid;
>> +next:
>> + extensions = base.next_extension;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> int xe_gem_create_ioctl(struct drm_device *dev, void *data,
>> struct drm_file *file)
>> {
>> @@ -3669,6 +3727,7 @@ int xe_gem_create_ioctl(struct drm_device *dev,
>> void *data,
>> struct xe_vm *vm = NULL;
>> struct xe_bo *bo;
>> unsigned int bo_flags;
>> + int numa_node;
>> u32 handle;
>> int err;
>> @@ -3744,6 +3803,11 @@ int xe_gem_create_ioctl(struct drm_device
>> *dev, void *data,
>> args->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
>> return -EINVAL;
>> + err = gem_create_parse_numa_node(xe, args->extensions, bo_flags,
>> + &numa_node);
>> + if (err)
>> + return err;
>> +
>> if (args->vm_id) {
>> vm = xe_vm_lookup(xef, args->vm_id);
>> if (XE_IOCTL_DBG(xe, !vm))
>> @@ -3760,7 +3824,7 @@ int xe_gem_create_ioctl(struct drm_device *dev,
>> void *data,
>> break;
>> }
>> bo = xe_bo_create_user(xe, vm, args->size, args->cpu_caching,
>> - bo_flags, &exec);
>> + bo_flags, numa_node, &exec);
>> drm_exec_retry_on_contention(&exec);
>> if (IS_ERR(bo)) {
>> err = PTR_ERR(bo);
>> @@ -4231,7 +4295,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_NEEDS_CPU_ACCESS, NULL);
>> + XE_BO_FLAG_NEEDS_CPU_ACCESS, NUMA_NO_NODE, 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 77b3a02e9b8e..225c6a8676a6 100644
>> --- a/drivers/gpu/drm/xe/xe_bo.h
>> +++ b/drivers/gpu/drm/xe/xe_bo.h
>> @@ -122,13 +122,14 @@ struct xe_bo *xe_bo_init_locked(struct
>> xe_device *xe, struct xe_bo *bo,
>> struct ttm_lru_bulk_move *bulk, size_t size,
>> u16 cpu_caching, enum ttm_bo_type type,
>> u32 flags, struct dma_buf *dma_buf,
>> - struct drm_exec *exec);
>> + int numa_node, struct drm_exec *exec);
>> struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct
>> xe_tile *tile,
>> struct xe_vm *vm, size_t size,
>> enum ttm_bo_type type, u32 flags,
>> struct drm_exec *exec);
>> struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_vm
>> *vm, size_t size,
>> - u16 cpu_caching, u32 flags, struct drm_exec *exec);
>> + u16 cpu_caching, u32 flags, int numa_node,
>> + struct drm_exec *exec);
>> struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct
>> xe_tile *tile,
>> struct xe_vm *vm, size_t size,
>> enum ttm_bo_type type, u32 flags,
>> diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c
>> b/drivers/gpu/drm/xe/xe_dma_buf.c
>> index 5bf13dc4b61d..b5351310a07b 100644
>> --- a/drivers/gpu/drm/xe/xe_dma_buf.c
>> +++ b/drivers/gpu/drm/xe/xe_dma_buf.c
>> @@ -343,7 +343,8 @@ xe_dma_buf_create_obj(struct drm_device *dev,
>> struct dma_buf *dma_buf)
>> bo = xe_bo_init_locked(xe, NULL, NULL, resv, NULL,
>> dma_buf->size,
>> 0, /* Will require 1way or 2way for vm_bind */
>> - ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf,
>> &exec);
>> + ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf,
>> + NUMA_NO_NODE, &exec);
>> drm_exec_retry_on_contention(&exec);
>> if (IS_ERR(bo)) {
>> ret = PTR_ERR(bo);
>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-11-02 18:24 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02 10:18 [RFC 0/7] drm/ttm, drm/xe: Per-BO host NUMA node placement Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 1/7] drm/ttm/pool: Add ttm_pool_alloc_node() for caller-selected NUMA node Himal Prasad Ghimiray
2026-11-02 10:26 ` sashiko-bot
2026-11-02 10:50 ` Christian König
2026-11-02 12:46 ` Thomas Hellström
2026-11-02 10:18 ` [RFC 2/7] drm/ttm: Add NUMA node aware restore helpers Himal Prasad Ghimiray
2026-11-02 10:26 ` sashiko-bot
2026-11-02 10:18 ` [RFC 3/7] drm/ttm/pool: enforce per-node cache limits on free Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 4/7] drm/xe/bo: Plumb a per-BO host NUMA node hint into tt populate Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 5/7] drm/xe/bo: Preserve the host NUMA node across backup / restore Himal Prasad Ghimiray
2026-11-02 10:18 ` [RFC 6/7] drm/xe/uapi: Add GEM_CREATE NUMA node placement property Himal Prasad Ghimiray
2026-11-02 10:27 ` sashiko-bot
2026-11-02 10:18 ` [RFC 7/7] drm/xe/uapi: Wire up GEM_CREATE NUMA node placement handler Himal Prasad Ghimiray
2026-11-02 10:29 ` sashiko-bot
2026-11-02 11:12 ` Matthew Auld
2026-11-02 18:24 ` Himal prasad Ghimiray
2026-11-02 12:44 ` ✓ CI.KUnit: success for drm/ttm, drm/xe: Per-BO host NUMA node placement Patchwork
2026-11-02 13:22 ` ✓ Xe.CI.BAT: " Patchwork
2026-11-02 14:55 ` ✓ Xe.CI.FULL: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox