* [PATCH 0/4] Page-reclaim fixes and PRL stats addition
@ 2026-01-05 23:33 Brian Nguyen
2026-01-05 23:33 ` [PATCH 1/4] drm/xe: Remove debug comment in page reclaim Brian Nguyen
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Brian Nguyen @ 2026-01-05 23:33 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
This series provides fixes to page reclamation and additional stats
for the page reclamation feature.
Patch 1 is just a small fixup to remove a debug comment.
Patch 2 makes the distinction between PRL invalidation done as
part of a typical workflow and invalidation done to abort and
fallback to normal TLB invalidation.
Patch 3 fixes the incorrect handling of larger page sizes for PRL entry
generation. 64KB are just contigious 4KB PTE so only need to add one.
2MB also needs to be handled separately because page directory are
handled differently. Also additional handling of racy pte reads and
page walk completions before PTE.
Patch 4 adds PRL related stats to GT stats to assist in debugging and
validation of the feature.
Modifications from the fixes will slightly conflict with the addition of
stats so it seemed better to push patches as a series together.
Thanks,
Brian
v2:
- Remove comment erroneously added in initial commit.
- Add explicit abort func to clearly define invalidation done
to indicate end of scope and invalidation done to abort PRL.
- Added PRL_ABORTED_STATS../
Brian Nguyen (4):
drm/xe: Remove debug comment in page reclaim
drm/xe: Add explicit abort page reclaim list
drm/xe: Fix page reclaim entry handling for large pages
drm/xe: Add page reclamation related stats
drivers/gpu/drm/xe/xe_gt_stats.c | 5 ++
drivers/gpu/drm/xe/xe_gt_stats_types.h | 5 ++
drivers/gpu/drm/xe/xe_guc_tlb_inval.c | 3 +
drivers/gpu/drm/xe/xe_page_reclaim.c | 26 ++++++++-
drivers/gpu/drm/xe/xe_page_reclaim.h | 3 +
drivers/gpu/drm/xe/xe_pt.c | 76 +++++++++++++++++---------
drivers/gpu/drm/xe/xe_tlb_inval_job.c | 2 +-
7 files changed, 92 insertions(+), 28 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] drm/xe: Remove debug comment in page reclaim
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
@ 2026-01-05 23:33 ` Brian Nguyen
2026-01-06 2:15 ` Matthew Brost
2026-01-05 23:33 ` [PATCH 2/4] drm/xe: Add explicit abort page reclaim list Brian Nguyen
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Brian Nguyen @ 2026-01-05 23:33 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
Drop debug comment erronenously added in patch commit.
Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
---
drivers/gpu/drm/xe/xe_page_reclaim.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
index fd8c33761127..94d4608ebd74 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.c
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
@@ -108,7 +108,6 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
*/
void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl)
{
- // xe_page_reclaim_list_invalidate(prl);
prl->entries = NULL;
prl->num_entries = 0;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] drm/xe: Add explicit abort page reclaim list
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
2026-01-05 23:33 ` [PATCH 1/4] drm/xe: Remove debug comment in page reclaim Brian Nguyen
@ 2026-01-05 23:33 ` Brian Nguyen
2026-01-06 2:23 ` Matthew Brost
2026-01-05 23:33 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Brian Nguyen @ 2026-01-05 23:33 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
PRLs could be invalidated to indicate its getting dropped from current
scope but are still valid. So standardize calls and add abort to clearly
define when an invalidation is a real abort and PRL should fallback.
Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
---
drivers/gpu/drm/xe/xe_page_reclaim.c | 23 +++++++++++++++++++++++
drivers/gpu/drm/xe/xe_page_reclaim.h | 3 +++
drivers/gpu/drm/xe/xe_pt.c | 21 +++++++++------------
drivers/gpu/drm/xe/xe_tlb_inval_job.c | 2 +-
4 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
index 94d4608ebd74..9f086067a4a1 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.c
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
@@ -100,6 +100,29 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
prl->num_entries = XE_PAGE_RECLAIM_INVALID_LIST;
}
+/**
+ * xe_page_reclaim_list_abort() - Abort a PRL, invalidate it, and log
+ * @gt: GT associated with this PRL
+ * @prl: Page reclaim list to invalidate
+ * @format: printf-style format string for vm_dbg
+ *
+ * This is intended for PRL abort paths where we want to track aborted PRLs
+ */
+void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *prl,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list va_args;
+
+ xe_page_reclaim_list_invalidate(prl);
+
+ va_start(va_args, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &va_args;
+ vm_dbg(>_to_xe(gt)->drm, "PRL aborted: %pV", &vaf);
+ va_end(va_args);
+}
+
/**
* xe_page_reclaim_list_init() - Initialize a page reclaim list
* @prl: Page reclaim list to initialize
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.h b/drivers/gpu/drm/xe/xe_page_reclaim.h
index a4f58e0ce9b4..2464268dba69 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.h
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.h
@@ -19,6 +19,7 @@
struct xe_tlb_inval;
struct xe_tlb_inval_fence;
struct xe_tile;
+struct xe_gt;
struct xe_vma;
struct xe_guc_page_reclaim_entry {
@@ -75,6 +76,8 @@ struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inva
struct xe_page_reclaim_list *prl,
struct xe_tlb_inval_fence *fence);
void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl);
+void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *prl,
+ const char *format, ...);
void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl);
int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list *prl);
/**
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 6cd78bb2b652..2752a5a48a97 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -1618,10 +1618,9 @@ static int generate_reclaim_entry(struct xe_tile *tile,
} else if (is_2m_pte(xe_child)) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
} else {
- xe_page_reclaim_list_invalidate(prl);
- vm_dbg(&tile_to_xe(tile)->drm,
- "PRL invalidate: unsupported PTE level=%u pte=%#llx\n",
- xe_child->level, pte);
+ xe_page_reclaim_list_abort(tile->primary_gt, prl,
+ "unsupported PTE level=%u pte=%#llx",
+ xe_child->level, pte);
return -EINVAL;
}
@@ -1670,10 +1669,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
break;
} else {
/* overflow, mark as invalid */
- xe_page_reclaim_list_invalidate(xe_walk->prl);
- vm_dbg(&xe->drm,
- "PRL invalidate: overflow while adding pte=%#llx",
- pte);
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "overflow while adding pte=%#llx",
+ pte);
break;
}
}
@@ -1682,10 +1680,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
/* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
- xe_page_reclaim_list_invalidate(xe_walk->prl);
- vm_dbg(&xe->drm,
- "PRL invalidate: kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
- level, addr, next, xe_child->num_live);
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
+ level, addr, next, xe_child->num_live);
}
return 0;
diff --git a/drivers/gpu/drm/xe/xe_tlb_inval_job.c b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
index 6a7bd6315797..b8916552101c 100644
--- a/drivers/gpu/drm/xe/xe_tlb_inval_job.c
+++ b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
@@ -182,7 +182,7 @@ static void xe_tlb_inval_job_destroy(struct kref *ref)
struct xe_vm *vm = job->vm;
/* BO creation retains a copy (if used), so no longer needed */
- xe_page_reclaim_entries_put(job->prl.entries);
+ xe_page_reclaim_list_invalidate(&job->prl);
if (!job->fence_armed)
kfree(ifence);
--
2.52.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
2026-01-05 23:33 ` [PATCH 1/4] drm/xe: Remove debug comment in page reclaim Brian Nguyen
2026-01-05 23:33 ` [PATCH 2/4] drm/xe: Add explicit abort page reclaim list Brian Nguyen
@ 2026-01-05 23:33 ` Brian Nguyen
2026-01-06 16:41 ` Matthew Brost
2026-01-05 23:33 ` [PATCH 4/4] drm/xe: Add page reclamation related stats Brian Nguyen
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Brian Nguyen @ 2026-01-05 23:33 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
For 64KB pages, XE_PTE_PS64 is defined for all consecutive 4KB pages and
are all considered leaf nodes, so existing check was falsely adding
multiple 64KB pages to PRL.
For larger entries such as 2MB PDE, the check for pte->base.children is
insufficient since this array is always defined for page directory,
level 1 and above, so perform a check on the entry itself pointing to
the correct page.
For unmaps, if the range is properly covered by the page full directory,
page walker may finish without walking to the leaf nodes.
For example, a 1G range can be fully covered by 512 2MB pages if
alignment allows. In this case, the page walker will walk until
it reaches this corresponding directory which can correlate to the 1GB
range. Page walker will simply complete its walk and the individual 2MB
PDE leaves won't get accessed.
In this case, PRL invalidation is also required, so add a check to see if
pt entry cover the entire range since the walker will complete the walk.
There are possible race conditions that will cause driver to read a pte
that hasn't been written to yet. The 2 scenarios are:
- Another issued TLB invalidation such as from userptr or MMU notifier.
- Dependencies on original bind that has yet to be executed with an
unbind on that job.
The expectation is these race conditions are likely rare cases so simply
perform a fallback to full PPC flush invalidation instead.
v2:
- Reword commit and updated zero-pte handling. (Matthew B)
Fixes: b912138df299 ("drm/xe: Create page reclaim list on unbind")
Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 50 +++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 2752a5a48a97..668a981696f9 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -1576,12 +1576,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
return false;
}
-/* Huge 2MB leaf lives directly in a level-1 table and has no children */
-static bool is_2m_pte(struct xe_pt *pte)
-{
- return pte->level == 1 && !pte->base.children;
-}
-
/* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
#define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
({ \
@@ -1594,7 +1588,8 @@ static int generate_reclaim_entry(struct xe_tile *tile,
u64 pte, struct xe_pt *xe_child)
{
struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
- u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
+ u64 phys_addr = pte & XE_PTE_ADDR_MASK;
+ u64 phys_page = phys_addr >> XE_PTE_SHIFT;
int num_entries = prl->num_entries;
u32 reclamation_size;
@@ -1613,10 +1608,13 @@ static int generate_reclaim_entry(struct xe_tile *tile,
*/
if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
+ xe_tile_assert(tile, phys_addr % SZ_4K == 0);
} else if (xe_child->level == 0) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
- } else if (is_2m_pte(xe_child)) {
+ xe_tile_assert(tile, phys_addr % SZ_64K == 0);
+ } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
+ xe_tile_assert(tile, phys_addr % SZ_2M == 0);
} else {
xe_page_reclaim_list_abort(tile->primary_gt, prl,
"unsupported PTE level=%u pte=%#llx",
@@ -1647,20 +1645,39 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
struct xe_pt_stage_unbind_walk *xe_walk =
container_of(walk, typeof(*xe_walk), base);
struct xe_device *xe = tile_to_xe(xe_walk->tile);
+ pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
XE_WARN_ON(!*child);
XE_WARN_ON(!level);
/* Check for leaf node */
if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
- !xe_child->base.children) {
+ (!xe_child->base.children || !xe_child->base.children[first])) {
struct iosys_map *leaf_map = &xe_child->bo->vmap;
- pgoff_t first = xe_pt_offset(addr, 0, walk);
- pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
+ pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
for (pgoff_t i = 0; i < count; i++) {
u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
int ret;
+ /*
+ * In rare scenarios, pte may not be written yet due to racy conditions.
+ * In such cases, invalidate the PRL and fallback to full PPC invalidation.
+ */
+ if (!pte) {
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "found zero pte at addr=%#llx", addr);
+ break;
+ }
+
+ /* Ensure it is a defined page */
+ xe_tile_assert(xe_walk->tile,
+ xe_child->level == 0 ||
+ (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
+
+ /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
+ if (pte & XE_PTE_PS64)
+ i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
+
/* Account for NULL terminated entry on end (-1) */
if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl,
@@ -1677,9 +1694,14 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
}
}
- /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
- if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
- xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
+ /*
+ * If aborting page walk early or page walk finishes,
+ * invalidate PRL since PTE may be dropped from this abort
+ */
+ if ((xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) ||
+ xe_pt_covers(addr, next, xe_child->level, &xe_walk->base)) &&
+ xe_walk->prl && level > 1 && (xe_child->base.children &&
+ xe_child->base.children[first]) && xe_child->num_live != 0) {
xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
"kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
level, addr, next, xe_child->num_live);
--
2.52.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] drm/xe: Add page reclamation related stats
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
` (2 preceding siblings ...)
2026-01-05 23:33 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
@ 2026-01-05 23:33 ` Brian Nguyen
2026-01-05 23:41 ` ✓ CI.KUnit: success for Page-reclaim fixes and PRL stats addition (rev2) Patchwork
2026-01-06 1:12 ` ✗ Xe.CI.Full: failure " Patchwork
5 siblings, 0 replies; 14+ messages in thread
From: Brian Nguyen @ 2026-01-05 23:33 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
Add page reclaim list (PRL) related stats to GT stats to assist in
debugging and tuning of page reclaim related actions. Include counters
of page sizes added to PRL and if PRL action is issued.
v2:
- Add PRL_ABORTED_COUNT stats and corresponding changes. (Matthew B)
Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_gt_stats.c | 5 +++++
drivers/gpu/drm/xe/xe_gt_stats_types.h | 5 +++++
drivers/gpu/drm/xe/xe_guc_tlb_inval.c | 3 +++
drivers/gpu/drm/xe/xe_page_reclaim.c | 2 ++
drivers/gpu/drm/xe/xe_pt.c | 5 +++++
5 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_gt_stats.c b/drivers/gpu/drm/xe/xe_gt_stats.c
index fb2904bd0abd..8294bcd40310 100644
--- a/drivers/gpu/drm/xe/xe_gt_stats.c
+++ b/drivers/gpu/drm/xe/xe_gt_stats.c
@@ -76,6 +76,11 @@ static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = {
"hw_engine_group_suspend_lr_queue_us"),
DEF_STAT_STR(HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US,
"hw_engine_group_wait_dma_queue_us"),
+ DEF_STAT_STR(PRL_4K_ENTRY_COUNT, "prl_4k_entry_count"),
+ DEF_STAT_STR(PRL_64K_ENTRY_COUNT, "prl_64k_entry_count"),
+ DEF_STAT_STR(PRL_2M_ENTRY_COUNT, "prl_2m_entry_count"),
+ DEF_STAT_STR(PRL_ISSUED_COUNT, "prl_issued_count"),
+ DEF_STAT_STR(PRL_ABORTED_COUNT, "prl_aborted_count"),
};
/**
diff --git a/drivers/gpu/drm/xe/xe_gt_stats_types.h b/drivers/gpu/drm/xe/xe_gt_stats_types.h
index b92d013091d5..b8accdbc54eb 100644
--- a/drivers/gpu/drm/xe/xe_gt_stats_types.h
+++ b/drivers/gpu/drm/xe/xe_gt_stats_types.h
@@ -49,6 +49,11 @@ enum xe_gt_stats_id {
XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_COUNT,
XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_US,
XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US,
+ XE_GT_STATS_ID_PRL_4K_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_64K_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_2M_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_ISSUED_COUNT,
+ XE_GT_STATS_ID_PRL_ABORTED_COUNT,
/* must be the last entry */
__XE_GT_STATS_NUM_IDS,
};
diff --git a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
index 6532a88d51e2..774467befbb9 100644
--- a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
+++ b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
@@ -97,6 +97,7 @@ static int send_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval, u32 seqno)
static int send_page_reclaim(struct xe_guc *guc, u32 seqno,
u64 gpu_addr)
{
+ struct xe_gt *gt = guc_to_gt(guc);
u32 action[] = {
XE_GUC_ACTION_PAGE_RECLAMATION,
seqno,
@@ -104,6 +105,8 @@ static int send_page_reclaim(struct xe_guc *guc, u32 seqno,
upper_32_bits(gpu_addr),
};
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_ISSUED_COUNT, 1);
+
return xe_guc_ct_send(&guc->ct, action, ARRAY_SIZE(action),
G2H_LEN_DW_PAGE_RECLAMATION, 1);
}
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
index 9f086067a4a1..2f5acd3cb408 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.c
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
@@ -12,6 +12,7 @@
#include "regs/xe_gt_regs.h"
#include "xe_assert.h"
+#include "xe_gt_stats.h"
#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_pat.h"
@@ -115,6 +116,7 @@ void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *p
va_list va_args;
xe_page_reclaim_list_invalidate(prl);
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_ABORTED_COUNT, 1);
va_start(va_args, fmt);
vaf.fmt = fmt;
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 668a981696f9..669e7bbde106 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -11,6 +11,7 @@
#include "xe_drm_client.h"
#include "xe_exec_queue.h"
#include "xe_gt.h"
+#include "xe_gt_stats.h"
#include "xe_migrate.h"
#include "xe_page_reclaim.h"
#include "xe_pt_types.h"
@@ -1587,6 +1588,7 @@ static int generate_reclaim_entry(struct xe_tile *tile,
struct xe_page_reclaim_list *prl,
u64 pte, struct xe_pt *xe_child)
{
+ struct xe_gt *gt = tile->primary_gt;
struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
u64 phys_addr = pte & XE_PTE_ADDR_MASK;
u64 phys_page = phys_addr >> XE_PTE_SHIFT;
@@ -1607,12 +1609,15 @@ static int generate_reclaim_entry(struct xe_tile *tile,
* Only 4K, 64K (level 0), and 2M pages are supported by hardware for page reclaim
*/
if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_4K_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
xe_tile_assert(tile, phys_addr % SZ_4K == 0);
} else if (xe_child->level == 0) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_64K_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
xe_tile_assert(tile, phys_addr % SZ_64K == 0);
} else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_2M_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
xe_tile_assert(tile, phys_addr % SZ_2M == 0);
} else {
--
2.52.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* ✓ CI.KUnit: success for Page-reclaim fixes and PRL stats addition (rev2)
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
` (3 preceding siblings ...)
2026-01-05 23:33 ` [PATCH 4/4] drm/xe: Add page reclamation related stats Brian Nguyen
@ 2026-01-05 23:41 ` Patchwork
2026-01-06 1:12 ` ✗ Xe.CI.Full: failure " Patchwork
5 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2026-01-05 23:41 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
== Series Details ==
Series: Page-reclaim fixes and PRL stats addition (rev2)
URL : https://patchwork.freedesktop.org/series/159478/
State : success
== Summary ==
+ trap cleanup EXIT
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
[23:40:17] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[23:40:21] 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
[23:40:52] Starting KUnit Kernel (1/1)...
[23:40:52] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[23:40:53] ================== guc_buf (11 subtests) ===================
[23:40:53] [PASSED] test_smallest
[23:40:53] [PASSED] test_largest
[23:40:53] [PASSED] test_granular
[23:40:53] [PASSED] test_unique
[23:40:53] [PASSED] test_overlap
[23:40:53] [PASSED] test_reusable
[23:40:53] [PASSED] test_too_big
[23:40:53] [PASSED] test_flush
[23:40:53] [PASSED] test_lookup
[23:40:53] [PASSED] test_data
[23:40:53] [PASSED] test_class
[23:40:53] ===================== [PASSED] guc_buf =====================
[23:40:53] =================== guc_dbm (7 subtests) ===================
[23:40:53] [PASSED] test_empty
[23:40:53] [PASSED] test_default
[23:40:53] ======================== test_size ========================
[23:40:53] [PASSED] 4
[23:40:53] [PASSED] 8
[23:40:53] [PASSED] 32
[23:40:53] [PASSED] 256
[23:40:53] ==================== [PASSED] test_size ====================
[23:40:53] ======================= test_reuse ========================
[23:40:53] [PASSED] 4
[23:40:53] [PASSED] 8
[23:40:53] [PASSED] 32
[23:40:53] [PASSED] 256
[23:40:53] =================== [PASSED] test_reuse ====================
[23:40:53] =================== test_range_overlap ====================
[23:40:53] [PASSED] 4
[23:40:53] [PASSED] 8
[23:40:53] [PASSED] 32
[23:40:53] [PASSED] 256
[23:40:53] =============== [PASSED] test_range_overlap ================
[23:40:53] =================== test_range_compact ====================
[23:40:53] [PASSED] 4
[23:40:53] [PASSED] 8
[23:40:53] [PASSED] 32
[23:40:53] [PASSED] 256
[23:40:53] =============== [PASSED] test_range_compact ================
[23:40:53] ==================== test_range_spare =====================
[23:40:53] [PASSED] 4
[23:40:53] [PASSED] 8
[23:40:53] [PASSED] 32
[23:40:53] [PASSED] 256
[23:40:53] ================ [PASSED] test_range_spare =================
[23:40:53] ===================== [PASSED] guc_dbm =====================
[23:40:53] =================== guc_idm (6 subtests) ===================
[23:40:53] [PASSED] bad_init
[23:40:53] [PASSED] no_init
[23:40:53] [PASSED] init_fini
[23:40:53] [PASSED] check_used
[23:40:53] [PASSED] check_quota
[23:40:53] [PASSED] check_all
[23:40:53] ===================== [PASSED] guc_idm =====================
[23:40:53] ================== no_relay (3 subtests) ===================
[23:40:53] [PASSED] xe_drops_guc2pf_if_not_ready
[23:40:53] [PASSED] xe_drops_guc2vf_if_not_ready
[23:40:53] [PASSED] xe_rejects_send_if_not_ready
[23:40:53] ==================== [PASSED] no_relay =====================
[23:40:53] ================== pf_relay (14 subtests) ==================
[23:40:53] [PASSED] pf_rejects_guc2pf_too_short
[23:40:53] [PASSED] pf_rejects_guc2pf_too_long
[23:40:53] [PASSED] pf_rejects_guc2pf_no_payload
[23:40:53] [PASSED] pf_fails_no_payload
[23:40:53] [PASSED] pf_fails_bad_origin
[23:40:53] [PASSED] pf_fails_bad_type
[23:40:53] [PASSED] pf_txn_reports_error
[23:40:53] [PASSED] pf_txn_sends_pf2guc
[23:40:53] [PASSED] pf_sends_pf2guc
[23:40:53] [SKIPPED] pf_loopback_nop
[23:40:53] [SKIPPED] pf_loopback_echo
[23:40:53] [SKIPPED] pf_loopback_fail
[23:40:53] [SKIPPED] pf_loopback_busy
[23:40:53] [SKIPPED] pf_loopback_retry
[23:40:53] ==================== [PASSED] pf_relay =====================
[23:40:53] ================== vf_relay (3 subtests) ===================
[23:40:53] [PASSED] vf_rejects_guc2vf_too_short
[23:40:53] [PASSED] vf_rejects_guc2vf_too_long
[23:40:53] [PASSED] vf_rejects_guc2vf_no_payload
[23:40:53] ==================== [PASSED] vf_relay =====================
[23:40:53] ================ pf_gt_config (6 subtests) =================
[23:40:53] [PASSED] fair_contexts_1vf
[23:40:53] [PASSED] fair_doorbells_1vf
[23:40:53] [PASSED] fair_ggtt_1vf
[23:40:53] ====================== fair_contexts ======================
[23:40:53] [PASSED] 1 VF
[23:40:53] [PASSED] 2 VFs
[23:40:53] [PASSED] 3 VFs
[23:40:53] [PASSED] 4 VFs
[23:40:53] [PASSED] 5 VFs
[23:40:53] [PASSED] 6 VFs
[23:40:53] [PASSED] 7 VFs
[23:40:53] [PASSED] 8 VFs
[23:40:53] [PASSED] 9 VFs
[23:40:53] [PASSED] 10 VFs
[23:40:53] [PASSED] 11 VFs
[23:40:53] [PASSED] 12 VFs
[23:40:53] [PASSED] 13 VFs
[23:40:53] [PASSED] 14 VFs
[23:40:53] [PASSED] 15 VFs
[23:40:53] [PASSED] 16 VFs
[23:40:53] [PASSED] 17 VFs
[23:40:53] [PASSED] 18 VFs
[23:40:53] [PASSED] 19 VFs
[23:40:53] [PASSED] 20 VFs
[23:40:53] [PASSED] 21 VFs
[23:40:53] [PASSED] 22 VFs
[23:40:53] [PASSED] 23 VFs
[23:40:53] [PASSED] 24 VFs
[23:40:53] [PASSED] 25 VFs
[23:40:53] [PASSED] 26 VFs
[23:40:53] [PASSED] 27 VFs
[23:40:53] [PASSED] 28 VFs
[23:40:53] [PASSED] 29 VFs
[23:40:53] [PASSED] 30 VFs
[23:40:53] [PASSED] 31 VFs
[23:40:53] [PASSED] 32 VFs
[23:40:53] [PASSED] 33 VFs
[23:40:53] [PASSED] 34 VFs
[23:40:53] [PASSED] 35 VFs
[23:40:53] [PASSED] 36 VFs
[23:40:53] [PASSED] 37 VFs
[23:40:53] [PASSED] 38 VFs
[23:40:53] [PASSED] 39 VFs
[23:40:53] [PASSED] 40 VFs
[23:40:53] [PASSED] 41 VFs
[23:40:53] [PASSED] 42 VFs
[23:40:53] [PASSED] 43 VFs
[23:40:53] [PASSED] 44 VFs
[23:40:53] [PASSED] 45 VFs
[23:40:53] [PASSED] 46 VFs
[23:40:53] [PASSED] 47 VFs
[23:40:53] [PASSED] 48 VFs
[23:40:53] [PASSED] 49 VFs
[23:40:53] [PASSED] 50 VFs
[23:40:53] [PASSED] 51 VFs
[23:40:53] [PASSED] 52 VFs
[23:40:53] [PASSED] 53 VFs
[23:40:53] [PASSED] 54 VFs
[23:40:53] [PASSED] 55 VFs
[23:40:53] [PASSED] 56 VFs
[23:40:53] [PASSED] 57 VFs
[23:40:53] [PASSED] 58 VFs
[23:40:53] [PASSED] 59 VFs
[23:40:53] [PASSED] 60 VFs
[23:40:53] [PASSED] 61 VFs
[23:40:53] [PASSED] 62 VFs
[23:40:53] [PASSED] 63 VFs
[23:40:53] ================== [PASSED] fair_contexts ==================
[23:40:53] ===================== fair_doorbells ======================
[23:40:53] [PASSED] 1 VF
[23:40:53] [PASSED] 2 VFs
[23:40:53] [PASSED] 3 VFs
[23:40:53] [PASSED] 4 VFs
[23:40:53] [PASSED] 5 VFs
[23:40:53] [PASSED] 6 VFs
[23:40:53] [PASSED] 7 VFs
[23:40:53] [PASSED] 8 VFs
[23:40:53] [PASSED] 9 VFs
[23:40:53] [PASSED] 10 VFs
[23:40:53] [PASSED] 11 VFs
[23:40:53] [PASSED] 12 VFs
[23:40:53] [PASSED] 13 VFs
[23:40:53] [PASSED] 14 VFs
[23:40:53] [PASSED] 15 VFs
[23:40:53] [PASSED] 16 VFs
[23:40:53] [PASSED] 17 VFs
[23:40:53] [PASSED] 18 VFs
[23:40:53] [PASSED] 19 VFs
[23:40:53] [PASSED] 20 VFs
[23:40:53] [PASSED] 21 VFs
[23:40:53] [PASSED] 22 VFs
[23:40:53] [PASSED] 23 VFs
[23:40:53] [PASSED] 24 VFs
[23:40:53] [PASSED] 25 VFs
[23:40:53] [PASSED] 26 VFs
[23:40:53] [PASSED] 27 VFs
[23:40:53] [PASSED] 28 VFs
[23:40:53] [PASSED] 29 VFs
[23:40:53] [PASSED] 30 VFs
[23:40:53] [PASSED] 31 VFs
[23:40:53] [PASSED] 32 VFs
[23:40:53] [PASSED] 33 VFs
[23:40:53] [PASSED] 34 VFs
[23:40:53] [PASSED] 35 VFs
[23:40:53] [PASSED] 36 VFs
[23:40:53] [PASSED] 37 VFs
[23:40:53] [PASSED] 38 VFs
[23:40:53] [PASSED] 39 VFs
[23:40:53] [PASSED] 40 VFs
[23:40:53] [PASSED] 41 VFs
[23:40:53] [PASSED] 42 VFs
[23:40:53] [PASSED] 43 VFs
[23:40:53] [PASSED] 44 VFs
[23:40:53] [PASSED] 45 VFs
[23:40:53] [PASSED] 46 VFs
[23:40:53] [PASSED] 47 VFs
[23:40:53] [PASSED] 48 VFs
[23:40:53] [PASSED] 49 VFs
[23:40:53] [PASSED] 50 VFs
[23:40:53] [PASSED] 51 VFs
[23:40:53] [PASSED] 52 VFs
[23:40:53] [PASSED] 53 VFs
[23:40:53] [PASSED] 54 VFs
[23:40:53] [PASSED] 55 VFs
[23:40:53] [PASSED] 56 VFs
[23:40:53] [PASSED] 57 VFs
[23:40:53] [PASSED] 58 VFs
[23:40:53] [PASSED] 59 VFs
[23:40:53] [PASSED] 60 VFs
[23:40:53] [PASSED] 61 VFs
[23:40:53] [PASSED] 62 VFs
[23:40:53] [PASSED] 63 VFs
[23:40:53] ================= [PASSED] fair_doorbells ==================
[23:40:53] ======================== fair_ggtt ========================
[23:40:53] [PASSED] 1 VF
[23:40:53] [PASSED] 2 VFs
[23:40:53] [PASSED] 3 VFs
[23:40:53] [PASSED] 4 VFs
[23:40:53] [PASSED] 5 VFs
[23:40:53] [PASSED] 6 VFs
[23:40:53] [PASSED] 7 VFs
[23:40:53] [PASSED] 8 VFs
[23:40:53] [PASSED] 9 VFs
[23:40:53] [PASSED] 10 VFs
[23:40:53] [PASSED] 11 VFs
[23:40:53] [PASSED] 12 VFs
[23:40:53] [PASSED] 13 VFs
[23:40:53] [PASSED] 14 VFs
[23:40:53] [PASSED] 15 VFs
[23:40:53] [PASSED] 16 VFs
[23:40:53] [PASSED] 17 VFs
[23:40:53] [PASSED] 18 VFs
[23:40:53] [PASSED] 19 VFs
[23:40:53] [PASSED] 20 VFs
[23:40:53] [PASSED] 21 VFs
[23:40:53] [PASSED] 22 VFs
[23:40:53] [PASSED] 23 VFs
[23:40:53] [PASSED] 24 VFs
[23:40:53] [PASSED] 25 VFs
[23:40:53] [PASSED] 26 VFs
[23:40:53] [PASSED] 27 VFs
[23:40:53] [PASSED] 28 VFs
[23:40:53] [PASSED] 29 VFs
[23:40:53] [PASSED] 30 VFs
[23:40:53] [PASSED] 31 VFs
[23:40:53] [PASSED] 32 VFs
[23:40:53] [PASSED] 33 VFs
[23:40:53] [PASSED] 34 VFs
[23:40:53] [PASSED] 35 VFs
[23:40:53] [PASSED] 36 VFs
[23:40:53] [PASSED] 37 VFs
[23:40:53] [PASSED] 38 VFs
[23:40:53] [PASSED] 39 VFs
[23:40:53] [PASSED] 40 VFs
[23:40:53] [PASSED] 41 VFs
[23:40:53] [PASSED] 42 VFs
[23:40:53] [PASSED] 43 VFs
[23:40:53] [PASSED] 44 VFs
[23:40:53] [PASSED] 45 VFs
[23:40:53] [PASSED] 46 VFs
[23:40:53] [PASSED] 47 VFs
[23:40:53] [PASSED] 48 VFs
[23:40:53] [PASSED] 49 VFs
[23:40:53] [PASSED] 50 VFs
[23:40:53] [PASSED] 51 VFs
[23:40:53] [PASSED] 52 VFs
[23:40:53] [PASSED] 53 VFs
[23:40:53] [PASSED] 54 VFs
[23:40:53] [PASSED] 55 VFs
[23:40:53] [PASSED] 56 VFs
[23:40:53] [PASSED] 57 VFs
[23:40:53] [PASSED] 58 VFs
[23:40:53] [PASSED] 59 VFs
[23:40:53] [PASSED] 60 VFs
[23:40:53] [PASSED] 61 VFs
[23:40:53] [PASSED] 62 VFs
[23:40:53] [PASSED] 63 VFs
[23:40:53] ==================== [PASSED] fair_ggtt ====================
[23:40:53] ================== [PASSED] pf_gt_config ===================
[23:40:53] ===================== lmtt (1 subtest) =====================
[23:40:53] ======================== test_ops =========================
[23:40:53] [PASSED] 2-level
[23:40:53] [PASSED] multi-level
[23:40:53] ==================== [PASSED] test_ops =====================
[23:40:53] ====================== [PASSED] lmtt =======================
[23:40:53] ================= pf_service (11 subtests) =================
[23:40:53] [PASSED] pf_negotiate_any
[23:40:53] [PASSED] pf_negotiate_base_match
[23:40:53] [PASSED] pf_negotiate_base_newer
[23:40:53] [PASSED] pf_negotiate_base_next
[23:40:53] [SKIPPED] pf_negotiate_base_older
[23:40:53] [PASSED] pf_negotiate_base_prev
[23:40:53] [PASSED] pf_negotiate_latest_match
[23:40:53] [PASSED] pf_negotiate_latest_newer
[23:40:53] [PASSED] pf_negotiate_latest_next
[23:40:53] [SKIPPED] pf_negotiate_latest_older
[23:40:53] [SKIPPED] pf_negotiate_latest_prev
[23:40:53] =================== [PASSED] pf_service ====================
[23:40:53] ================= xe_guc_g2g (2 subtests) ==================
[23:40:53] ============== xe_live_guc_g2g_kunit_default ==============
[23:40:53] ========= [SKIPPED] xe_live_guc_g2g_kunit_default ==========
[23:40:53] ============== xe_live_guc_g2g_kunit_allmem ===============
[23:40:53] ========== [SKIPPED] xe_live_guc_g2g_kunit_allmem ==========
[23:40:53] =================== [SKIPPED] xe_guc_g2g ===================
[23:40:53] =================== xe_mocs (2 subtests) ===================
[23:40:53] ================ xe_live_mocs_kernel_kunit ================
[23:40:53] =========== [SKIPPED] xe_live_mocs_kernel_kunit ============
[23:40:53] ================ xe_live_mocs_reset_kunit =================
[23:40:53] ============ [SKIPPED] xe_live_mocs_reset_kunit ============
[23:40:53] ==================== [SKIPPED] xe_mocs =====================
[23:40:53] ================= xe_migrate (2 subtests) ==================
[23:40:53] ================= xe_migrate_sanity_kunit =================
[23:40:53] ============ [SKIPPED] xe_migrate_sanity_kunit =============
[23:40:53] ================== xe_validate_ccs_kunit ==================
[23:40:53] ============= [SKIPPED] xe_validate_ccs_kunit ==============
[23:40:53] =================== [SKIPPED] xe_migrate ===================
[23:40:53] ================== xe_dma_buf (1 subtest) ==================
[23:40:53] ==================== xe_dma_buf_kunit =====================
[23:40:53] ================ [SKIPPED] xe_dma_buf_kunit ================
[23:40:53] =================== [SKIPPED] xe_dma_buf ===================
[23:40:53] ================= xe_bo_shrink (1 subtest) =================
[23:40:53] =================== xe_bo_shrink_kunit ====================
[23:40:53] =============== [SKIPPED] xe_bo_shrink_kunit ===============
[23:40:53] ================== [SKIPPED] xe_bo_shrink ==================
[23:40:53] ==================== xe_bo (2 subtests) ====================
[23:40:53] ================== xe_ccs_migrate_kunit ===================
[23:40:53] ============== [SKIPPED] xe_ccs_migrate_kunit ==============
[23:40:53] ==================== xe_bo_evict_kunit ====================
[23:40:53] =============== [SKIPPED] xe_bo_evict_kunit ================
[23:40:53] ===================== [SKIPPED] xe_bo ======================
[23:40:53] ==================== args (13 subtests) ====================
[23:40:53] [PASSED] count_args_test
[23:40:53] [PASSED] call_args_example
[23:40:53] [PASSED] call_args_test
[23:40:53] [PASSED] drop_first_arg_example
[23:40:53] [PASSED] drop_first_arg_test
[23:40:53] [PASSED] first_arg_example
[23:40:53] [PASSED] first_arg_test
[23:40:53] [PASSED] last_arg_example
[23:40:53] [PASSED] last_arg_test
[23:40:53] [PASSED] pick_arg_example
[23:40:53] [PASSED] if_args_example
[23:40:53] [PASSED] if_args_test
[23:40:53] [PASSED] sep_comma_example
[23:40:53] ====================== [PASSED] args =======================
[23:40:53] =================== xe_pci (3 subtests) ====================
[23:40:53] ==================== check_graphics_ip ====================
[23:40:53] [PASSED] 12.00 Xe_LP
[23:40:53] [PASSED] 12.10 Xe_LP+
[23:40:53] [PASSED] 12.55 Xe_HPG
[23:40:53] [PASSED] 12.60 Xe_HPC
[23:40:53] [PASSED] 12.70 Xe_LPG
[23:40:53] [PASSED] 12.71 Xe_LPG
[23:40:53] [PASSED] 12.74 Xe_LPG+
[23:40:53] [PASSED] 20.01 Xe2_HPG
[23:40:53] [PASSED] 20.02 Xe2_HPG
[23:40:53] [PASSED] 20.04 Xe2_LPG
[23:40:53] [PASSED] 30.00 Xe3_LPG
[23:40:53] [PASSED] 30.01 Xe3_LPG
[23:40:53] [PASSED] 30.03 Xe3_LPG
[23:40:53] [PASSED] 30.04 Xe3_LPG
[23:40:53] [PASSED] 30.05 Xe3_LPG
[23:40:53] [PASSED] 35.11 Xe3p_XPC
[23:40:53] ================ [PASSED] check_graphics_ip ================
[23:40:53] ===================== check_media_ip ======================
[23:40:53] [PASSED] 12.00 Xe_M
[23:40:53] [PASSED] 12.55 Xe_HPM
[23:40:53] [PASSED] 13.00 Xe_LPM+
[23:40:53] [PASSED] 13.01 Xe2_HPM
[23:40:53] [PASSED] 20.00 Xe2_LPM
[23:40:53] [PASSED] 30.00 Xe3_LPM
[23:40:53] [PASSED] 30.02 Xe3_LPM
[23:40:53] [PASSED] 35.00 Xe3p_LPM
[23:40:53] [PASSED] 35.03 Xe3p_HPM
[23:40:53] ================= [PASSED] check_media_ip ==================
[23:40:53] =================== check_platform_desc ===================
[23:40:53] [PASSED] 0x9A60 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A68 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A70 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A40 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A49 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A59 (TIGERLAKE)
[23:40:53] [PASSED] 0x9A78 (TIGERLAKE)
[23:40:53] [PASSED] 0x9AC0 (TIGERLAKE)
[23:40:53] [PASSED] 0x9AC9 (TIGERLAKE)
[23:40:53] [PASSED] 0x9AD9 (TIGERLAKE)
[23:40:53] [PASSED] 0x9AF8 (TIGERLAKE)
[23:40:53] [PASSED] 0x4C80 (ROCKETLAKE)
[23:40:53] [PASSED] 0x4C8A (ROCKETLAKE)
[23:40:53] [PASSED] 0x4C8B (ROCKETLAKE)
[23:40:53] [PASSED] 0x4C8C (ROCKETLAKE)
[23:40:53] [PASSED] 0x4C90 (ROCKETLAKE)
[23:40:53] [PASSED] 0x4C9A (ROCKETLAKE)
[23:40:53] [PASSED] 0x4680 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4682 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4688 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x468A (ALDERLAKE_S)
[23:40:53] [PASSED] 0x468B (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4690 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4692 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4693 (ALDERLAKE_S)
[23:40:53] [PASSED] 0x46A0 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46A1 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46A2 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46A3 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46A6 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46A8 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46AA (ALDERLAKE_P)
[23:40:53] [PASSED] 0x462A (ALDERLAKE_P)
[23:40:53] [PASSED] 0x4626 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x4628 (ALDERLAKE_P)
stty: 'standard input': Inappropriate ioctl for device
[23:40:53] [PASSED] 0x46B0 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46B1 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46B2 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46B3 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46C0 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46C1 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46C2 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46C3 (ALDERLAKE_P)
[23:40:53] [PASSED] 0x46D0 (ALDERLAKE_N)
[23:40:53] [PASSED] 0x46D1 (ALDERLAKE_N)
[23:40:53] [PASSED] 0x46D2 (ALDERLAKE_N)
[23:40:53] [PASSED] 0x46D3 (ALDERLAKE_N)
[23:40:53] [PASSED] 0x46D4 (ALDERLAKE_N)
[23:40:53] [PASSED] 0xA721 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7A1 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7A9 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7AC (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7AD (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA720 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7A0 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7A8 (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7AA (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA7AB (ALDERLAKE_P)
[23:40:53] [PASSED] 0xA780 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA781 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA782 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA783 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA788 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA789 (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA78A (ALDERLAKE_S)
[23:40:53] [PASSED] 0xA78B (ALDERLAKE_S)
[23:40:53] [PASSED] 0x4905 (DG1)
[23:40:53] [PASSED] 0x4906 (DG1)
[23:40:53] [PASSED] 0x4907 (DG1)
[23:40:53] [PASSED] 0x4908 (DG1)
[23:40:53] [PASSED] 0x4909 (DG1)
[23:40:53] [PASSED] 0x56C0 (DG2)
[23:40:53] [PASSED] 0x56C2 (DG2)
[23:40:53] [PASSED] 0x56C1 (DG2)
[23:40:53] [PASSED] 0x7D51 (METEORLAKE)
[23:40:53] [PASSED] 0x7DD1 (METEORLAKE)
[23:40:53] [PASSED] 0x7D41 (METEORLAKE)
[23:40:53] [PASSED] 0x7D67 (METEORLAKE)
[23:40:53] [PASSED] 0xB640 (METEORLAKE)
[23:40:53] [PASSED] 0x56A0 (DG2)
[23:40:53] [PASSED] 0x56A1 (DG2)
[23:40:53] [PASSED] 0x56A2 (DG2)
[23:40:53] [PASSED] 0x56BE (DG2)
[23:40:53] [PASSED] 0x56BF (DG2)
[23:40:53] [PASSED] 0x5690 (DG2)
[23:40:53] [PASSED] 0x5691 (DG2)
[23:40:53] [PASSED] 0x5692 (DG2)
[23:40:53] [PASSED] 0x56A5 (DG2)
[23:40:53] [PASSED] 0x56A6 (DG2)
[23:40:53] [PASSED] 0x56B0 (DG2)
[23:40:53] [PASSED] 0x56B1 (DG2)
[23:40:53] [PASSED] 0x56BA (DG2)
[23:40:53] [PASSED] 0x56BB (DG2)
[23:40:53] [PASSED] 0x56BC (DG2)
[23:40:53] [PASSED] 0x56BD (DG2)
[23:40:53] [PASSED] 0x5693 (DG2)
[23:40:53] [PASSED] 0x5694 (DG2)
[23:40:53] [PASSED] 0x5695 (DG2)
[23:40:53] [PASSED] 0x56A3 (DG2)
[23:40:53] [PASSED] 0x56A4 (DG2)
[23:40:53] [PASSED] 0x56B2 (DG2)
[23:40:53] [PASSED] 0x56B3 (DG2)
[23:40:53] [PASSED] 0x5696 (DG2)
[23:40:53] [PASSED] 0x5697 (DG2)
[23:40:53] [PASSED] 0xB69 (PVC)
[23:40:53] [PASSED] 0xB6E (PVC)
[23:40:53] [PASSED] 0xBD4 (PVC)
[23:40:53] [PASSED] 0xBD5 (PVC)
[23:40:53] [PASSED] 0xBD6 (PVC)
[23:40:53] [PASSED] 0xBD7 (PVC)
[23:40:53] [PASSED] 0xBD8 (PVC)
[23:40:53] [PASSED] 0xBD9 (PVC)
[23:40:53] [PASSED] 0xBDA (PVC)
[23:40:53] [PASSED] 0xBDB (PVC)
[23:40:53] [PASSED] 0xBE0 (PVC)
[23:40:53] [PASSED] 0xBE1 (PVC)
[23:40:53] [PASSED] 0xBE5 (PVC)
[23:40:53] [PASSED] 0x7D40 (METEORLAKE)
[23:40:53] [PASSED] 0x7D45 (METEORLAKE)
[23:40:53] [PASSED] 0x7D55 (METEORLAKE)
[23:40:53] [PASSED] 0x7D60 (METEORLAKE)
[23:40:53] [PASSED] 0x7DD5 (METEORLAKE)
[23:40:53] [PASSED] 0x6420 (LUNARLAKE)
[23:40:53] [PASSED] 0x64A0 (LUNARLAKE)
[23:40:53] [PASSED] 0x64B0 (LUNARLAKE)
[23:40:53] [PASSED] 0xE202 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE209 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE20B (BATTLEMAGE)
[23:40:53] [PASSED] 0xE20C (BATTLEMAGE)
[23:40:53] [PASSED] 0xE20D (BATTLEMAGE)
[23:40:53] [PASSED] 0xE210 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE211 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE212 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE216 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE220 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE221 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE222 (BATTLEMAGE)
[23:40:53] [PASSED] 0xE223 (BATTLEMAGE)
[23:40:53] [PASSED] 0xB080 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB081 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB082 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB083 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB084 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB085 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB086 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB087 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB08F (PANTHERLAKE)
[23:40:53] [PASSED] 0xB090 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB0A0 (PANTHERLAKE)
[23:40:53] [PASSED] 0xB0B0 (PANTHERLAKE)
[23:40:53] [PASSED] 0xFD80 (PANTHERLAKE)
[23:40:53] [PASSED] 0xFD81 (PANTHERLAKE)
[23:40:53] [PASSED] 0xD740 (NOVALAKE_S)
[23:40:53] [PASSED] 0xD741 (NOVALAKE_S)
[23:40:53] [PASSED] 0xD742 (NOVALAKE_S)
[23:40:53] [PASSED] 0xD743 (NOVALAKE_S)
[23:40:53] [PASSED] 0xD744 (NOVALAKE_S)
[23:40:53] [PASSED] 0xD745 (NOVALAKE_S)
[23:40:53] [PASSED] 0x674C (CRESCENTISLAND)
[23:40:53] =============== [PASSED] check_platform_desc ===============
[23:40:53] ===================== [PASSED] xe_pci ======================
[23:40:53] =================== xe_rtp (2 subtests) ====================
[23:40:53] =============== xe_rtp_process_to_sr_tests ================
[23:40:53] [PASSED] coalesce-same-reg
[23:40:53] [PASSED] no-match-no-add
[23:40:53] [PASSED] match-or
[23:40:53] [PASSED] match-or-xfail
[23:40:53] [PASSED] no-match-no-add-multiple-rules
[23:40:53] [PASSED] two-regs-two-entries
[23:40:53] [PASSED] clr-one-set-other
[23:40:53] [PASSED] set-field
[23:40:53] [PASSED] conflict-duplicate
[23:40:53] [PASSED] conflict-not-disjoint
[23:40:53] [PASSED] conflict-reg-type
[23:40:53] =========== [PASSED] xe_rtp_process_to_sr_tests ============
[23:40:53] ================== xe_rtp_process_tests ===================
[23:40:53] [PASSED] active1
[23:40:53] [PASSED] active2
[23:40:53] [PASSED] active-inactive
[23:40:53] [PASSED] inactive-active
[23:40:53] [PASSED] inactive-1st_or_active-inactive
[23:40:53] [PASSED] inactive-2nd_or_active-inactive
[23:40:53] [PASSED] inactive-last_or_active-inactive
[23:40:53] [PASSED] inactive-no_or_active-inactive
[23:40:53] ============== [PASSED] xe_rtp_process_tests ===============
[23:40:53] ===================== [PASSED] xe_rtp ======================
[23:40:53] ==================== xe_wa (1 subtest) =====================
[23:40:53] ======================== xe_wa_gt =========================
[23:40:53] [PASSED] TIGERLAKE B0
[23:40:53] [PASSED] DG1 A0
[23:40:53] [PASSED] DG1 B0
[23:40:53] [PASSED] ALDERLAKE_S A0
[23:40:53] [PASSED] ALDERLAKE_S B0
[23:40:53] [PASSED] ALDERLAKE_S C0
[23:40:53] [PASSED] ALDERLAKE_S D0
[23:40:53] [PASSED] ALDERLAKE_P A0
[23:40:53] [PASSED] ALDERLAKE_P B0
[23:40:53] [PASSED] ALDERLAKE_P C0
[23:40:53] [PASSED] ALDERLAKE_S RPLS D0
[23:40:53] [PASSED] ALDERLAKE_P RPLU E0
[23:40:53] [PASSED] DG2 G10 C0
[23:40:53] [PASSED] DG2 G11 B1
[23:40:53] [PASSED] DG2 G12 A1
[23:40:53] [PASSED] METEORLAKE 12.70(Xe_LPG) A0 13.00(Xe_LPM+) A0
[23:40:53] [PASSED] METEORLAKE 12.71(Xe_LPG) A0 13.00(Xe_LPM+) A0
[23:40:53] [PASSED] METEORLAKE 12.74(Xe_LPG+) A0 13.00(Xe_LPM+) A0
[23:40:53] [PASSED] LUNARLAKE 20.04(Xe2_LPG) A0 20.00(Xe2_LPM) A0
[23:40:53] [PASSED] LUNARLAKE 20.04(Xe2_LPG) B0 20.00(Xe2_LPM) A0
[23:40:53] [PASSED] BATTLEMAGE 20.01(Xe2_HPG) A0 13.01(Xe2_HPM) A1
[23:40:53] [PASSED] PANTHERLAKE 30.00(Xe3_LPG) A0 30.00(Xe3_LPM) A0
[23:40:53] ==================== [PASSED] xe_wa_gt =====================
[23:40:53] ====================== [PASSED] xe_wa ======================
[23:40:53] ============================================================
[23:40:53] Testing complete. Ran 512 tests: passed: 494, skipped: 18
[23:40:53] Elapsed time: 36.278s total, 4.241s configuring, 31.570s building, 0.453s running
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/tests/.kunitconfig
[23:40:53] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[23:40:55] 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
[23:41:20] Starting KUnit Kernel (1/1)...
[23:41:20] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[23:41:20] ============ drm_test_pick_cmdline (2 subtests) ============
[23:41:20] [PASSED] drm_test_pick_cmdline_res_1920_1080_60
[23:41:20] =============== drm_test_pick_cmdline_named ===============
[23:41:20] [PASSED] NTSC
[23:41:20] [PASSED] NTSC-J
[23:41:20] [PASSED] PAL
[23:41:20] [PASSED] PAL-M
[23:41:20] =========== [PASSED] drm_test_pick_cmdline_named ===========
[23:41:20] ============== [PASSED] drm_test_pick_cmdline ==============
[23:41:20] == drm_test_atomic_get_connector_for_encoder (1 subtest) ===
[23:41:20] [PASSED] drm_test_drm_atomic_get_connector_for_encoder
[23:41:20] ==== [PASSED] drm_test_atomic_get_connector_for_encoder ====
[23:41:20] =========== drm_validate_clone_mode (2 subtests) ===========
[23:41:20] ============== drm_test_check_in_clone_mode ===============
[23:41:20] [PASSED] in_clone_mode
[23:41:20] [PASSED] not_in_clone_mode
[23:41:20] ========== [PASSED] drm_test_check_in_clone_mode ===========
[23:41:20] =============== drm_test_check_valid_clones ===============
[23:41:20] [PASSED] not_in_clone_mode
[23:41:20] [PASSED] valid_clone
[23:41:20] [PASSED] invalid_clone
[23:41:20] =========== [PASSED] drm_test_check_valid_clones ===========
[23:41:20] ============= [PASSED] drm_validate_clone_mode =============
[23:41:20] ============= drm_validate_modeset (1 subtest) =============
[23:41:20] [PASSED] drm_test_check_connector_changed_modeset
[23:41:20] ============== [PASSED] drm_validate_modeset ===============
[23:41:20] ====== drm_test_bridge_get_current_state (2 subtests) ======
[23:41:20] [PASSED] drm_test_drm_bridge_get_current_state_atomic
[23:41:20] [PASSED] drm_test_drm_bridge_get_current_state_legacy
[23:41:20] ======== [PASSED] drm_test_bridge_get_current_state ========
[23:41:20] ====== drm_test_bridge_helper_reset_crtc (3 subtests) ======
[23:41:20] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic
[23:41:20] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic_disabled
[23:41:20] [PASSED] drm_test_drm_bridge_helper_reset_crtc_legacy
[23:41:20] ======== [PASSED] drm_test_bridge_helper_reset_crtc ========
[23:41:20] ============== drm_bridge_alloc (2 subtests) ===============
[23:41:20] [PASSED] drm_test_drm_bridge_alloc_basic
[23:41:20] [PASSED] drm_test_drm_bridge_alloc_get_put
[23:41:20] ================ [PASSED] drm_bridge_alloc =================
[23:41:20] ================== drm_buddy (8 subtests) ==================
[23:41:20] [PASSED] drm_test_buddy_alloc_limit
[23:41:20] [PASSED] drm_test_buddy_alloc_optimistic
[23:41:20] [PASSED] drm_test_buddy_alloc_pessimistic
[23:41:20] [PASSED] drm_test_buddy_alloc_pathological
[23:41:20] [PASSED] drm_test_buddy_alloc_contiguous
[23:41:20] [PASSED] drm_test_buddy_alloc_clear
[23:41:20] [PASSED] drm_test_buddy_alloc_range_bias
[23:41:20] [PASSED] drm_test_buddy_fragmentation_performance
[23:41:20] ==================== [PASSED] drm_buddy ====================
[23:41:20] ============= drm_cmdline_parser (40 subtests) =============
[23:41:20] [PASSED] drm_test_cmdline_force_d_only
[23:41:20] [PASSED] drm_test_cmdline_force_D_only_dvi
[23:41:20] [PASSED] drm_test_cmdline_force_D_only_hdmi
[23:41:20] [PASSED] drm_test_cmdline_force_D_only_not_digital
[23:41:20] [PASSED] drm_test_cmdline_force_e_only
[23:41:20] [PASSED] drm_test_cmdline_res
[23:41:20] [PASSED] drm_test_cmdline_res_vesa
[23:41:20] [PASSED] drm_test_cmdline_res_vesa_rblank
[23:41:20] [PASSED] drm_test_cmdline_res_rblank
[23:41:20] [PASSED] drm_test_cmdline_res_bpp
[23:41:20] [PASSED] drm_test_cmdline_res_refresh
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_margins
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_force_off
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_analog
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_digital
[23:41:20] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on
[23:41:20] [PASSED] drm_test_cmdline_res_margins_force_on
[23:41:20] [PASSED] drm_test_cmdline_res_vesa_margins
[23:41:20] [PASSED] drm_test_cmdline_name
[23:41:20] [PASSED] drm_test_cmdline_name_bpp
[23:41:20] [PASSED] drm_test_cmdline_name_option
[23:41:20] [PASSED] drm_test_cmdline_name_bpp_option
[23:41:20] [PASSED] drm_test_cmdline_rotate_0
[23:41:20] [PASSED] drm_test_cmdline_rotate_90
[23:41:20] [PASSED] drm_test_cmdline_rotate_180
[23:41:20] [PASSED] drm_test_cmdline_rotate_270
[23:41:20] [PASSED] drm_test_cmdline_hmirror
[23:41:20] [PASSED] drm_test_cmdline_vmirror
[23:41:20] [PASSED] drm_test_cmdline_margin_options
[23:41:20] [PASSED] drm_test_cmdline_multiple_options
[23:41:20] [PASSED] drm_test_cmdline_bpp_extra_and_option
[23:41:20] [PASSED] drm_test_cmdline_extra_and_option
[23:41:20] [PASSED] drm_test_cmdline_freestanding_options
[23:41:20] [PASSED] drm_test_cmdline_freestanding_force_e_and_options
[23:41:20] [PASSED] drm_test_cmdline_panel_orientation
[23:41:20] ================ drm_test_cmdline_invalid =================
[23:41:20] [PASSED] margin_only
[23:41:20] [PASSED] interlace_only
[23:41:20] [PASSED] res_missing_x
[23:41:20] [PASSED] res_missing_y
[23:41:20] [PASSED] res_bad_y
[23:41:20] [PASSED] res_missing_y_bpp
[23:41:20] [PASSED] res_bad_bpp
[23:41:20] [PASSED] res_bad_refresh
[23:41:20] [PASSED] res_bpp_refresh_force_on_off
[23:41:20] [PASSED] res_invalid_mode
[23:41:20] [PASSED] res_bpp_wrong_place_mode
[23:41:20] [PASSED] name_bpp_refresh
[23:41:20] [PASSED] name_refresh
[23:41:20] [PASSED] name_refresh_wrong_mode
[23:41:20] [PASSED] name_refresh_invalid_mode
[23:41:20] [PASSED] rotate_multiple
[23:41:20] [PASSED] rotate_invalid_val
[23:41:20] [PASSED] rotate_truncated
[23:41:20] [PASSED] invalid_option
[23:41:20] [PASSED] invalid_tv_option
[23:41:20] [PASSED] truncated_tv_option
[23:41:20] ============ [PASSED] drm_test_cmdline_invalid =============
[23:41:20] =============== drm_test_cmdline_tv_options ===============
[23:41:20] [PASSED] NTSC
[23:41:20] [PASSED] NTSC_443
[23:41:20] [PASSED] NTSC_J
[23:41:20] [PASSED] PAL
[23:41:20] [PASSED] PAL_M
[23:41:20] [PASSED] PAL_N
[23:41:20] [PASSED] SECAM
[23:41:20] [PASSED] MONO_525
[23:41:20] [PASSED] MONO_625
[23:41:20] =========== [PASSED] drm_test_cmdline_tv_options ===========
[23:41:20] =============== [PASSED] drm_cmdline_parser ================
[23:41:20] ========== drmm_connector_hdmi_init (20 subtests) ==========
[23:41:20] [PASSED] drm_test_connector_hdmi_init_valid
[23:41:20] [PASSED] drm_test_connector_hdmi_init_bpc_8
[23:41:20] [PASSED] drm_test_connector_hdmi_init_bpc_10
[23:41:20] [PASSED] drm_test_connector_hdmi_init_bpc_12
[23:41:20] [PASSED] drm_test_connector_hdmi_init_bpc_invalid
[23:41:20] [PASSED] drm_test_connector_hdmi_init_bpc_null
[23:41:20] [PASSED] drm_test_connector_hdmi_init_formats_empty
[23:41:20] [PASSED] drm_test_connector_hdmi_init_formats_no_rgb
[23:41:20] === drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[23:41:20] [PASSED] supported_formats=0x9 yuv420_allowed=1
[23:41:20] [PASSED] supported_formats=0x9 yuv420_allowed=0
[23:41:20] [PASSED] supported_formats=0x3 yuv420_allowed=1
[23:41:20] [PASSED] supported_formats=0x3 yuv420_allowed=0
[23:41:20] === [PASSED] drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[23:41:20] [PASSED] drm_test_connector_hdmi_init_null_ddc
[23:41:20] [PASSED] drm_test_connector_hdmi_init_null_product
[23:41:20] [PASSED] drm_test_connector_hdmi_init_null_vendor
[23:41:20] [PASSED] drm_test_connector_hdmi_init_product_length_exact
[23:41:20] [PASSED] drm_test_connector_hdmi_init_product_length_too_long
[23:41:20] [PASSED] drm_test_connector_hdmi_init_product_valid
[23:41:20] [PASSED] drm_test_connector_hdmi_init_vendor_length_exact
[23:41:20] [PASSED] drm_test_connector_hdmi_init_vendor_length_too_long
[23:41:20] [PASSED] drm_test_connector_hdmi_init_vendor_valid
[23:41:20] ========= drm_test_connector_hdmi_init_type_valid =========
[23:41:20] [PASSED] HDMI-A
[23:41:20] [PASSED] HDMI-B
[23:41:20] ===== [PASSED] drm_test_connector_hdmi_init_type_valid =====
[23:41:20] ======== drm_test_connector_hdmi_init_type_invalid ========
[23:41:20] [PASSED] Unknown
[23:41:20] [PASSED] VGA
[23:41:20] [PASSED] DVI-I
[23:41:20] [PASSED] DVI-D
[23:41:20] [PASSED] DVI-A
[23:41:20] [PASSED] Composite
[23:41:20] [PASSED] SVIDEO
[23:41:20] [PASSED] LVDS
[23:41:20] [PASSED] Component
[23:41:20] [PASSED] DIN
[23:41:20] [PASSED] DP
[23:41:20] [PASSED] TV
[23:41:20] [PASSED] eDP
[23:41:20] [PASSED] Virtual
[23:41:20] [PASSED] DSI
[23:41:20] [PASSED] DPI
[23:41:20] [PASSED] Writeback
[23:41:20] [PASSED] SPI
[23:41:20] [PASSED] USB
[23:41:20] ==== [PASSED] drm_test_connector_hdmi_init_type_invalid ====
[23:41:20] ============ [PASSED] drmm_connector_hdmi_init =============
[23:41:20] ============= drmm_connector_init (3 subtests) =============
[23:41:20] [PASSED] drm_test_drmm_connector_init
[23:41:20] [PASSED] drm_test_drmm_connector_init_null_ddc
[23:41:20] ========= drm_test_drmm_connector_init_type_valid =========
[23:41:20] [PASSED] Unknown
[23:41:20] [PASSED] VGA
[23:41:20] [PASSED] DVI-I
[23:41:20] [PASSED] DVI-D
[23:41:20] [PASSED] DVI-A
[23:41:20] [PASSED] Composite
[23:41:20] [PASSED] SVIDEO
[23:41:20] [PASSED] LVDS
[23:41:20] [PASSED] Component
[23:41:20] [PASSED] DIN
[23:41:20] [PASSED] DP
[23:41:20] [PASSED] HDMI-A
[23:41:20] [PASSED] HDMI-B
[23:41:20] [PASSED] TV
[23:41:20] [PASSED] eDP
[23:41:20] [PASSED] Virtual
[23:41:20] [PASSED] DSI
[23:41:20] [PASSED] DPI
[23:41:20] [PASSED] Writeback
[23:41:20] [PASSED] SPI
[23:41:20] [PASSED] USB
[23:41:20] ===== [PASSED] drm_test_drmm_connector_init_type_valid =====
[23:41:20] =============== [PASSED] drmm_connector_init ===============
[23:41:20] ========= drm_connector_dynamic_init (6 subtests) ==========
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_init
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_init_null_ddc
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_init_not_added
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_init_properties
[23:41:20] ===== drm_test_drm_connector_dynamic_init_type_valid ======
[23:41:20] [PASSED] Unknown
[23:41:20] [PASSED] VGA
[23:41:20] [PASSED] DVI-I
[23:41:20] [PASSED] DVI-D
[23:41:20] [PASSED] DVI-A
[23:41:20] [PASSED] Composite
[23:41:20] [PASSED] SVIDEO
[23:41:20] [PASSED] LVDS
[23:41:20] [PASSED] Component
[23:41:20] [PASSED] DIN
[23:41:20] [PASSED] DP
[23:41:20] [PASSED] HDMI-A
[23:41:20] [PASSED] HDMI-B
[23:41:20] [PASSED] TV
[23:41:20] [PASSED] eDP
[23:41:20] [PASSED] Virtual
[23:41:20] [PASSED] DSI
[23:41:20] [PASSED] DPI
[23:41:20] [PASSED] Writeback
[23:41:20] [PASSED] SPI
[23:41:20] [PASSED] USB
[23:41:20] = [PASSED] drm_test_drm_connector_dynamic_init_type_valid ==
[23:41:20] ======== drm_test_drm_connector_dynamic_init_name =========
[23:41:20] [PASSED] Unknown
[23:41:20] [PASSED] VGA
[23:41:20] [PASSED] DVI-I
[23:41:20] [PASSED] DVI-D
[23:41:20] [PASSED] DVI-A
[23:41:20] [PASSED] Composite
[23:41:20] [PASSED] SVIDEO
[23:41:20] [PASSED] LVDS
[23:41:20] [PASSED] Component
[23:41:20] [PASSED] DIN
[23:41:20] [PASSED] DP
[23:41:20] [PASSED] HDMI-A
[23:41:20] [PASSED] HDMI-B
[23:41:20] [PASSED] TV
[23:41:20] [PASSED] eDP
[23:41:20] [PASSED] Virtual
[23:41:20] [PASSED] DSI
[23:41:20] [PASSED] DPI
[23:41:20] [PASSED] Writeback
[23:41:20] [PASSED] SPI
[23:41:20] [PASSED] USB
[23:41:20] ==== [PASSED] drm_test_drm_connector_dynamic_init_name =====
[23:41:20] =========== [PASSED] drm_connector_dynamic_init ============
[23:41:20] ==== drm_connector_dynamic_register_early (4 subtests) =====
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_early_on_list
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_early_defer
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_early_no_init
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_early_no_mode_object
[23:41:20] ====== [PASSED] drm_connector_dynamic_register_early =======
[23:41:20] ======= drm_connector_dynamic_register (7 subtests) ========
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_on_list
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_no_defer
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_no_init
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_mode_object
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_sysfs
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_sysfs_name
[23:41:20] [PASSED] drm_test_drm_connector_dynamic_register_debugfs
[23:41:20] ========= [PASSED] drm_connector_dynamic_register ==========
[23:41:20] = drm_connector_attach_broadcast_rgb_property (2 subtests) =
[23:41:20] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property
[23:41:20] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector
[23:41:20] === [PASSED] drm_connector_attach_broadcast_rgb_property ===
[23:41:20] ========== drm_get_tv_mode_from_name (2 subtests) ==========
[23:41:20] ========== drm_test_get_tv_mode_from_name_valid ===========
[23:41:20] [PASSED] NTSC
[23:41:20] [PASSED] NTSC-443
[23:41:20] [PASSED] NTSC-J
[23:41:20] [PASSED] PAL
[23:41:20] [PASSED] PAL-M
[23:41:20] [PASSED] PAL-N
[23:41:20] [PASSED] SECAM
[23:41:20] [PASSED] Mono
[23:41:20] ====== [PASSED] drm_test_get_tv_mode_from_name_valid =======
[23:41:20] [PASSED] drm_test_get_tv_mode_from_name_truncated
[23:41:20] ============ [PASSED] drm_get_tv_mode_from_name ============
[23:41:20] = drm_test_connector_hdmi_compute_mode_clock (12 subtests) =
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1
[23:41:20] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_double
[23:41:20] = drm_test_connector_hdmi_compute_mode_clock_yuv420_valid =
[23:41:20] [PASSED] VIC 96
[23:41:20] [PASSED] VIC 97
[23:41:20] [PASSED] VIC 101
[23:41:20] [PASSED] VIC 102
[23:41:20] [PASSED] VIC 106
[23:41:20] [PASSED] VIC 107
[23:41:20] === [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_valid ===
[23:41:20] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc
[23:41:20] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc
[23:41:20] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc
[23:41:20] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc
[23:41:20] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc
[23:41:20] === [PASSED] drm_test_connector_hdmi_compute_mode_clock ====
[23:41:20] == drm_hdmi_connector_get_broadcast_rgb_name (2 subtests) ==
[23:41:20] === drm_test_drm_hdmi_connector_get_broadcast_rgb_name ====
[23:41:20] [PASSED] Automatic
[23:41:20] [PASSED] Full
[23:41:20] [PASSED] Limited 16:235
[23:41:20] === [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name ===
[23:41:20] [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid
[23:41:20] ==== [PASSED] drm_hdmi_connector_get_broadcast_rgb_name ====
[23:41:20] == drm_hdmi_connector_get_output_format_name (2 subtests) ==
[23:41:20] === drm_test_drm_hdmi_connector_get_output_format_name ====
[23:41:20] [PASSED] RGB
[23:41:20] [PASSED] YUV 4:2:0
[23:41:20] [PASSED] YUV 4:2:2
[23:41:20] [PASSED] YUV 4:4:4
[23:41:20] === [PASSED] drm_test_drm_hdmi_connector_get_output_format_name ===
[23:41:20] [PASSED] drm_test_drm_hdmi_connector_get_output_format_name_invalid
[23:41:20] ==== [PASSED] drm_hdmi_connector_get_output_format_name ====
[23:41:20] ============= drm_damage_helper (21 subtests) ==============
[23:41:20] [PASSED] drm_test_damage_iter_no_damage
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_fractional_src
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_src_moved
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_fractional_src_moved
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_not_visible
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_no_crtc
[23:41:20] [PASSED] drm_test_damage_iter_no_damage_no_fb
[23:41:20] [PASSED] drm_test_damage_iter_simple_damage
[23:41:20] [PASSED] drm_test_damage_iter_single_damage
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_intersect_src
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_outside_src
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_fractional_src
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_intersect_fractional_src
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_outside_fractional_src
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_src_moved
[23:41:20] [PASSED] drm_test_damage_iter_single_damage_fractional_src_moved
[23:41:20] [PASSED] drm_test_damage_iter_damage
[23:41:20] [PASSED] drm_test_damage_iter_damage_one_intersect
[23:41:20] [PASSED] drm_test_damage_iter_damage_one_outside
[23:41:20] [PASSED] drm_test_damage_iter_damage_src_moved
[23:41:20] [PASSED] drm_test_damage_iter_damage_not_visible
[23:41:20] ================ [PASSED] drm_damage_helper ================
[23:41:20] ============== drm_dp_mst_helper (3 subtests) ==============
[23:41:20] ============== drm_test_dp_mst_calc_pbn_mode ==============
[23:41:20] [PASSED] Clock 154000 BPP 30 DSC disabled
[23:41:20] [PASSED] Clock 234000 BPP 30 DSC disabled
[23:41:20] [PASSED] Clock 297000 BPP 24 DSC disabled
[23:41:20] [PASSED] Clock 332880 BPP 24 DSC enabled
[23:41:20] [PASSED] Clock 324540 BPP 24 DSC enabled
[23:41:20] ========== [PASSED] drm_test_dp_mst_calc_pbn_mode ==========
[23:41:20] ============== drm_test_dp_mst_calc_pbn_div ===============
[23:41:20] [PASSED] Link rate 2000000 lane count 4
[23:41:20] [PASSED] Link rate 2000000 lane count 2
[23:41:20] [PASSED] Link rate 2000000 lane count 1
[23:41:20] [PASSED] Link rate 1350000 lane count 4
[23:41:20] [PASSED] Link rate 1350000 lane count 2
[23:41:20] [PASSED] Link rate 1350000 lane count 1
[23:41:20] [PASSED] Link rate 1000000 lane count 4
[23:41:20] [PASSED] Link rate 1000000 lane count 2
[23:41:20] [PASSED] Link rate 1000000 lane count 1
[23:41:20] [PASSED] Link rate 810000 lane count 4
[23:41:20] [PASSED] Link rate 810000 lane count 2
[23:41:20] [PASSED] Link rate 810000 lane count 1
[23:41:20] [PASSED] Link rate 540000 lane count 4
[23:41:20] [PASSED] Link rate 540000 lane count 2
[23:41:20] [PASSED] Link rate 540000 lane count 1
[23:41:20] [PASSED] Link rate 270000 lane count 4
[23:41:20] [PASSED] Link rate 270000 lane count 2
[23:41:20] [PASSED] Link rate 270000 lane count 1
[23:41:20] [PASSED] Link rate 162000 lane count 4
[23:41:20] [PASSED] Link rate 162000 lane count 2
[23:41:20] [PASSED] Link rate 162000 lane count 1
[23:41:20] ========== [PASSED] drm_test_dp_mst_calc_pbn_div ===========
[23:41:20] ========= drm_test_dp_mst_sideband_msg_req_decode =========
[23:41:20] [PASSED] DP_ENUM_PATH_RESOURCES with port number
[23:41:20] [PASSED] DP_POWER_UP_PHY with port number
[23:41:20] [PASSED] DP_POWER_DOWN_PHY with port number
[23:41:20] [PASSED] DP_ALLOCATE_PAYLOAD with SDP stream sinks
[23:41:20] [PASSED] DP_ALLOCATE_PAYLOAD with port number
[23:41:20] [PASSED] DP_ALLOCATE_PAYLOAD with VCPI
[23:41:20] [PASSED] DP_ALLOCATE_PAYLOAD with PBN
[23:41:20] [PASSED] DP_QUERY_PAYLOAD with port number
[23:41:20] [PASSED] DP_QUERY_PAYLOAD with VCPI
[23:41:20] [PASSED] DP_REMOTE_DPCD_READ with port number
[23:41:20] [PASSED] DP_REMOTE_DPCD_READ with DPCD address
[23:41:20] [PASSED] DP_REMOTE_DPCD_READ with max number of bytes
[23:41:20] [PASSED] DP_REMOTE_DPCD_WRITE with port number
[23:41:20] [PASSED] DP_REMOTE_DPCD_WRITE with DPCD address
[23:41:20] [PASSED] DP_REMOTE_DPCD_WRITE with data array
[23:41:20] [PASSED] DP_REMOTE_I2C_READ with port number
[23:41:20] [PASSED] DP_REMOTE_I2C_READ with I2C device ID
[23:41:20] [PASSED] DP_REMOTE_I2C_READ with transactions array
[23:41:20] [PASSED] DP_REMOTE_I2C_WRITE with port number
[23:41:20] [PASSED] DP_REMOTE_I2C_WRITE with I2C device ID
[23:41:20] [PASSED] DP_REMOTE_I2C_WRITE with data array
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream ID
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with client ID
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream event
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with valid stream event
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream behavior
[23:41:20] [PASSED] DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior
[23:41:20] ===== [PASSED] drm_test_dp_mst_sideband_msg_req_decode =====
[23:41:20] ================ [PASSED] drm_dp_mst_helper ================
[23:41:20] ================== drm_exec (7 subtests) ===================
[23:41:20] [PASSED] sanitycheck
[23:41:20] [PASSED] test_lock
[23:41:20] [PASSED] test_lock_unlock
[23:41:20] [PASSED] test_duplicates
[23:41:20] [PASSED] test_prepare
[23:41:20] [PASSED] test_prepare_array
[23:41:20] [PASSED] test_multiple_loops
[23:41:20] ==================== [PASSED] drm_exec =====================
[23:41:20] =========== drm_format_helper_test (17 subtests) ===========
[23:41:20] ============== drm_test_fb_xrgb8888_to_gray8 ==============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========== [PASSED] drm_test_fb_xrgb8888_to_gray8 ==========
[23:41:20] ============= drm_test_fb_xrgb8888_to_rgb332 ==============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb332 ==========
[23:41:20] ============= drm_test_fb_xrgb8888_to_rgb565 ==============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb565 ==========
[23:41:20] ============ drm_test_fb_xrgb8888_to_xrgb1555 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_xrgb1555 =========
[23:41:20] ============ drm_test_fb_xrgb8888_to_argb1555 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_argb1555 =========
[23:41:20] ============ drm_test_fb_xrgb8888_to_rgba5551 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_rgba5551 =========
[23:41:20] ============= drm_test_fb_xrgb8888_to_rgb888 ==============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb888 ==========
[23:41:20] ============= drm_test_fb_xrgb8888_to_bgr888 ==============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========= [PASSED] drm_test_fb_xrgb8888_to_bgr888 ==========
[23:41:20] ============ drm_test_fb_xrgb8888_to_argb8888 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_argb8888 =========
[23:41:20] =========== drm_test_fb_xrgb8888_to_xrgb2101010 ===========
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======= [PASSED] drm_test_fb_xrgb8888_to_xrgb2101010 =======
[23:41:20] =========== drm_test_fb_xrgb8888_to_argb2101010 ===========
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======= [PASSED] drm_test_fb_xrgb8888_to_argb2101010 =======
[23:41:20] ============== drm_test_fb_xrgb8888_to_mono ===============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ========== [PASSED] drm_test_fb_xrgb8888_to_mono ===========
[23:41:20] ==================== drm_test_fb_swab =====================
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ================ [PASSED] drm_test_fb_swab =================
[23:41:20] ============ drm_test_fb_xrgb8888_to_xbgr8888 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_xbgr8888 =========
[23:41:20] ============ drm_test_fb_xrgb8888_to_abgr8888 =============
[23:41:20] [PASSED] single_pixel_source_buffer
[23:41:20] [PASSED] single_pixel_clip_rectangle
[23:41:20] [PASSED] well_known_colors
[23:41:20] [PASSED] destination_pitch
[23:41:20] ======== [PASSED] drm_test_fb_xrgb8888_to_abgr8888 =========
[23:41:20] ================= drm_test_fb_clip_offset =================
[23:41:20] [PASSED] pass through
[23:41:20] [PASSED] horizontal offset
[23:41:20] [PASSED] vertical offset
[23:41:20] [PASSED] horizontal and vertical offset
[23:41:20] [PASSED] horizontal offset (custom pitch)
[23:41:20] [PASSED] vertical offset (custom pitch)
[23:41:20] [PASSED] horizontal and vertical offset (custom pitch)
[23:41:20] ============= [PASSED] drm_test_fb_clip_offset =============
[23:41:20] =================== drm_test_fb_memcpy ====================
[23:41:20] [PASSED] single_pixel_source_buffer: XR24 little-endian (0x34325258)
[23:41:20] [PASSED] single_pixel_source_buffer: XRA8 little-endian (0x38415258)
[23:41:20] [PASSED] single_pixel_source_buffer: YU24 little-endian (0x34325559)
[23:41:20] [PASSED] single_pixel_clip_rectangle: XB24 little-endian (0x34324258)
[23:41:20] [PASSED] single_pixel_clip_rectangle: XRA8 little-endian (0x38415258)
[23:41:20] [PASSED] single_pixel_clip_rectangle: YU24 little-endian (0x34325559)
[23:41:20] [PASSED] well_known_colors: XB24 little-endian (0x34324258)
[23:41:20] [PASSED] well_known_colors: XRA8 little-endian (0x38415258)
[23:41:20] [PASSED] well_known_colors: YU24 little-endian (0x34325559)
[23:41:20] [PASSED] destination_pitch: XB24 little-endian (0x34324258)
[23:41:20] [PASSED] destination_pitch: XRA8 little-endian (0x38415258)
[23:41:20] [PASSED] destination_pitch: YU24 little-endian (0x34325559)
[23:41:20] =============== [PASSED] drm_test_fb_memcpy ================
[23:41:20] ============= [PASSED] drm_format_helper_test ==============
[23:41:20] ================= drm_format (18 subtests) =================
[23:41:20] [PASSED] drm_test_format_block_width_invalid
[23:41:20] [PASSED] drm_test_format_block_width_one_plane
[23:41:20] [PASSED] drm_test_format_block_width_two_plane
[23:41:20] [PASSED] drm_test_format_block_width_three_plane
[23:41:20] [PASSED] drm_test_format_block_width_tiled
[23:41:20] [PASSED] drm_test_format_block_height_invalid
[23:41:20] [PASSED] drm_test_format_block_height_one_plane
[23:41:20] [PASSED] drm_test_format_block_height_two_plane
[23:41:20] [PASSED] drm_test_format_block_height_three_plane
[23:41:20] [PASSED] drm_test_format_block_height_tiled
[23:41:20] [PASSED] drm_test_format_min_pitch_invalid
[23:41:20] [PASSED] drm_test_format_min_pitch_one_plane_8bpp
[23:41:20] [PASSED] drm_test_format_min_pitch_one_plane_16bpp
[23:41:20] [PASSED] drm_test_format_min_pitch_one_plane_24bpp
[23:41:20] [PASSED] drm_test_format_min_pitch_one_plane_32bpp
[23:41:20] [PASSED] drm_test_format_min_pitch_two_plane
[23:41:20] [PASSED] drm_test_format_min_pitch_three_plane_8bpp
[23:41:20] [PASSED] drm_test_format_min_pitch_tiled
[23:41:20] =================== [PASSED] drm_format ====================
[23:41:20] ============== drm_framebuffer (10 subtests) ===============
[23:41:20] ========== drm_test_framebuffer_check_src_coords ==========
[23:41:20] [PASSED] Success: source fits into fb
[23:41:20] [PASSED] Fail: overflowing fb with x-axis coordinate
[23:41:20] [PASSED] Fail: overflowing fb with y-axis coordinate
[23:41:20] [PASSED] Fail: overflowing fb with source width
[23:41:20] [PASSED] Fail: overflowing fb with source height
[23:41:20] ====== [PASSED] drm_test_framebuffer_check_src_coords ======
[23:41:20] [PASSED] drm_test_framebuffer_cleanup
[23:41:20] =============== drm_test_framebuffer_create ===============
[23:41:20] [PASSED] ABGR8888 normal sizes
[23:41:20] [PASSED] ABGR8888 max sizes
[23:41:20] [PASSED] ABGR8888 pitch greater than min required
[23:41:20] [PASSED] ABGR8888 pitch less than min required
[23:41:20] [PASSED] ABGR8888 Invalid width
[23:41:20] [PASSED] ABGR8888 Invalid buffer handle
[23:41:20] [PASSED] No pixel format
[23:41:20] [PASSED] ABGR8888 Width 0
[23:41:20] [PASSED] ABGR8888 Height 0
[23:41:20] [PASSED] ABGR8888 Out of bound height * pitch combination
[23:41:20] [PASSED] ABGR8888 Large buffer offset
[23:41:20] [PASSED] ABGR8888 Buffer offset for inexistent plane
[23:41:20] [PASSED] ABGR8888 Invalid flag
[23:41:20] [PASSED] ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers
[23:41:20] [PASSED] ABGR8888 Valid buffer modifier
[23:41:20] [PASSED] ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
[23:41:20] [PASSED] ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] NV12 Normal sizes
[23:41:20] [PASSED] NV12 Max sizes
[23:41:20] [PASSED] NV12 Invalid pitch
[23:41:20] [PASSED] NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag
[23:41:20] [PASSED] NV12 different modifier per-plane
[23:41:20] [PASSED] NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
[23:41:20] [PASSED] NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] NV12 Modifier for inexistent plane
[23:41:20] [PASSED] NV12 Handle for inexistent plane
[23:41:20] [PASSED] NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] YVU420 DRM_MODE_FB_MODIFIERS set without modifier
[23:41:20] [PASSED] YVU420 Normal sizes
[23:41:20] [PASSED] YVU420 Max sizes
[23:41:20] [PASSED] YVU420 Invalid pitch
[23:41:20] [PASSED] YVU420 Different pitches
[23:41:20] [PASSED] YVU420 Different buffer offsets/pitches
[23:41:20] [PASSED] YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS
[23:41:20] [PASSED] YVU420 Valid modifier
[23:41:20] [PASSED] YVU420 Different modifiers per plane
[23:41:20] [PASSED] YVU420 Modifier for inexistent plane
[23:41:20] [PASSED] YUV420_10BIT Invalid modifier(DRM_FORMAT_MOD_LINEAR)
[23:41:20] [PASSED] X0L2 Normal sizes
[23:41:20] [PASSED] X0L2 Max sizes
[23:41:20] [PASSED] X0L2 Invalid pitch
[23:41:20] [PASSED] X0L2 Pitch greater than minimum required
[23:41:20] [PASSED] X0L2 Handle for inexistent plane
[23:41:20] [PASSED] X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set
[23:41:20] [PASSED] X0L2 Modifier without DRM_MODE_FB_MODIFIERS set
[23:41:20] [PASSED] X0L2 Valid modifier
[23:41:20] [PASSED] X0L2 Modifier for inexistent plane
[23:41:20] =========== [PASSED] drm_test_framebuffer_create ===========
[23:41:20] [PASSED] drm_test_framebuffer_free
[23:41:20] [PASSED] drm_test_framebuffer_init
[23:41:20] [PASSED] drm_test_framebuffer_init_bad_format
[23:41:20] [PASSED] drm_test_framebuffer_init_dev_mismatch
[23:41:20] [PASSED] drm_test_framebuffer_lookup
[23:41:20] [PASSED] drm_test_framebuffer_lookup_inexistent
[23:41:20] [PASSED] drm_test_framebuffer_modifiers_not_supported
[23:41:20] ================= [PASSED] drm_framebuffer =================
[23:41:20] ================ drm_gem_shmem (8 subtests) ================
[23:41:20] [PASSED] drm_gem_shmem_test_obj_create
[23:41:20] [PASSED] drm_gem_shmem_test_obj_create_private
[23:41:20] [PASSED] drm_gem_shmem_test_pin_pages
[23:41:20] [PASSED] drm_gem_shmem_test_vmap
[23:41:20] [PASSED] drm_gem_shmem_test_get_sg_table
[23:41:20] [PASSED] drm_gem_shmem_test_get_pages_sgt
[23:41:20] [PASSED] drm_gem_shmem_test_madvise
[23:41:20] [PASSED] drm_gem_shmem_test_purge
[23:41:20] ================== [PASSED] drm_gem_shmem ==================
[23:41:20] === drm_atomic_helper_connector_hdmi_check (27 subtests) ===
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode_vic_1
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode_vic_1
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode_vic_1
[23:41:20] ====== drm_test_check_broadcast_rgb_cea_mode_yuv420 =======
[23:41:20] [PASSED] Automatic
[23:41:20] [PASSED] Full
[23:41:20] [PASSED] Limited 16:235
[23:41:20] == [PASSED] drm_test_check_broadcast_rgb_cea_mode_yuv420 ===
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_changed
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_not_changed
[23:41:20] [PASSED] drm_test_check_disable_connector
[23:41:20] [PASSED] drm_test_check_hdmi_funcs_reject_rate
[23:41:20] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_rgb
[23:41:20] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_yuv420
[23:41:20] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422
[23:41:20] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420
[23:41:20] [PASSED] drm_test_check_driver_unsupported_fallback_yuv420
[23:41:20] [PASSED] drm_test_check_output_bpc_crtc_mode_changed
[23:41:20] [PASSED] drm_test_check_output_bpc_crtc_mode_not_changed
[23:41:20] [PASSED] drm_test_check_output_bpc_dvi
[23:41:20] [PASSED] drm_test_check_output_bpc_format_vic_1
[23:41:20] [PASSED] drm_test_check_output_bpc_format_display_8bpc_only
[23:41:20] [PASSED] drm_test_check_output_bpc_format_display_rgb_only
[23:41:20] [PASSED] drm_test_check_output_bpc_format_driver_8bpc_only
[23:41:20] [PASSED] drm_test_check_output_bpc_format_driver_rgb_only
[23:41:20] [PASSED] drm_test_check_tmds_char_rate_rgb_8bpc
[23:41:20] [PASSED] drm_test_check_tmds_char_rate_rgb_10bpc
[23:41:20] [PASSED] drm_test_check_tmds_char_rate_rgb_12bpc
[23:41:20] ===== [PASSED] drm_atomic_helper_connector_hdmi_check ======
[23:41:20] === drm_atomic_helper_connector_hdmi_reset (6 subtests) ====
[23:41:20] [PASSED] drm_test_check_broadcast_rgb_value
[23:41:20] [PASSED] drm_test_check_bpc_8_value
[23:41:20] [PASSED] drm_test_check_bpc_10_value
[23:41:20] [PASSED] drm_test_check_bpc_12_value
[23:41:20] [PASSED] drm_test_check_format_value
[23:41:20] [PASSED] drm_test_check_tmds_char_value
[23:41:20] ===== [PASSED] drm_atomic_helper_connector_hdmi_reset ======
[23:41:20] = drm_atomic_helper_connector_hdmi_mode_valid (4 subtests) =
[23:41:20] [PASSED] drm_test_check_mode_valid
[23:41:20] [PASSED] drm_test_check_mode_valid_reject
[23:41:20] [PASSED] drm_test_check_mode_valid_reject_rate
[23:41:20] [PASSED] drm_test_check_mode_valid_reject_max_clock
[23:41:20] === [PASSED] drm_atomic_helper_connector_hdmi_mode_valid ===
[23:41:20] ================= drm_managed (2 subtests) =================
[23:41:20] [PASSED] drm_test_managed_release_action
[23:41:20] [PASSED] drm_test_managed_run_action
[23:41:20] =================== [PASSED] drm_managed ===================
[23:41:20] =================== drm_mm (6 subtests) ====================
[23:41:20] [PASSED] drm_test_mm_init
[23:41:20] [PASSED] drm_test_mm_debug
[23:41:20] [PASSED] drm_test_mm_align32
[23:41:20] [PASSED] drm_test_mm_align64
[23:41:20] [PASSED] drm_test_mm_lowest
[23:41:20] [PASSED] drm_test_mm_highest
[23:41:20] ===================== [PASSED] drm_mm ======================
[23:41:20] ============= drm_modes_analog_tv (5 subtests) =============
[23:41:20] [PASSED] drm_test_modes_analog_tv_mono_576i
[23:41:20] [PASSED] drm_test_modes_analog_tv_ntsc_480i
[23:41:20] [PASSED] drm_test_modes_analog_tv_ntsc_480i_inlined
[23:41:20] [PASSED] drm_test_modes_analog_tv_pal_576i
[23:41:20] [PASSED] drm_test_modes_analog_tv_pal_576i_inlined
[23:41:20] =============== [PASSED] drm_modes_analog_tv ===============
[23:41:20] ============== drm_plane_helper (2 subtests) ===============
[23:41:20] =============== drm_test_check_plane_state ================
[23:41:20] [PASSED] clipping_simple
[23:41:20] [PASSED] clipping_rotate_reflect
[23:41:20] [PASSED] positioning_simple
[23:41:20] [PASSED] upscaling
[23:41:20] [PASSED] downscaling
[23:41:20] [PASSED] rounding1
[23:41:20] [PASSED] rounding2
[23:41:20] [PASSED] rounding3
[23:41:20] [PASSED] rounding4
[23:41:20] =========== [PASSED] drm_test_check_plane_state ============
[23:41:20] =========== drm_test_check_invalid_plane_state ============
[23:41:20] [PASSED] positioning_invalid
[23:41:20] [PASSED] upscaling_invalid
[23:41:20] [PASSED] downscaling_invalid
[23:41:20] ======= [PASSED] drm_test_check_invalid_plane_state ========
[23:41:20] ================ [PASSED] drm_plane_helper =================
[23:41:20] ====== drm_connector_helper_tv_get_modes (1 subtest) =======
[23:41:20] ====== drm_test_connector_helper_tv_get_modes_check =======
[23:41:20] [PASSED] None
[23:41:20] [PASSED] PAL
[23:41:20] [PASSED] NTSC
[23:41:20] [PASSED] Both, NTSC Default
[23:41:20] [PASSED] Both, PAL Default
[23:41:20] [PASSED] Both, NTSC Default, with PAL on command-line
[23:41:20] [PASSED] Both, PAL Default, with NTSC on command-line
[23:41:20] == [PASSED] drm_test_connector_helper_tv_get_modes_check ===
[23:41:20] ======== [PASSED] drm_connector_helper_tv_get_modes ========
[23:41:20] ================== drm_rect (9 subtests) ===================
[23:41:20] [PASSED] drm_test_rect_clip_scaled_div_by_zero
[23:41:20] [PASSED] drm_test_rect_clip_scaled_not_clipped
[23:41:20] [PASSED] drm_test_rect_clip_scaled_clipped
[23:41:20] [PASSED] drm_test_rect_clip_scaled_signed_vs_unsigned
[23:41:20] ================= drm_test_rect_intersect =================
[23:41:20] [PASSED] top-left x bottom-right: 2x2+1+1 x 2x2+0+0
[23:41:20] [PASSED] top-right x bottom-left: 2x2+0+0 x 2x2+1-1
[23:41:20] [PASSED] bottom-left x top-right: 2x2+1-1 x 2x2+0+0
[23:41:20] [PASSED] bottom-right x top-left: 2x2+0+0 x 2x2+1+1
[23:41:20] [PASSED] right x left: 2x1+0+0 x 3x1+1+0
[23:41:20] [PASSED] left x right: 3x1+1+0 x 2x1+0+0
[23:41:20] [PASSED] up x bottom: 1x2+0+0 x 1x3+0-1
[23:41:20] [PASSED] bottom x up: 1x3+0-1 x 1x2+0+0
[23:41:20] [PASSED] touching corner: 1x1+0+0 x 2x2+1+1
[23:41:20] [PASSED] touching side: 1x1+0+0 x 1x1+1+0
[23:41:20] [PASSED] equal rects: 2x2+0+0 x 2x2+0+0
[23:41:20] [PASSED] inside another: 2x2+0+0 x 1x1+1+1
[23:41:20] [PASSED] far away: 1x1+0+0 x 1x1+3+6
[23:41:20] [PASSED] points intersecting: 0x0+5+10 x 0x0+5+10
[23:41:20] [PASSED] points not intersecting: 0x0+0+0 x 0x0+5+10
[23:41:20] ============= [PASSED] drm_test_rect_intersect =============
[23:41:20] ================ drm_test_rect_calc_hscale ================
[23:41:20] [PASSED] normal use
[23:41:20] [PASSED] out of max range
[23:41:20] [PASSED] out of min range
[23:41:20] [PASSED] zero dst
[23:41:20] [PASSED] negative src
[23:41:20] [PASSED] negative dst
[23:41:20] ============ [PASSED] drm_test_rect_calc_hscale ============
[23:41:20] ================ drm_test_rect_calc_vscale ================
[23:41:20] [PASSED] normal use
stty: 'standard input': Inappropriate ioctl for device
[23:41:20] [PASSED] out of max range
[23:41:20] [PASSED] out of min range
[23:41:20] [PASSED] zero dst
[23:41:20] [PASSED] negative src
[23:41:20] [PASSED] negative dst
[23:41:20] ============ [PASSED] drm_test_rect_calc_vscale ============
[23:41:20] ================== drm_test_rect_rotate ===================
[23:41:20] [PASSED] reflect-x
[23:41:20] [PASSED] reflect-y
[23:41:20] [PASSED] rotate-0
[23:41:20] [PASSED] rotate-90
[23:41:20] [PASSED] rotate-180
[23:41:20] [PASSED] rotate-270
[23:41:20] ============== [PASSED] drm_test_rect_rotate ===============
[23:41:20] ================ drm_test_rect_rotate_inv =================
[23:41:20] [PASSED] reflect-x
[23:41:20] [PASSED] reflect-y
[23:41:20] [PASSED] rotate-0
[23:41:20] [PASSED] rotate-90
[23:41:20] [PASSED] rotate-180
[23:41:20] [PASSED] rotate-270
[23:41:20] ============ [PASSED] drm_test_rect_rotate_inv =============
[23:41:20] ==================== [PASSED] drm_rect =====================
[23:41:20] ============ drm_sysfb_modeset_test (1 subtest) ============
[23:41:20] ============ drm_test_sysfb_build_fourcc_list =============
[23:41:20] [PASSED] no native formats
[23:41:20] [PASSED] XRGB8888 as native format
[23:41:20] [PASSED] remove duplicates
[23:41:20] [PASSED] convert alpha formats
[23:41:20] [PASSED] random formats
[23:41:20] ======== [PASSED] drm_test_sysfb_build_fourcc_list =========
[23:41:20] ============= [PASSED] drm_sysfb_modeset_test ==============
[23:41:20] ================== drm_fixp (2 subtests) ===================
[23:41:20] [PASSED] drm_test_int2fixp
[23:41:20] [PASSED] drm_test_sm2fixp
[23:41:20] ==================== [PASSED] drm_fixp =====================
[23:41:20] ============================================================
[23:41:20] Testing complete. Ran 624 tests: passed: 624
[23:41:20] Elapsed time: 27.467s total, 1.684s configuring, 25.363s building, 0.374s running
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/ttm/tests/.kunitconfig
[23:41:21] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[23:41:22] 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
[23:41:31] Starting KUnit Kernel (1/1)...
[23:41:31] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[23:41:32] ================= ttm_device (5 subtests) ==================
[23:41:32] [PASSED] ttm_device_init_basic
[23:41:32] [PASSED] ttm_device_init_multiple
[23:41:32] [PASSED] ttm_device_fini_basic
[23:41:32] [PASSED] ttm_device_init_no_vma_man
[23:41:32] ================== ttm_device_init_pools ==================
[23:41:32] [PASSED] No DMA allocations, no DMA32 required
[23:41:32] [PASSED] DMA allocations, DMA32 required
[23:41:32] [PASSED] No DMA allocations, DMA32 required
[23:41:32] [PASSED] DMA allocations, no DMA32 required
[23:41:32] ============== [PASSED] ttm_device_init_pools ==============
[23:41:32] =================== [PASSED] ttm_device ====================
[23:41:32] ================== ttm_pool (8 subtests) ===================
[23:41:32] ================== ttm_pool_alloc_basic ===================
[23:41:32] [PASSED] One page
[23:41:32] [PASSED] More than one page
[23:41:32] [PASSED] Above the allocation limit
[23:41:32] [PASSED] One page, with coherent DMA mappings enabled
[23:41:32] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[23:41:32] ============== [PASSED] ttm_pool_alloc_basic ===============
[23:41:32] ============== ttm_pool_alloc_basic_dma_addr ==============
[23:41:32] [PASSED] One page
[23:41:32] [PASSED] More than one page
[23:41:32] [PASSED] Above the allocation limit
[23:41:32] [PASSED] One page, with coherent DMA mappings enabled
[23:41:32] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[23:41:32] ========== [PASSED] ttm_pool_alloc_basic_dma_addr ==========
[23:41:32] [PASSED] ttm_pool_alloc_order_caching_match
[23:41:32] [PASSED] ttm_pool_alloc_caching_mismatch
[23:41:32] [PASSED] ttm_pool_alloc_order_mismatch
[23:41:32] [PASSED] ttm_pool_free_dma_alloc
[23:41:32] [PASSED] ttm_pool_free_no_dma_alloc
[23:41:32] [PASSED] ttm_pool_fini_basic
[23:41:32] ==================== [PASSED] ttm_pool =====================
[23:41:32] ================ ttm_resource (8 subtests) =================
[23:41:32] ================= ttm_resource_init_basic =================
[23:41:32] [PASSED] Init resource in TTM_PL_SYSTEM
[23:41:32] [PASSED] Init resource in TTM_PL_VRAM
[23:41:32] [PASSED] Init resource in a private placement
[23:41:32] [PASSED] Init resource in TTM_PL_SYSTEM, set placement flags
[23:41:32] ============= [PASSED] ttm_resource_init_basic =============
[23:41:32] [PASSED] ttm_resource_init_pinned
[23:41:32] [PASSED] ttm_resource_fini_basic
[23:41:32] [PASSED] ttm_resource_manager_init_basic
[23:41:32] [PASSED] ttm_resource_manager_usage_basic
[23:41:32] [PASSED] ttm_resource_manager_set_used_basic
[23:41:32] [PASSED] ttm_sys_man_alloc_basic
[23:41:32] [PASSED] ttm_sys_man_free_basic
[23:41:32] ================== [PASSED] ttm_resource ===================
[23:41:32] =================== ttm_tt (15 subtests) ===================
[23:41:32] ==================== ttm_tt_init_basic ====================
[23:41:32] [PASSED] Page-aligned size
[23:41:32] [PASSED] Extra pages requested
[23:41:32] ================ [PASSED] ttm_tt_init_basic ================
[23:41:32] [PASSED] ttm_tt_init_misaligned
[23:41:32] [PASSED] ttm_tt_fini_basic
[23:41:32] [PASSED] ttm_tt_fini_sg
[23:41:32] [PASSED] ttm_tt_fini_shmem
[23:41:32] [PASSED] ttm_tt_create_basic
[23:41:32] [PASSED] ttm_tt_create_invalid_bo_type
[23:41:32] [PASSED] ttm_tt_create_ttm_exists
[23:41:32] [PASSED] ttm_tt_create_failed
[23:41:32] [PASSED] ttm_tt_destroy_basic
[23:41:32] [PASSED] ttm_tt_populate_null_ttm
[23:41:32] [PASSED] ttm_tt_populate_populated_ttm
[23:41:32] [PASSED] ttm_tt_unpopulate_basic
[23:41:32] [PASSED] ttm_tt_unpopulate_empty_ttm
[23:41:32] [PASSED] ttm_tt_swapin_basic
[23:41:32] ===================== [PASSED] ttm_tt ======================
[23:41:32] =================== ttm_bo (14 subtests) ===================
[23:41:32] =========== ttm_bo_reserve_optimistic_no_ticket ===========
[23:41:32] [PASSED] Cannot be interrupted and sleeps
[23:41:32] [PASSED] Cannot be interrupted, locks straight away
[23:41:32] [PASSED] Can be interrupted, sleeps
[23:41:32] ======= [PASSED] ttm_bo_reserve_optimistic_no_ticket =======
[23:41:32] [PASSED] ttm_bo_reserve_locked_no_sleep
[23:41:32] [PASSED] ttm_bo_reserve_no_wait_ticket
[23:41:32] [PASSED] ttm_bo_reserve_double_resv
[23:41:32] [PASSED] ttm_bo_reserve_interrupted
[23:41:32] [PASSED] ttm_bo_reserve_deadlock
[23:41:32] [PASSED] ttm_bo_unreserve_basic
[23:41:32] [PASSED] ttm_bo_unreserve_pinned
[23:41:32] [PASSED] ttm_bo_unreserve_bulk
[23:41:32] [PASSED] ttm_bo_fini_basic
[23:41:32] [PASSED] ttm_bo_fini_shared_resv
[23:41:32] [PASSED] ttm_bo_pin_basic
[23:41:32] [PASSED] ttm_bo_pin_unpin_resource
[23:41:32] [PASSED] ttm_bo_multiple_pin_one_unpin
[23:41:32] ===================== [PASSED] ttm_bo ======================
[23:41:32] ============== ttm_bo_validate (21 subtests) ===============
[23:41:32] ============== ttm_bo_init_reserved_sys_man ===============
[23:41:32] [PASSED] Buffer object for userspace
[23:41:32] [PASSED] Kernel buffer object
[23:41:32] [PASSED] Shared buffer object
[23:41:32] ========== [PASSED] ttm_bo_init_reserved_sys_man ===========
[23:41:32] ============== ttm_bo_init_reserved_mock_man ==============
[23:41:32] [PASSED] Buffer object for userspace
[23:41:32] [PASSED] Kernel buffer object
[23:41:32] [PASSED] Shared buffer object
[23:41:32] ========== [PASSED] ttm_bo_init_reserved_mock_man ==========
[23:41:32] [PASSED] ttm_bo_init_reserved_resv
[23:41:32] ================== ttm_bo_validate_basic ==================
[23:41:32] [PASSED] Buffer object for userspace
[23:41:32] [PASSED] Kernel buffer object
[23:41:32] [PASSED] Shared buffer object
[23:41:32] ============== [PASSED] ttm_bo_validate_basic ==============
[23:41:32] [PASSED] ttm_bo_validate_invalid_placement
[23:41:32] ============= ttm_bo_validate_same_placement ==============
[23:41:32] [PASSED] System manager
[23:41:32] [PASSED] VRAM manager
[23:41:32] ========= [PASSED] ttm_bo_validate_same_placement ==========
[23:41:32] [PASSED] ttm_bo_validate_failed_alloc
[23:41:32] [PASSED] ttm_bo_validate_pinned
[23:41:32] [PASSED] ttm_bo_validate_busy_placement
[23:41:32] ================ ttm_bo_validate_multihop =================
[23:41:32] [PASSED] Buffer object for userspace
[23:41:32] [PASSED] Kernel buffer object
[23:41:32] [PASSED] Shared buffer object
[23:41:32] ============ [PASSED] ttm_bo_validate_multihop =============
[23:41:32] ========== ttm_bo_validate_no_placement_signaled ==========
[23:41:32] [PASSED] Buffer object in system domain, no page vector
[23:41:32] [PASSED] Buffer object in system domain with an existing page vector
[23:41:32] ====== [PASSED] ttm_bo_validate_no_placement_signaled ======
[23:41:32] ======== ttm_bo_validate_no_placement_not_signaled ========
[23:41:32] [PASSED] Buffer object for userspace
[23:41:32] [PASSED] Kernel buffer object
[23:41:32] [PASSED] Shared buffer object
[23:41:32] ==== [PASSED] ttm_bo_validate_no_placement_not_signaled ====
[23:41:32] [PASSED] ttm_bo_validate_move_fence_signaled
[23:41:32] ========= ttm_bo_validate_move_fence_not_signaled =========
[23:41:32] [PASSED] Waits for GPU
[23:41:32] [PASSED] Tries to lock straight away
[23:41:32] ===== [PASSED] ttm_bo_validate_move_fence_not_signaled =====
[23:41:32] [PASSED] ttm_bo_validate_happy_evict
[23:41:32] [PASSED] ttm_bo_validate_all_pinned_evict
[23:41:32] [PASSED] ttm_bo_validate_allowed_only_evict
[23:41:32] [PASSED] ttm_bo_validate_deleted_evict
[23:41:32] [PASSED] ttm_bo_validate_busy_domain_evict
[23:41:32] [PASSED] ttm_bo_validate_evict_gutting
[23:41:32] [PASSED] ttm_bo_validate_recrusive_evict
stty: 'standard input': Inappropriate ioctl for device
[23:41:32] ================= [PASSED] ttm_bo_validate =================
[23:41:32] ============================================================
[23:41:32] Testing complete. Ran 101 tests: passed: 101
[23:41:32] Elapsed time: 11.198s total, 1.568s configuring, 9.414s building, 0.182s running
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 14+ messages in thread
* ✗ Xe.CI.Full: failure for Page-reclaim fixes and PRL stats addition (rev2)
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
` (4 preceding siblings ...)
2026-01-05 23:41 ` ✓ CI.KUnit: success for Page-reclaim fixes and PRL stats addition (rev2) Patchwork
@ 2026-01-06 1:12 ` Patchwork
5 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2026-01-06 1:12 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 379 bytes --]
== Series Details ==
Series: Page-reclaim fixes and PRL stats addition (rev2)
URL : https://patchwork.freedesktop.org/series/159478/
State : failure
== Summary ==
ERROR: The runconfig 'xe-4331-908651b5352ab4610d22645ef30427d2d36a954c_FULL' does not exist in the database
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-159478v2/index.html
[-- Attachment #2: Type: text/html, Size: 944 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/4] drm/xe: Remove debug comment in page reclaim
2026-01-05 23:33 ` [PATCH 1/4] drm/xe: Remove debug comment in page reclaim Brian Nguyen
@ 2026-01-06 2:15 ` Matthew Brost
0 siblings, 0 replies; 14+ messages in thread
From: Matthew Brost @ 2026-01-06 2:15 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
On Tue, Jan 06, 2026 at 07:33:53AM +0800, Brian Nguyen wrote:
> Drop debug comment erronenously added in patch commit.
>
> Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_page_reclaim.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
> index fd8c33761127..94d4608ebd74 100644
> --- a/drivers/gpu/drm/xe/xe_page_reclaim.c
> +++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
> @@ -108,7 +108,6 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
> */
> void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl)
> {
> - // xe_page_reclaim_list_invalidate(prl);
> prl->entries = NULL;
> prl->num_entries = 0;
> }
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/4] drm/xe: Add explicit abort page reclaim list
2026-01-05 23:33 ` [PATCH 2/4] drm/xe: Add explicit abort page reclaim list Brian Nguyen
@ 2026-01-06 2:23 ` Matthew Brost
2026-01-06 12:44 ` Nguyen, Brian3
0 siblings, 1 reply; 14+ messages in thread
From: Matthew Brost @ 2026-01-06 2:23 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
On Tue, Jan 06, 2026 at 07:33:54AM +0800, Brian Nguyen wrote:
> PRLs could be invalidated to indicate its getting dropped from current
> scope but are still valid. So standardize calls and add abort to clearly
> define when an invalidation is a real abort and PRL should fallback.
>
> Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
> ---
> drivers/gpu/drm/xe/xe_page_reclaim.c | 23 +++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_page_reclaim.h | 3 +++
> drivers/gpu/drm/xe/xe_pt.c | 21 +++++++++------------
> drivers/gpu/drm/xe/xe_tlb_inval_job.c | 2 +-
> 4 files changed, 36 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
> index 94d4608ebd74..9f086067a4a1 100644
> --- a/drivers/gpu/drm/xe/xe_page_reclaim.c
> +++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
> @@ -100,6 +100,29 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
> prl->num_entries = XE_PAGE_RECLAIM_INVALID_LIST;
> }
>
> +/**
> + * xe_page_reclaim_list_abort() - Abort a PRL, invalidate it, and log
> + * @gt: GT associated with this PRL
> + * @prl: Page reclaim list to invalidate
> + * @format: printf-style format string for vm_dbg
@fmt
> + *
> + * This is intended for PRL abort paths where we want to track aborted PRLs
> + */
> +void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *prl,
> + const char *fmt, ...)
> +{
> + struct va_format vaf;
> + va_list va_args;
> +
> + xe_page_reclaim_list_invalidate(prl);
> +
> + va_start(va_args, fmt);
If vm_dbg calls va_start (it does in __drm_dev_dbg) this won't work as
calling va_start start twice is undefined behavior. IIRC, this works on
some compilers but not others so as soon as kernel test robot tries a
certain build we will get bug reports. The W/A here is make make
xe_page_reclaim_list_abort a macro.
> + vaf.fmt = fmt;
> + vaf.va = &va_args;
> + vm_dbg(>_to_xe(gt)->drm, "PRL aborted: %pV", &vaf);
> + va_end(va_args);
> +}
> +
> /**
> * xe_page_reclaim_list_init() - Initialize a page reclaim list
> * @prl: Page reclaim list to initialize
> diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.h b/drivers/gpu/drm/xe/xe_page_reclaim.h
> index a4f58e0ce9b4..2464268dba69 100644
> --- a/drivers/gpu/drm/xe/xe_page_reclaim.h
> +++ b/drivers/gpu/drm/xe/xe_page_reclaim.h
> @@ -19,6 +19,7 @@
> struct xe_tlb_inval;
> struct xe_tlb_inval_fence;
> struct xe_tile;
> +struct xe_gt;
> struct xe_vma;
>
> struct xe_guc_page_reclaim_entry {
> @@ -75,6 +76,8 @@ struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inva
> struct xe_page_reclaim_list *prl,
> struct xe_tlb_inval_fence *fence);
> void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl);
> +void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *prl,
> + const char *format, ...);
So I think here, make xe_page_reclaim_list_abort a macro in this header
file.
> void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl);
> int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list *prl);
> /**
> diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> index 6cd78bb2b652..2752a5a48a97 100644
> --- a/drivers/gpu/drm/xe/xe_pt.c
> +++ b/drivers/gpu/drm/xe/xe_pt.c
> @@ -1618,10 +1618,9 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> } else if (is_2m_pte(xe_child)) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
> } else {
> - xe_page_reclaim_list_invalidate(prl);
> - vm_dbg(&tile_to_xe(tile)->drm,
> - "PRL invalidate: unsupported PTE level=%u pte=%#llx\n",
> - xe_child->level, pte);
> + xe_page_reclaim_list_abort(tile->primary_gt, prl,
> + "unsupported PTE level=%u pte=%#llx",
> + xe_child->level, pte);
> return -EINVAL;
> }
>
> @@ -1670,10 +1669,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> break;
> } else {
> /* overflow, mark as invalid */
> - xe_page_reclaim_list_invalidate(xe_walk->prl);
> - vm_dbg(&xe->drm,
> - "PRL invalidate: overflow while adding pte=%#llx",
> - pte);
> + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> + "overflow while adding pte=%#llx",
> + pte);
> break;
> }
> }
> @@ -1682,10 +1680,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
> if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
> xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
> - xe_page_reclaim_list_invalidate(xe_walk->prl);
> - vm_dbg(&xe->drm,
> - "PRL invalidate: kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> - level, addr, next, xe_child->num_live);
> + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> + "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> + level, addr, next, xe_child->num_live);
> }
>
> return 0;
> diff --git a/drivers/gpu/drm/xe/xe_tlb_inval_job.c b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> index 6a7bd6315797..b8916552101c 100644
> --- a/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> +++ b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> @@ -182,7 +182,7 @@ static void xe_tlb_inval_job_destroy(struct kref *ref)
> struct xe_vm *vm = job->vm;
>
> /* BO creation retains a copy (if used), so no longer needed */
> - xe_page_reclaim_entries_put(job->prl.entries);
> + xe_page_reclaim_list_invalidate(&job->prl);
This doesn't look right or at minimum is unrelated to this patch.
Matt
>
> if (!job->fence_armed)
> kfree(ifence);
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 2/4] drm/xe: Add explicit abort page reclaim list
2026-01-06 2:23 ` Matthew Brost
@ 2026-01-06 12:44 ` Nguyen, Brian3
0 siblings, 0 replies; 14+ messages in thread
From: Nguyen, Brian3 @ 2026-01-06 12:44 UTC (permalink / raw)
To: Brost, Matthew; +Cc: intel-xe@lists.freedesktop.org
On Monday, January 5, 2026 6:24 PM, Matthew Brost wrote:
> On Tue, Jan 06, 2026 at 07:33:54AM +0800, Brian Nguyen wrote:
> > PRLs could be invalidated to indicate its getting dropped from current
> > scope but are still valid. So standardize calls and add abort to
> > clearly define when an invalidation is a real abort and PRL should fallback.
> >
> > Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_page_reclaim.c | 23 +++++++++++++++++++++++
> > drivers/gpu/drm/xe/xe_page_reclaim.h | 3 +++
> > drivers/gpu/drm/xe/xe_pt.c | 21 +++++++++------------
> > drivers/gpu/drm/xe/xe_tlb_inval_job.c | 2 +-
> > 4 files changed, 36 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c
> > b/drivers/gpu/drm/xe/xe_page_reclaim.c
> > index 94d4608ebd74..9f086067a4a1 100644
> > --- a/drivers/gpu/drm/xe/xe_page_reclaim.c
> > +++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
> > @@ -100,6 +100,29 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
> > prl->num_entries = XE_PAGE_RECLAIM_INVALID_LIST; }
> >
> > +/**
> > + * xe_page_reclaim_list_abort() - Abort a PRL, invalidate it, and log
> > + * @gt: GT associated with this PRL
> > + * @prl: Page reclaim list to invalidate
> > + * @format: printf-style format string for vm_dbg
>
> @fmt
>
Got it.
> > + *
> > + * This is intended for PRL abort paths where we want to track
> > +aborted PRLs */ void xe_page_reclaim_list_abort(struct xe_gt *gt,
> > +struct xe_page_reclaim_list *prl,
> > + const char *fmt, ...)
> > +{
> > + struct va_format vaf;
> > + va_list va_args;
> > +
> > + xe_page_reclaim_list_invalidate(prl);
> > +
> > + va_start(va_args, fmt);
>
> If vm_dbg calls va_start (it does in __drm_dev_dbg) this won't work as calling va_start start twice is undefined behavior. IIRC, this
> works on some compilers but not others so as soon as kernel test robot tries a certain build we will get bug reports. The W/A here is
> make make xe_page_reclaim_list_abort a macro.
>
Interesting... got it. Let me work on switching that to a macro. Thanks.
> > + vaf.fmt = fmt;
> > + vaf.va = &va_args;
> > + vm_dbg(>_to_xe(gt)->drm, "PRL aborted: %pV", &vaf);
> > + va_end(va_args);
> > +}
> > +
> > /**
> > * xe_page_reclaim_list_init() - Initialize a page reclaim list
> > * @prl: Page reclaim list to initialize diff --git
> > a/drivers/gpu/drm/xe/xe_page_reclaim.h
> > b/drivers/gpu/drm/xe/xe_page_reclaim.h
> > index a4f58e0ce9b4..2464268dba69 100644
> > --- a/drivers/gpu/drm/xe/xe_page_reclaim.h
> > +++ b/drivers/gpu/drm/xe/xe_page_reclaim.h
> > @@ -19,6 +19,7 @@
> > struct xe_tlb_inval;
> > struct xe_tlb_inval_fence;
> > struct xe_tile;
> > +struct xe_gt;
> > struct xe_vma;
> >
> > struct xe_guc_page_reclaim_entry {
> > @@ -75,6 +76,8 @@ struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inva
> > struct xe_page_reclaim_list *prl,
> > struct xe_tlb_inval_fence *fence); void
> > xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl);
> > +void xe_page_reclaim_list_abort(struct xe_gt *gt, struct xe_page_reclaim_list *prl,
> > + const char *format, ...);
>
> So I think here, make xe_page_reclaim_list_abort a macro in this header file.
>
Got it.
> > void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl);
> > int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list
> > *prl);
> > /**
> > diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> > index 6cd78bb2b652..2752a5a48a97 100644
> > --- a/drivers/gpu/drm/xe/xe_pt.c
> > +++ b/drivers/gpu/drm/xe/xe_pt.c
> > @@ -1618,10 +1618,9 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> > } else if (is_2m_pte(xe_child)) {
> > reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
> > } else {
> > - xe_page_reclaim_list_invalidate(prl);
> > - vm_dbg(&tile_to_xe(tile)->drm,
> > - "PRL invalidate: unsupported PTE level=%u pte=%#llx\n",
> > - xe_child->level, pte);
> > + xe_page_reclaim_list_abort(tile->primary_gt, prl,
> > + "unsupported PTE level=%u pte=%#llx",
> > + xe_child->level, pte);
> > return -EINVAL;
> > }
> >
> > @@ -1670,10 +1669,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> > break;
> > } else {
> > /* overflow, mark as invalid */
> > - xe_page_reclaim_list_invalidate(xe_walk->prl);
> > - vm_dbg(&xe->drm,
> > - "PRL invalidate: overflow while adding pte=%#llx",
> > - pte);
> > + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> > + "overflow while adding pte=%#llx",
> > + pte);
> > break;
> > }
> > }
> > @@ -1682,10 +1680,9 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> > /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
> > if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
> > xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
> > - xe_page_reclaim_list_invalidate(xe_walk->prl);
> > - vm_dbg(&xe->drm,
> > - "PRL invalidate: kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> > - level, addr, next, xe_child->num_live);
> > + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> > + "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> > + level, addr, next, xe_child->num_live);
> > }
> >
> > return 0;
> > diff --git a/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> > b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> > index 6a7bd6315797..b8916552101c 100644
> > --- a/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> > +++ b/drivers/gpu/drm/xe/xe_tlb_inval_job.c
> > @@ -182,7 +182,7 @@ static void xe_tlb_inval_job_destroy(struct kref *ref)
> > struct xe_vm *vm = job->vm;
> >
> > /* BO creation retains a copy (if used), so no longer needed */
> > - xe_page_reclaim_entries_put(job->prl.entries);
> > + xe_page_reclaim_list_invalidate(&job->prl);
>
> This doesn't look right or at minimum is unrelated to this patch.
>
It was a thought since we had an explicit abort func for PRL, I thought it would be better to use
xe_page_reclaim_list_invalidate to properly invalidate any PRL that we would no longer use since
it would've been left in a state where entries are freed but the num_entries still have some value.
This would just be mirroring the logic we have for page reclaim in xe_pt where we invalidate the PRL
after passing the list to the tlb inval job. But I can remove it in next patch submission unless stated otherwise.
Brian
> Matt
>
> >
> > if (!job->fence_armed)
> > kfree(ifence);
> > --
> > 2.52.0
> >
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages
2026-01-05 23:33 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
@ 2026-01-06 16:41 ` Matthew Brost
2026-01-06 17:12 ` Nguyen, Brian3
0 siblings, 1 reply; 14+ messages in thread
From: Matthew Brost @ 2026-01-06 16:41 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
On Tue, Jan 06, 2026 at 07:33:55AM +0800, Brian Nguyen wrote:
> For 64KB pages, XE_PTE_PS64 is defined for all consecutive 4KB pages and
> are all considered leaf nodes, so existing check was falsely adding
> multiple 64KB pages to PRL.
>
> For larger entries such as 2MB PDE, the check for pte->base.children is
> insufficient since this array is always defined for page directory,
> level 1 and above, so perform a check on the entry itself pointing to
> the correct page.
>
> For unmaps, if the range is properly covered by the page full directory,
> page walker may finish without walking to the leaf nodes.
>
> For example, a 1G range can be fully covered by 512 2MB pages if
> alignment allows. In this case, the page walker will walk until
> it reaches this corresponding directory which can correlate to the 1GB
> range. Page walker will simply complete its walk and the individual 2MB
> PDE leaves won't get accessed.
>
> In this case, PRL invalidation is also required, so add a check to see if
> pt entry cover the entire range since the walker will complete the walk.
>
> There are possible race conditions that will cause driver to read a pte
> that hasn't been written to yet. The 2 scenarios are:
> - Another issued TLB invalidation such as from userptr or MMU notifier.
> - Dependencies on original bind that has yet to be executed with an
> unbind on that job.
>
> The expectation is these race conditions are likely rare cases so simply
> perform a fallback to full PPC flush invalidation instead.
>
> v2:
> - Reword commit and updated zero-pte handling. (Matthew B)
>
> Fixes: b912138df299 ("drm/xe: Create page reclaim list on unbind")
> Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_pt.c | 50 +++++++++++++++++++++++++++-----------
> 1 file changed, 36 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> index 2752a5a48a97..668a981696f9 100644
> --- a/drivers/gpu/drm/xe/xe_pt.c
> +++ b/drivers/gpu/drm/xe/xe_pt.c
> @@ -1576,12 +1576,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
> return false;
> }
>
> -/* Huge 2MB leaf lives directly in a level-1 table and has no children */
> -static bool is_2m_pte(struct xe_pt *pte)
> -{
> - return pte->level == 1 && !pte->base.children;
> -}
> -
> /* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
> #define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
> ({ \
> @@ -1594,7 +1588,8 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> u64 pte, struct xe_pt *xe_child)
> {
> struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
> - u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
> + u64 phys_addr = pte & XE_PTE_ADDR_MASK;
> + u64 phys_page = phys_addr >> XE_PTE_SHIFT;
> int num_entries = prl->num_entries;
> u32 reclamation_size;
>
> @@ -1613,10 +1608,13 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> */
> if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
> + xe_tile_assert(tile, phys_addr % SZ_4K == 0);
> } else if (xe_child->level == 0) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
> - } else if (is_2m_pte(xe_child)) {
> + xe_tile_assert(tile, phys_addr % SZ_64K == 0);
> + } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
> + xe_tile_assert(tile, phys_addr % SZ_2M == 0);
> } else {
> xe_page_reclaim_list_abort(tile->primary_gt, prl,
> "unsupported PTE level=%u pte=%#llx",
> @@ -1647,20 +1645,39 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> struct xe_pt_stage_unbind_walk *xe_walk =
> container_of(walk, typeof(*xe_walk), base);
> struct xe_device *xe = tile_to_xe(xe_walk->tile);
> + pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
>
> XE_WARN_ON(!*child);
> XE_WARN_ON(!level);
> /* Check for leaf node */
> if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
> - !xe_child->base.children) {
> + (!xe_child->base.children || !xe_child->base.children[first])) {
> struct iosys_map *leaf_map = &xe_child->bo->vmap;
> - pgoff_t first = xe_pt_offset(addr, 0, walk);
> - pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
> + pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
>
> for (pgoff_t i = 0; i < count; i++) {
> u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
> int ret;
>
> + /*
> + * In rare scenarios, pte may not be written yet due to racy conditions.
> + * In such cases, invalidate the PRL and fallback to full PPC invalidation.
> + */
> + if (!pte) {
> + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> + "found zero pte at addr=%#llx", addr);
> + break;
> + }
> +
> + /* Ensure it is a defined page */
> + xe_tile_assert(xe_walk->tile,
> + xe_child->level == 0 ||
> + (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
> +
> + /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
> + if (pte & XE_PTE_PS64)
> + i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
> +
> /* Account for NULL terminated entry on end (-1) */
> if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
> ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl,
> @@ -1677,9 +1694,14 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> }
> }
>
> - /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
> - if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
> - xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
> + /*
> + * If aborting page walk early or page walk finishes,
> + * invalidate PRL since PTE may be dropped from this abort
> + */
> + if ((xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) ||
> + xe_pt_covers(addr, next, xe_child->level, &xe_walk->base)) &&
> + xe_walk->prl && level > 1 && (xe_child->base.children &&
> + xe_child->base.children[first]) && xe_child->num_live != 0) {
This is pretty confusing if statement. I'm not really following the
'xe_child->base.children[first]' check. At minimum can the comment above
this if statement perhaps explain all the condition here?
Matt
> xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> level, addr, next, xe_child->num_live);
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages
2026-01-06 16:41 ` Matthew Brost
@ 2026-01-06 17:12 ` Nguyen, Brian3
0 siblings, 0 replies; 14+ messages in thread
From: Nguyen, Brian3 @ 2026-01-06 17:12 UTC (permalink / raw)
To: Brost, Matthew; +Cc: intel-xe@lists.freedesktop.org
On Tuesday, January 6, 2026 8:42 AM, Matthew Brost wrote:
> On Tue, Jan 06, 2026 at 07:33:55AM +0800, Brian Nguyen wrote:
> > For 64KB pages, XE_PTE_PS64 is defined for all consecutive 4KB pages
> > and are all considered leaf nodes, so existing check was falsely
> > adding multiple 64KB pages to PRL.
> >
> > For larger entries such as 2MB PDE, the check for pte->base.children
> > is insufficient since this array is always defined for page
> > directory, level 1 and above, so perform a check on the entry itself
> > pointing to the correct page.
> >
> > For unmaps, if the range is properly covered by the page full
> > directory, page walker may finish without walking to the leaf nodes.
> >
> > For example, a 1G range can be fully covered by 512 2MB pages if
> > alignment allows. In this case, the page walker will walk until it
> > reaches this corresponding directory which can correlate to the 1GB
> > range. Page walker will simply complete its walk and the individual
> > 2MB PDE leaves won't get accessed.
> >
> > In this case, PRL invalidation is also required, so add a check to see
> > if pt entry cover the entire range since the walker will complete the walk.
> >
> > There are possible race conditions that will cause driver to read a
> > pte that hasn't been written to yet. The 2 scenarios are:
> > - Another issued TLB invalidation such as from userptr or MMU notifier.
> > - Dependencies on original bind that has yet to be executed with an
> > unbind on that job.
> >
> > The expectation is these race conditions are likely rare cases so
> > simply perform a fallback to full PPC flush invalidation instead.
> >
> > v2:
> > - Reword commit and updated zero-pte handling. (Matthew B)
> >
> > Fixes: b912138df299 ("drm/xe: Create page reclaim list on unbind")
> > Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
> > Cc: Matthew Brost <matthew.brost@intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_pt.c | 50
> > +++++++++++++++++++++++++++-----------
> > 1 file changed, 36 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> > index 2752a5a48a97..668a981696f9 100644
> > --- a/drivers/gpu/drm/xe/xe_pt.c
> > +++ b/drivers/gpu/drm/xe/xe_pt.c
> > @@ -1576,12 +1576,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
> > return false;
> > }
> >
> > -/* Huge 2MB leaf lives directly in a level-1 table and has no
> > children */ -static bool is_2m_pte(struct xe_pt *pte) -{
> > - return pte->level == 1 && !pte->base.children;
> > -}
> > -
> > /* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
> > #define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
> > ({ \
> > @@ -1594,7 +1588,8 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> > u64 pte, struct xe_pt *xe_child) {
> > struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
> > - u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
> > + u64 phys_addr = pte & XE_PTE_ADDR_MASK;
> > + u64 phys_page = phys_addr >> XE_PTE_SHIFT;
> > int num_entries = prl->num_entries;
> > u32 reclamation_size;
> >
> > @@ -1613,10 +1608,13 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> > */
> > if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
> > reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /*
> > reclamation_size = 0 */
> > + xe_tile_assert(tile, phys_addr % SZ_4K == 0);
> > } else if (xe_child->level == 0) {
> > reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
> > - } else if (is_2m_pte(xe_child)) {
> > + xe_tile_assert(tile, phys_addr % SZ_64K == 0);
> > + } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
> > reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /*
> > reclamation_size = 9 */
> > + xe_tile_assert(tile, phys_addr % SZ_2M == 0);
> > } else {
> > xe_page_reclaim_list_abort(tile->primary_gt, prl,
> > "unsupported PTE level=%u pte=%#llx", @@ -1647,20 +1645,39 @@
> > static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> > struct xe_pt_stage_unbind_walk *xe_walk =
> > container_of(walk, typeof(*xe_walk), base);
> > struct xe_device *xe = tile_to_xe(xe_walk->tile);
> > + pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
> >
> > XE_WARN_ON(!*child);
> > XE_WARN_ON(!level);
> > /* Check for leaf node */
> > if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
> > - !xe_child->base.children) {
> > + (!xe_child->base.children || !xe_child->base.children[first])) {
> > struct iosys_map *leaf_map = &xe_child->bo->vmap;
> > - pgoff_t first = xe_pt_offset(addr, 0, walk);
> > - pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
> > + pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level,
> > +walk);
> >
> > for (pgoff_t i = 0; i < count; i++) {
> > u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
> > int ret;
> >
> > + /*
> > + * In rare scenarios, pte may not be written yet due to racy conditions.
> > + * In such cases, invalidate the PRL and fallback to full PPC invalidation.
> > + */
> > + if (!pte) {
> > + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> > + "found zero pte at addr=%#llx", addr);
> > + break;
> > + }
> > +
> > + /* Ensure it is a defined page */
> > + xe_tile_assert(xe_walk->tile,
> > + xe_child->level == 0 ||
> > + (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
> > +
> > + /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
> > + if (pte & XE_PTE_PS64)
> > + i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
> > +
> > /* Account for NULL terminated entry on end (-1) */
> > if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
> > ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl, @@
> > -1677,9 +1694,14 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> > }
> > }
> >
> > - /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
> > - if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
> > - xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
> > + /*
> > + * If aborting page walk early or page walk finishes,
> > + * invalidate PRL since PTE may be dropped from this abort
> > + */
> > + if ((xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) ||
> > + xe_pt_covers(addr, next, xe_child->level, &xe_walk->base)) &&
> > + xe_walk->prl && level > 1 && (xe_child->base.children &&
> > + xe_child->base.children[first]) && xe_child->num_live != 0) {
>
> This is pretty confusing if statement. I'm not really following the 'xe_child->base.children[first]' check. At minimum can the comment
> above this if statement perhaps explain all the condition here?
>
Sure, will add a comment here for the conditions.
My line of thinking for the conditions were:
xe_child->base.children[first] addition was due to xe_child->base.children check being insufficient for page directory above level 1,
which would correspond to the 2MB pages (appears to always be defined even if it's a 2MB leaf). In that case, I am looking to see
if that 2MB page directory has a child at the corresponding index and if so, we can determine if it's a leaf 2MB page table or still
some sort of page directory.
xe_pt_check_kill was the check to see if we kill subsequent page walks.
xe_pt_covers checks the condition where we'll walk a page directory that perfectly corresponds to the range so it
will not continue to page walk. The worry here is for a case such as 1GB range filled with 512 x 2MB pages, we will
walk the 1GB range but won't enter one level down, which will drop this entire range if not handled.
xe_walk->prl && level > 1 is nullptr check for PRL and to ensure we don't fallback on a pte killed.
xe_child->num_live != 0 ensures that the range killed is one that doesn't have any children, then there's no need to fallback.
Brian
> Matt
>
> > xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> > "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> > level, addr, next, xe_child->num_live);
> > --
> > 2.52.0
> >
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages
2026-01-07 1:04 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
@ 2026-01-07 1:04 ` Brian Nguyen
2026-01-08 16:22 ` Matthew Brost
0 siblings, 1 reply; 14+ messages in thread
From: Brian Nguyen @ 2026-01-07 1:04 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost
For 64KB pages, XE_PTE_PS64 is defined for all consecutive 4KB pages and
are all considered leaf nodes, so existing check was falsely adding
multiple 64KB pages to PRL.
For larger entries such as 2MB PDE, the check for pte->base.children is
insufficient since this array is always defined for page directory,
level 1 and above, so perform a check on the entry itself pointing to
the correct page.
For unmaps, if the range is properly covered by the page full directory,
page walker may finish without walking to the leaf nodes.
For example, a 1G range can be fully covered by 512 2MB pages if
alignment allows. In this case, the page walker will walk until
it reaches this corresponding directory which can correlate to the 1GB
range. Page walker will simply complete its walk and the individual 2MB
PDE leaves won't get accessed.
In this case, PRL invalidation is also required, so add a check to see if
pt entry cover the entire range since the walker will complete the walk.
There are possible race conditions that will cause driver to read a pte
that hasn't been written to yet. The 2 scenarios are:
- Another issued TLB invalidation such as from userptr or MMU notifier.
- Dependencies on original bind that has yet to be executed with an
unbind on that job.
The expectation is these race conditions are likely rare cases so simply
perform a fallback to full PPC flush invalidation instead.
v2:
- Reword commit and updated zero-pte handling. (Matthew B)
v3:
- Rework if statement for abort case with additional comments. (Matthew B)
Fixes: b912138df299 ("drm/xe: Create page reclaim list on unbind")
Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 64 ++++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 2752a5a48a97..a53944957be4 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -1576,12 +1576,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
return false;
}
-/* Huge 2MB leaf lives directly in a level-1 table and has no children */
-static bool is_2m_pte(struct xe_pt *pte)
-{
- return pte->level == 1 && !pte->base.children;
-}
-
/* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
#define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
({ \
@@ -1594,7 +1588,8 @@ static int generate_reclaim_entry(struct xe_tile *tile,
u64 pte, struct xe_pt *xe_child)
{
struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
- u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
+ u64 phys_addr = pte & XE_PTE_ADDR_MASK;
+ u64 phys_page = phys_addr >> XE_PTE_SHIFT;
int num_entries = prl->num_entries;
u32 reclamation_size;
@@ -1613,10 +1608,13 @@ static int generate_reclaim_entry(struct xe_tile *tile,
*/
if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
+ xe_tile_assert(tile, phys_addr % SZ_4K == 0);
} else if (xe_child->level == 0) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
- } else if (is_2m_pte(xe_child)) {
+ xe_tile_assert(tile, phys_addr % SZ_64K == 0);
+ } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
+ xe_tile_assert(tile, phys_addr % SZ_2M == 0);
} else {
xe_page_reclaim_list_abort(tile->primary_gt, prl,
"unsupported PTE level=%u pte=%#llx",
@@ -1647,20 +1645,40 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
struct xe_pt_stage_unbind_walk *xe_walk =
container_of(walk, typeof(*xe_walk), base);
struct xe_device *xe = tile_to_xe(xe_walk->tile);
+ pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
+ bool killed;
XE_WARN_ON(!*child);
XE_WARN_ON(!level);
/* Check for leaf node */
if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
- !xe_child->base.children) {
+ (!xe_child->base.children || !xe_child->base.children[first])) {
struct iosys_map *leaf_map = &xe_child->bo->vmap;
- pgoff_t first = xe_pt_offset(addr, 0, walk);
- pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
+ pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
for (pgoff_t i = 0; i < count; i++) {
u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
int ret;
+ /*
+ * In rare scenarios, pte may not be written yet due to racy conditions.
+ * In such cases, invalidate the PRL and fallback to full PPC invalidation.
+ */
+ if (!pte) {
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "found zero pte at addr=%#llx", addr);
+ break;
+ }
+
+ /* Ensure it is a defined page */
+ xe_tile_assert(xe_walk->tile,
+ xe_child->level == 0 ||
+ (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
+
+ /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
+ if (pte & XE_PTE_PS64)
+ i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
+
/* Account for NULL terminated entry on end (-1) */
if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl,
@@ -1677,12 +1695,24 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
}
}
- /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
- if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
- xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
- xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
- "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
- level, addr, next, xe_child->num_live);
+ killed = xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk);
+
+ /*
+ * Verify PRL is active and if entry is not a leaf pte (base.children conditions),
+ * there is a potential need to invalidate the PRL if any PTE (num_live) are dropped.
+ */
+ if (xe_walk->prl && level > 1 && xe_child->num_live &&
+ xe_child->base.children && xe_child->base.children[first]) {
+ bool covered = xe_pt_covers(addr, next, xe_child->level, &xe_walk->base);
+
+ /*
+ * If aborting page walk early (kill) or page walk completes the full range
+ * we need to invalidate the PRL.
+ */
+ if (killed || covered)
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "kill at level=%u addr=%#llx next=%#llx num_live=%u",
+ level, addr, next, xe_child->num_live);
}
return 0;
--
2.52.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages
2026-01-07 1:04 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
@ 2026-01-08 16:22 ` Matthew Brost
0 siblings, 0 replies; 14+ messages in thread
From: Matthew Brost @ 2026-01-08 16:22 UTC (permalink / raw)
To: Brian Nguyen; +Cc: intel-xe
On Wed, Jan 07, 2026 at 09:04:51AM +0800, Brian Nguyen wrote:
> For 64KB pages, XE_PTE_PS64 is defined for all consecutive 4KB pages and
> are all considered leaf nodes, so existing check was falsely adding
> multiple 64KB pages to PRL.
>
> For larger entries such as 2MB PDE, the check for pte->base.children is
> insufficient since this array is always defined for page directory,
> level 1 and above, so perform a check on the entry itself pointing to
> the correct page.
>
> For unmaps, if the range is properly covered by the page full directory,
> page walker may finish without walking to the leaf nodes.
>
> For example, a 1G range can be fully covered by 512 2MB pages if
> alignment allows. In this case, the page walker will walk until
> it reaches this corresponding directory which can correlate to the 1GB
> range. Page walker will simply complete its walk and the individual 2MB
> PDE leaves won't get accessed.
>
> In this case, PRL invalidation is also required, so add a check to see if
> pt entry cover the entire range since the walker will complete the walk.
>
> There are possible race conditions that will cause driver to read a pte
> that hasn't been written to yet. The 2 scenarios are:
> - Another issued TLB invalidation such as from userptr or MMU notifier.
> - Dependencies on original bind that has yet to be executed with an
> unbind on that job.
>
> The expectation is these race conditions are likely rare cases so simply
> perform a fallback to full PPC flush invalidation instead.
>
> v2:
> - Reword commit and updated zero-pte handling. (Matthew B)
>
> v3:
> - Rework if statement for abort case with additional comments. (Matthew B)
>
> Fixes: b912138df299 ("drm/xe: Create page reclaim list on unbind")
> Signed-off-by: Brian Nguyen <brian3.nguyen@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_pt.c | 64 ++++++++++++++++++++++++++++----------
> 1 file changed, 47 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> index 2752a5a48a97..a53944957be4 100644
> --- a/drivers/gpu/drm/xe/xe_pt.c
> +++ b/drivers/gpu/drm/xe/xe_pt.c
> @@ -1576,12 +1576,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
> return false;
> }
>
> -/* Huge 2MB leaf lives directly in a level-1 table and has no children */
> -static bool is_2m_pte(struct xe_pt *pte)
> -{
> - return pte->level == 1 && !pte->base.children;
> -}
> -
> /* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
> #define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
> ({ \
> @@ -1594,7 +1588,8 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> u64 pte, struct xe_pt *xe_child)
> {
> struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
> - u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
> + u64 phys_addr = pte & XE_PTE_ADDR_MASK;
> + u64 phys_page = phys_addr >> XE_PTE_SHIFT;
> int num_entries = prl->num_entries;
> u32 reclamation_size;
>
> @@ -1613,10 +1608,13 @@ static int generate_reclaim_entry(struct xe_tile *tile,
> */
> if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
> + xe_tile_assert(tile, phys_addr % SZ_4K == 0);
> } else if (xe_child->level == 0) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
> - } else if (is_2m_pte(xe_child)) {
> + xe_tile_assert(tile, phys_addr % SZ_64K == 0);
> + } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
> reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
> + xe_tile_assert(tile, phys_addr % SZ_2M == 0);
> } else {
> xe_page_reclaim_list_abort(tile->primary_gt, prl,
> "unsupported PTE level=%u pte=%#llx",
> @@ -1647,20 +1645,40 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> struct xe_pt_stage_unbind_walk *xe_walk =
> container_of(walk, typeof(*xe_walk), base);
> struct xe_device *xe = tile_to_xe(xe_walk->tile);
> + pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
> + bool killed;
>
> XE_WARN_ON(!*child);
> XE_WARN_ON(!level);
> /* Check for leaf node */
> if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
> - !xe_child->base.children) {
> + (!xe_child->base.children || !xe_child->base.children[first])) {
> struct iosys_map *leaf_map = &xe_child->bo->vmap;
> - pgoff_t first = xe_pt_offset(addr, 0, walk);
> - pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
> + pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
>
> for (pgoff_t i = 0; i < count; i++) {
> u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
> int ret;
>
> + /*
> + * In rare scenarios, pte may not be written yet due to racy conditions.
> + * In such cases, invalidate the PRL and fallback to full PPC invalidation.
> + */
> + if (!pte) {
> + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> + "found zero pte at addr=%#llx", addr);
> + break;
> + }
> +
> + /* Ensure it is a defined page */
> + xe_tile_assert(xe_walk->tile,
> + xe_child->level == 0 ||
> + (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
> +
> + /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
> + if (pte & XE_PTE_PS64)
> + i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
> +
> /* Account for NULL terminated entry on end (-1) */
> if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
> ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl,
> @@ -1677,12 +1695,24 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
> }
> }
>
> - /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
> - if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
> - xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
> - xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> - "kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
> - level, addr, next, xe_child->num_live);
> + killed = xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk);
> +
> + /*
> + * Verify PRL is active and if entry is not a leaf pte (base.children conditions),
> + * there is a potential need to invalidate the PRL if any PTE (num_live) are dropped.
> + */
> + if (xe_walk->prl && level > 1 && xe_child->num_live &&
> + xe_child->base.children && xe_child->base.children[first]) {
> + bool covered = xe_pt_covers(addr, next, xe_child->level, &xe_walk->base);
> +
> + /*
> + * If aborting page walk early (kill) or page walk completes the full range
> + * we need to invalidate the PRL.
> + */
> + if (killed || covered)
> + xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
> + "kill at level=%u addr=%#llx next=%#llx num_live=%u",
> + level, addr, next, xe_child->num_live);
> }
>
> return 0;
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-01-08 16:22 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-05 23:33 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
2026-01-05 23:33 ` [PATCH 1/4] drm/xe: Remove debug comment in page reclaim Brian Nguyen
2026-01-06 2:15 ` Matthew Brost
2026-01-05 23:33 ` [PATCH 2/4] drm/xe: Add explicit abort page reclaim list Brian Nguyen
2026-01-06 2:23 ` Matthew Brost
2026-01-06 12:44 ` Nguyen, Brian3
2026-01-05 23:33 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
2026-01-06 16:41 ` Matthew Brost
2026-01-06 17:12 ` Nguyen, Brian3
2026-01-05 23:33 ` [PATCH 4/4] drm/xe: Add page reclamation related stats Brian Nguyen
2026-01-05 23:41 ` ✓ CI.KUnit: success for Page-reclaim fixes and PRL stats addition (rev2) Patchwork
2026-01-06 1:12 ` ✗ Xe.CI.Full: failure " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2026-01-07 1:04 [PATCH 0/4] Page-reclaim fixes and PRL stats addition Brian Nguyen
2026-01-07 1:04 ` [PATCH 3/4] drm/xe: Fix page reclaim entry handling for large pages Brian Nguyen
2026-01-08 16:22 ` Matthew Brost
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox