Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Matthew Auld" <matthew.auld@intel.com>
Cc: intel-xe@lists.freedesktop.org
Subject: Re: [CI] drm/xe/vram: Add early VRAM health check
Date: Wed, 26 Aug 2026 13:11:34 +0000	[thread overview]
Message-ID: <20260826131135.4BD171F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260826125304.378173-2-matthew.auld@intel.com>

Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [High] VRAM memtest BOs are leaked on error paths and skipped tiles.
- [High] `xe_migrate_debug_ccs_overlap` fails to acquire the necessary `job_mutex` lock.
- [High] `xe_migrate_debug_ccs_overlap` fails to initialize the second migration batch buffer, causing execution of uninitialized GPU memory.
- [High] Hardcoded 256MB VRAM bounds in `xe_migrate_debug_ccs_overlap` causes out-of-bounds GPU reads on systems with small VRAM.
- [High] The CCS overlap test writes a canary to the end of VRAM but checks the CCS metadata for the beginning of VRAM, rendering the test useless.
- [Medium] Mismatch between code implementation and comment for flat CCS offset rounding.
- [Medium] Config guard mismatch for `memtest_bo` causes build failures.
- [Medium] Ignoring the return value of `xe_migrate_clear()` masks software errors as hardware failures.
--

commit c386b266adaf1a488d11cddd5ddf577c88467fb1
Author: Matthew Auld <matthew.auld@intel.com>
Subject: drm/xe/vram: Add early VRAM health check

This commit introduces an early VRAM health check to detect BAR sizing, CCS
sizing, and identity map setup issues using a canary page at the end of VRAM.

> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> index 71ce153737abe..5d9e3dc133fa8 100644
> --- a/drivers/gpu/drm/xe/xe_device.c
> +++ b/drivers/gpu/drm/xe/xe_device.c
[ ... ]
> @@ -1040,6 +1040,8 @@ int xe_device_probe(struct xe_device *xe)
>  	if (err)
>  		return err;
>  
> +	xe_vram_reserve_memtest_bo(xe);
> +
>  	for_each_tile(tile, xe, id) {
>  		err = xe_tile_init(tile);
>  		if (err)
>  			return err;

[Severity: High]
If xe_tile_init() fails, does this code leak the reserved memtest BOs since
there is no cleanup before returning the error?

[ ... ]
> diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
> index f79d0047bec69..644be4c2d4404 100644
> --- a/drivers/gpu/drm/xe/xe_migrate.c
> +++ b/drivers/gpu/drm/xe/xe_migrate.c
[ ... ]
> @@ -2635,3 +2635,59 @@ void xe_migrate_job_lock_assert(struct xe_exec_queue *q)
>  #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
>  #include "tests/xe_migrate.c"
>  #endif
> +
> +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEM)
> +void xe_migrate_debug_ccs_overlap(struct xe_migrate *m, struct xe_bo *last_page_bo, struct xe_bo *scratch_bo)
> +{
> +	struct xe_device *xe = tile_to_xe(m->tile);
> +	struct xe_gt *gt = m->tile->primary_gt;
> +	struct dma_fence *fence;
> +	struct xe_bb *bb;
> +	struct xe_sched_job *job;
> +	u64 first_page_dpa, clear_L0_ofs, scratch_dpa, scratch_L0_ofs;
> +
> +	if (!xe_device_has_flat_ccs(xe))
> +		return;
> +
> +	first_page_dpa = xe_vram_region_dpa_base(m->tile->mem.vram);
> +	clear_L0_ofs = xe_migrate_vram_ofs(xe, first_page_dpa, true);

[Severity: High]
The test writes a canary pattern to the end of VRAM (vram_size - SZ_64K) later,
but clear_L0_ofs is based on first_page_dpa (the very beginning of VRAM). Does
this check the wrong CCS metadata region and miss the canary pattern entirely?

> +
> +	scratch_dpa = xe_bo_addr(scratch_bo, 0, XE_PAGE_SIZE);
> +	scratch_L0_ofs = xe_migrate_vram_ofs(xe, scratch_dpa, false);
> +
> +	for (int j = 0; j < 4; j++) {
> +		bb = xe_bb_new(gt, 256, xe->info.has_usm);
> +		if (IS_ERR(bb)) {
> +			drm_warn(&xe->drm, "Failed to create bb for VRAM overlap check\n");
> +			return;
> +		}
> +
> +		for (int i = 0; i < 16; i++) {
> +			int idx = (j * 16) + i;
> +			/* 4MB payload = 16KB CCS metadata */
> +			emit_copy_ccs(gt, bb, scratch_L0_ofs + (idx * 16384), false,
> +				      clear_L0_ofs + (idx * SZ_4M), true, SZ_4M);

[Severity: High]
Is it possible for a tile's VRAM to be smaller than 256MB? This loop
unconditionally tests 256MB (64 iterations of 4MB chunks), which might result
in out-of-bounds GPU reads on smaller VRAM configurations.

> +		}
> +
> +		bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
> +
> +		job = xe_bb_create_migration_job(m->q, bb,
> +						 xe_migrate_batch_base(m, xe->info.has_usm),
> +						 bb->len);

[Severity: High]
By passing bb->len as the second_idx right after writing MI_BATCH_BUFFER_END,
does xe_bb_create_migration_job() leave the second batch buffer empty and
unterminated? This might cause the GPU to execute uninitialized memory.

> +		if (!IS_ERR(job)) {
> +			xe_sched_job_add_migrate_flush(job, MI_FLUSH_DW_CCS);
> +			xe_sched_job_arm(job);
> +
> +			fence = dma_fence_get(&job->drm.s_fence->finished);
> +			xe_sched_job_push(job);

[Severity: High]
Does this code need to acquire m->job_mutex before calling xe_sched_job_arm()
and xe_sched_job_push()? Other migration jobs hold this lock to serialize
queue accesses.

[ ... ]
> diff --git a/drivers/gpu/drm/xe/xe_tile_types.h b/drivers/gpu/drm/xe/xe_tile_types.h
> index 0048100ccb723..75097e4d1c643 100644
> --- a/drivers/gpu/drm/xe/xe_tile_types.h
> +++ b/drivers/gpu/drm/xe/xe_tile_types.h
> @@ -97,6 +97,10 @@ struct xe_tile {
>  		 * Only main GT has page reclaim list allocations.
>  		 */
>  		struct xe_sa_manager *reclaim_pool;
> +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
> +		/** @mem.memtest_bo: VRAM overlap check BO */
> +		struct xe_bo *memtest_bo;
> +#endif

[Severity: Medium]
In this header, memtest_bo is guarded by CONFIG_DRM_XE_DEBUG, but in
xe_vram.c and xe_migrate.c its usage is guarded by CONFIG_DRM_XE_DEBUG_MEM.
Will this cause a build failure if CONFIG_DRM_XE_DEBUG_MEM is enabled without
CONFIG_DRM_XE_DEBUG?

[ ... ]
> diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c
> index 23eb7edbdd572..eb3d7b42371cd 100644
> --- a/drivers/gpu/drm/xe/xe_vram.c
> +++ b/drivers/gpu/drm/xe/xe_vram.c
[ ... ]
> @@ -89,7 +92,7 @@ static int get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size, u64 *poffset)
>  		offset = offset_hi << 32; /* HW view bits 39:32 */
>  		offset |= offset_lo << 6; /* HW view bits 31:6 */
>  		offset *= num_enabled; /* convert to SW view */
> -		offset = round_up(offset, SZ_128K); /* SW must round up to nearest 128K */
> +		offset = round_up(offset, SZ_128K); /* SW must round down to nearest 2M */

[Severity: Medium]
The comment states we must round down to nearest 2M, but the code still calls
round_up(offset, SZ_128K). Which one is the intended behavior?

[ ... ]
> @@ -387,3 +390,160 @@ resource_size_t xe_vram_region_actual_physical_size(const struct xe_vram_region
[ ... ]
> +int xe_vram_memtest(struct xe_device *xe)
> +{
> +	struct xe_tile *tile;
> +	u8 id;
> +	int err = 0;
> +
> +	for_each_tile(tile, xe, id) {
> +		struct xe_bo *last_page_bo = tile->mem.memtest_bo;
> +		struct dma_fence *fence;
> +		bool overlap = false;
> +		int i, consecutive = 0;
> +		u8 val;
> +
> +		if (!last_page_bo || !tile->migrate)
> +			continue;

[Severity: High]
For tiles without a migrate engine, does this continue bypass the unpin and
cleanup of tile->mem.memtest_bo, leading to a resource leak?

[ ... ]
> +		/* 2. Non-CCS access via GPU on the last page */
> +		fence = xe_migrate_clear(tile->migrate, last_page_bo,
> +					 last_page_bo->ttm.resource,
> +					 XE_MIGRATE_CLEAR_FLAG_BO_DATA);
> +		if (!IS_ERR(fence)) {
> +			dma_fence_wait(fence, false);
> +			dma_fence_put(fence);
> +		}
> +
> +		rmb();
> +
> +		val = xe_map_rd(xe, &last_page_bo->vmap, 0, u8);
> +		if (drm_WARN(&xe->drm, val != 0x00,
> +			     "Tile %d: GPU memtest clear failed at offset 0 (expected 0x00, got 0x%02x)\n",
> +			     id, val)) {

[Severity: Medium]
If xe_migrate_clear() fails and returns an ERR_PTR, this skips the wait but
proceeds to read the VRAM validation byte. Will this falsely report a GPU
hardware failure because it reads the old 0xA5 value instead of 0x00?

[ ... ]
> +
> +unpin:
> +		xe_bo_unpin_map_no_vm(last_page_bo);
> +		tile->mem.memtest_bo = NULL;
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}

[Severity: High]
On error, this early return skips cleanup for the remaining tiles in the loop.
Does this code leak the memtest_bo for subsequent tiles?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260826125304.378173-2-matthew.auld@intel.com?part=1

  parent reply	other threads:[~2026-08-26 13:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 12:53 [CI] drm/xe/vram: Add early VRAM health check Matthew Auld
2026-08-26 12:59 ` ✗ CI.checkpatch: warning for " Patchwork
2026-08-26 13:01 ` ✓ CI.KUnit: success " Patchwork
2026-08-26 13:11 ` sashiko-bot [this message]
2026-08-26 13:59 ` ✗ Xe.CI.BAT: failure " Patchwork
2026-08-26 16:12 ` ✗ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260826131135.4BD171F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.auld@intel.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox