<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 28.05.2025 12:44, Michał Winiarski
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:jsmkqmq2m2uh2kee6dyxzklq3g3nm3htbskxf5zobpenchn3tm@mptopuryvmw3">
      <pre wrap="" class="moz-quote-pre">On Tue, May 20, 2025 at 01:19:24AM +0200, Tomasz Lis wrote:
</pre>
      <blockquote type="cite">
        <pre wrap="" class="moz-quote-pre">All contexts require an update of state data, as the data includes
GGTT references to memirq-related buffers.

Default contexts need these references updated as well, because they
are not refreshed when a new context is created from them.

v2: Update addresses by xe_lrc_write_ctx_reg() rather than
  set_memory_based_intr()
v3: Renamed parameter, reordered parameters in some functs

Signed-off-by: Tomasz Lis <a class="moz-txt-link-rfc2396E" href="mailto:tomasz.lis@intel.com"><tomasz.lis@intel.com></a>
Cc: Michal Wajdeczko <a class="moz-txt-link-rfc2396E" href="mailto:michal.wajdeczko@intel.com"><michal.wajdeczko@intel.com></a>
---
 drivers/gpu/drm/xe/xe_exec_queue.c |  4 +++-
 drivers/gpu/drm/xe/xe_lrc.c        | 35 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/xe/xe_lrc.h        |  2 ++
 drivers/gpu/drm/xe/xe_sriov_vf.c   | 13 ++++++++++-
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index d696c8410a32..9c3e568400e0 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -1051,6 +1051,8 @@ void xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q)
 {
        int i;
 
-       for (i = 0; i < q->width; ++i)
+       for (i = 0; i < q->width; ++i) {
+               xe_lrc_update_memirq_regs_with_address(q->lrc[i], q->hwe);
</pre>
      </blockquote>
      <pre wrap="" class="moz-quote-pre">
What if we're not using memirq?</pre>
    </blockquote>
    <p>We currently do not support VF Migration with Xe driver on any
      platform without memory-based IRQs.</p>
    <p>But will add `xe_device_uses_memirq()` condition - MMIO IRQs
      should not need any additional code within VF recovery (we're
      already re-enabling IRQs during kickstart), so that's the only
      thing required for the support.<br>
    </p>
    <blockquote type="cite" cite="mid:jsmkqmq2m2uh2kee6dyxzklq3g3nm3htbskxf5zobpenchn3tm@mptopuryvmw3">
      <pre wrap="" class="moz-quote-pre">

</pre>
      <blockquote type="cite">
        <pre wrap="" class="moz-quote-pre">           xe_lrc_update_hwctx_regs_with_address(q->lrc[i]);
+       }
 }
diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 525565480aef..959ac9c5d39a 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -898,6 +898,41 @@ static void *empty_lrc_data(struct xe_hw_engine *hwe)
        return data;
 }
 
+/**
+ * xe_default_lrc_update_memirq_regs_with_address - Re-compute GGTT references in default LRC
+ *   of given engine.
+ * @hwe: the &xe_hw_engine struct instance
+ */
+void xe_default_lrc_update_memirq_regs_with_address(struct xe_hw_engine *hwe)
+{
+       struct xe_gt *gt = hwe->gt;
+       u32 *regs;
+
+       if (!gt->default_lrc[hwe->class])
+               return;
+
+       regs = gt->default_lrc[hwe->class] + LRC_PPHWSP_SIZE;
+       set_memory_based_intr(regs, hwe);
</pre>
      </blockquote>
      <pre wrap="" class="moz-quote-pre">
We're using set_memory_based_intr() for gt->default_lrc, and
xe_lrc_update_memirq_regs_with_address() for q->lrc.

Why do we need 2 different methods to do that?
</pre>
    </blockquote>
    <p>Real context state may be in LMEM, while default is just a
      CPU-side buffer.</p>
    <p>In Xe, we use iosys_map struct to write shared memory, and we
      have wrappers over the kernel functions to handle write/read from
      instances of that struct.</p>
    <p>Therefore, we cannot reuse `set_memory_based_intr()` for real
      LRCs. Well, we could allocate a cpu-side buffer, copy data to it,
      call the `set_memory_based_intr()` and the copy again. This is
      actually what I did originally - but it was problematic because
      required `kalloc()` so it got changed on previous round of review.<br>
    </p>
    <p>Going opposite way, we could use `<span class="k">struct</span><span class="w"> </span><span class="nc"><span class="highlighted">iosys_map</span></span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n"><span class="highlighted">IOSYS_MAP</span>_INIT_VADDR</span><span class="p">(regs</span><span class="p">);</span><span class="w"></span>`
      and use the `<span style="white-space: pre-wrap">xe_lrc_update_memirq_regs_with_address()` on both real and default LRC. But that would require getting rid of `xe_lrc_write_ctx_reg()` reuse, and it wouldn't really eliminate any code - </span>`set_memory_based_intr()`
      still have to stay.<br>
    </p>
    <p>So - yes, we use two different methods, but only one is
      implemented in this patch.<br>
    </p>
    <blockquote type="cite" cite="mid:jsmkqmq2m2uh2kee6dyxzklq3g3nm3htbskxf5zobpenchn3tm@mptopuryvmw3">
      <blockquote type="cite">
        <pre wrap="" class="moz-quote-pre">+}
+
+/**
+ * xe_lrc_update_memirq_regs_with_address - Re-compute GGTT references in mem interrupt data
+ *   for given LRC.
+ * @lrc: the &xe_lrc struct instance
+ * @hwe: the &xe_hw_engine struct instance
+ */
+void xe_lrc_update_memirq_regs_with_address(struct xe_lrc *lrc, struct xe_hw_engine *hwe)
+{
+       struct xe_memirq *memirq = &gt_to_tile(hwe->gt)->memirq;
+
+       xe_lrc_write_ctx_reg(lrc, CTX_INT_MASK_ENABLE_PTR,
+                            xe_memirq_enable_ptr(memirq));
+       xe_lrc_write_ctx_reg(lrc, CTX_INT_STATUS_REPORT_PTR,
+                            xe_memirq_status_ptr(memirq, hwe));
+       xe_lrc_write_ctx_reg(lrc, CTX_INT_SRC_REPORT_PTR,
+                            xe_memirq_source_ptr(memirq, hwe));
+}
+
 static void xe_lrc_set_ppgtt(struct xe_lrc *lrc, struct xe_vm *vm)
 {
        u64 desc = xe_vm_pdp4_descriptor(vm, gt_to_tile(lrc->gt));
diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h
index e7a99cfd0abe..801a6b943f6e 100644
--- a/drivers/gpu/drm/xe/xe_lrc.h
+++ b/drivers/gpu/drm/xe/xe_lrc.h
@@ -89,6 +89,8 @@ 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);
+void xe_default_lrc_update_memirq_regs_with_address(struct xe_hw_engine *hwe);
+void xe_lrc_update_memirq_regs_with_address(struct xe_lrc *lrc, struct xe_hw_engine *hwe);
 
 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);
diff --git a/drivers/gpu/drm/xe/xe_sriov_vf.c b/drivers/gpu/drm/xe/xe_sriov_vf.c
index 0f0d1a97ae1d..0a9761b6ffb5 100644
--- a/drivers/gpu/drm/xe/xe_sriov_vf.c
+++ b/drivers/gpu/drm/xe/xe_sriov_vf.c
@@ -225,13 +225,24 @@ static int vf_post_migration_requery_guc(struct xe_device *xe)
        return ret;
 }
 
+static void xe_gt_default_lrcs_hwsp_rebase(struct xe_gt *gt)
+{
+       struct xe_hw_engine *hwe;
+       enum xe_hw_engine_id id;
+
+       for_each_hw_engine(hwe, gt, id)
+               xe_default_lrc_update_memirq_regs_with_address(hwe);
+}
</pre>
      </blockquote>
      <pre wrap="" class="moz-quote-pre">
Device-level functions live in xe_sriov_vf.c, GT-level functions live in
xe_gt_sriov_vf.c</pre>
    </blockquote>
    <p>ack</p>
    <p>-Tomasz<br>
    </p>
    <blockquote type="cite" cite="mid:jsmkqmq2m2uh2kee6dyxzklq3g3nm3htbskxf5zobpenchn3tm@mptopuryvmw3">
      <pre wrap="" class="moz-quote-pre">
Thanks,
-Michał

</pre>
      <blockquote type="cite">
        <pre wrap="" class="moz-quote-pre">+
 static void vf_post_migration_fixup_contexts(struct xe_device *xe)
 {
        struct xe_gt *gt;
        unsigned int id;
 
-       for_each_gt(gt, xe, id)
+       for_each_gt(gt, xe, id) {
+               xe_gt_default_lrcs_hwsp_rebase(gt);
                xe_guc_contexts_hwsp_rebase(&gt->uc.guc);
+       }
 }
 
 static void vf_post_migration_fixup_ctb(struct xe_device *xe)
-- 
2.25.1

</pre>
      </blockquote>
    </blockquote>
  </body>
</html>