drm/xe/vf: Rebase HWSP of all contexts after migration

All contexts require an update due to GGTT range shift, as that
affects their HWSP.

The HW status page of a context contains GGTT references, which
need to be shifted to a new range (or re-computed using the
previously updated vma nodes). The references include ring start
address and indirect state address.

v2: move some functions to better matched files
v3: Add missing kerneldocs
v4: Style fix

Signed-off-by: Tomasz Lis <tomasz.lis@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Michal Winiarski <michal.winiarski@intel.com>
Acked-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
Reviewed-by: Michal Winiarski <michal.winiarski@intel.com>
Link: https://lore.kernel.org/r/20250802031045.1127138-5-tomasz.lis@intel.com
Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
This commit is contained in:
Tomasz Lis
2025-08-02 05:10:41 +02:00
committed by Michał Winiarski
parent a0840b1ce9
commit b46ef76673
7 changed files with 52 additions and 0 deletions

View File

@@ -1076,3 +1076,16 @@ int xe_exec_queue_last_fence_test_dep(struct xe_exec_queue *q, struct xe_vm *vm)
return err;
}
/**
* xe_exec_queue_contexts_hwsp_rebase - Re-compute GGTT references
* within all LRCs of a queue.
* @q: the &xe_exec_queue struct instance containing target LRCs
*/
void xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q)
{
int i;
for (i = 0; i < q->width; ++i)
xe_lrc_update_hwctx_regs_with_address(q->lrc[i]);
}

View File

@@ -90,4 +90,6 @@ int xe_exec_queue_last_fence_test_dep(struct xe_exec_queue *q,
struct xe_vm *vm);
void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q);
void xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q);
#endif

View File

@@ -2505,3 +2505,19 @@ void xe_guc_submit_print(struct xe_guc *guc, struct drm_printer *p)
guc_exec_queue_print(q, p);
mutex_unlock(&guc->submission_state.lock);
}
/**
* xe_guc_contexts_hwsp_rebase - Re-compute GGTT references within all
* exec queues registered to given GuC.
* @guc: the &xe_guc struct instance
*/
void xe_guc_contexts_hwsp_rebase(struct xe_guc *guc)
{
struct xe_exec_queue *q;
unsigned long index;
mutex_lock(&guc->submission_state.lock);
xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
xe_exec_queue_contexts_hwsp_rebase(q);
mutex_unlock(&guc->submission_state.lock);
}

View File

@@ -46,4 +46,6 @@ xe_guc_exec_queue_snapshot_free(struct xe_guc_submit_exec_queue_snapshot *snapsh
void xe_guc_submit_print(struct xe_guc *guc, struct drm_printer *p);
void xe_guc_register_exec_queue(struct xe_exec_queue *q, int ctx_type);
void xe_guc_contexts_hwsp_rebase(struct xe_guc *guc);
#endif

View File

@@ -1439,6 +1439,23 @@ void xe_lrc_destroy(struct kref *ref)
kfree(lrc);
}
/**
* xe_lrc_update_hwctx_regs_with_address - Re-compute GGTT references within given LRC.
* @lrc: the &xe_lrc struct instance
*/
void xe_lrc_update_hwctx_regs_with_address(struct xe_lrc *lrc)
{
if (xe_lrc_has_indirect_ring_state(lrc)) {
xe_lrc_write_ctx_reg(lrc, CTX_INDIRECT_RING_STATE,
__xe_lrc_indirect_ring_ggtt_addr(lrc));
xe_lrc_write_indirect_ctx_reg(lrc, INDIRECT_CTX_RING_START,
__xe_lrc_ring_ggtt_addr(lrc));
} else {
xe_lrc_write_ctx_reg(lrc, CTX_RING_START, __xe_lrc_ring_ggtt_addr(lrc));
}
}
void xe_lrc_set_ring_tail(struct xe_lrc *lrc, u32 tail)
{
if (xe_lrc_has_indirect_ring_state(lrc))

View File

@@ -88,6 +88,7 @@ bool xe_lrc_ring_is_idle(struct xe_lrc *lrc);
u32 xe_lrc_indirect_ring_ggtt_addr(struct xe_lrc *lrc);
u32 xe_lrc_ggtt_addr(struct xe_lrc *lrc);
u32 *xe_lrc_regs(struct xe_lrc *lrc);
void xe_lrc_update_hwctx_regs_with_address(struct xe_lrc *lrc);
u32 xe_lrc_read_ctx_reg(struct xe_lrc *lrc, int reg_nr);
void xe_lrc_write_ctx_reg(struct xe_lrc *lrc, int reg_nr, u32 val);

View File

@@ -269,6 +269,7 @@ static int gt_vf_post_migration_fixups(struct xe_gt *gt)
shift = xe_gt_sriov_vf_ggtt_shift(gt);
if (shift) {
xe_tile_sriov_vf_fixup_ggtt_nodes(gt_to_tile(gt), shift);
xe_guc_contexts_hwsp_rebase(&gt->uc.guc);
/* FIXME: add the recovery steps */
xe_guc_ct_fixup_messages_with_ggtt(&gt->uc.guc.ct, shift);
}