drm/i915: Get meteorlake graphics working#418
Conversation
|
This patch allows me to use DRI in X and I've also successfully started sway on meteorlake. However, on my first try plasma became unresponsive not long after I started firefox. I can repeat the issue. |
I did apply that patch. I've also just now tried the other one, same issue. I've also had a panic which I couldn't read because of the DRM screen, and for some reason it didn't write to /var/crash. I know it's a panic though because instead of forcing the power off I just typed reboot and it did it, this implies the debugger prompt. |
|
You should be able to get auto crash dumps with if that helps capture the panic. As for the GuC communication messages, does that happen every time you use plasma? I've only managed to see it the one time. Are any other desktops impacted? |
|
IIRC it is not enough to set PG_M. There was "lkpi_vmf_insert_pfn_prot_locked: page rename failed: page is mapped" console mesage appeared too often to lock OS in some cases. |
|
I haven't observed that one myself so will be interesting if anyone else runs into it |
|
That looks quite interesting! As I am very new to FreeBSD but managed to compile the driver already I will give it a try, too. But I am unsure about compiling against R15. I wasn't able to compile the master nor drm_v6.10 branch due to missing dependencies in the system sources. Will try with tag drm_v6.9_1 then which compiled successful before and apply this pull request. Also https://reviews.freebsd.org/D55536 has been mentioned necessary to apply. So, I guess this will require to rebuild FreeBSD and to build the drm driver, right? Anything else I need to take care about? |
|
I had the chance to get closer to this. I built the kernel from freebsd-src main with applied patch D55536. Then I built the drm-kmod from this branch mtl. But, I couldn't get neither sway (wayland) nor xfce4 (Xorg) to run. Wayland still complained missing
See full Xorg.0.log attached. Anyway, system kept stable and no buggy output in tty anymore after loading the module. System info: ThinkPad T14 G5: |
|
Do you have |
Thx, I missed that one. But, I'm afraid to say, it didn't do the trick. Behavior is still the same. Neither wayland nor Xorg are able to start. Error messages are also still the same. Maybe I have missed something else. I will start over applying your changes to the latest drm-kmod. Some other changes have been there in the meantime. Keeping you updated. |
Do not use Intel driver with modern devices. It does not work. Use modesetting |
|
I could have seen this earlier. So not loading the module on boot but via kldload gave me the output, when loading the module manually later. See log attached. Seems firmware doesn't match kernel. I tried by updating gpu-firmware-kmod-intel-meteorlake but there wasn't any newer. |
|
We will need logs to see what's going wrong with your system. If you have gotten this MR to run properly then you definitely should not be seeing the intel_device_info error. I'd make sure you're installing things properly and the firmware pkg is installed as well, check for any dmesg errors about firmware failing to load, etc. Looks like you need to build your gpu-firmware-kmod for your new kernel: |
|
Will the fixes mentioned here allow me to do this: mpv --vo=gpu-next --gpu-api=opengl --hwdec=no video.mkv ? Will gpu-next be usable on a Meteor Lake iGPU if these fixes are applied? |
|
It works on my Framework Laptop. Thanks! |
|
I don't get it. I did also build the drm-kmod-firmware to match the installed kernel. Now, loading the firmware by the driver succeeded, but the module instantly traces with:
So what are the steps to get this to work? I assumed:
What am I missing? |
|
What freebsd kernel are you building? You should run the latest CURRENT and it will have everything already. Your panic sounds like you are missing commit "linuxkpi: Don't destroy the mutex in |
|
cc: @dumbbell |
|
i am currently running 16-Current (PkgBase from today), have build drm-kmod (master) and the corresponding: i tried applying the patch from @amshafer on top of drm-kmod master, |
|
@dasTor: The panic you shared should be fixed in my |
|
@dumbbell i did build the kernel from your |
|
@dasTor: I’m surprised. This code is not hardware dependent and will behave the same everywhere. The only similar report was because of an unclean build. Can you try to refresh freebsd-src and drm-kmod branches and try to compile both from scratch? For the record, all DRM-6.12-related linuxkpi patches were pushed to both freebsd-src main and stable/15 branches. |
Bump from drm_v6.9_1 to master HEAD a72c05b22dc21e to pick up Linux 6.12-based DRM drivers and Meteor Lake / Arrow Lake support. Includes: - Reorder kconfig.mk / bsd.kmod.mk includes in drm/Makefile and i915/Makefile so generated headers (device_if.h, vnode_if.h, ...) resolve and so MKCONFIG-gated SRCS+= blocks (drm_debugfs.c, etc.) are not silently dropped. Without this, drm.ko links but is missing symbols like drm_debugfs_add_files at load time. - Suppress -Waddress-of-packed-member globally in i915 build. - Cherry-pick two commits from amshafer:mtl (PR freebsd/drm-kmod#418): initialize GMADR on Meteor Lake (a2ca1d5) and skip GT1 standalone media GT (0872ce4), without which i915 fails with "Enabling uc failed (-5)" / "declaring it wedged" on MTL. Tested on Lenovo X1 Carbon (Meteor Lake-P, PCI ID 0x7d45) with hw.i915kms.enable_guc=2: GuC firmware loads (mtl_guc_70.bin v70.53.0), GT0 initializes, /dev/dri/{card0,renderD128} are created.
That's the same trace I got, too. So, I am not alone anymore 😀 |
|
@dumbbell i updated current from pkgbase yesterday and did a clean rebuild of drm-kmod (master) |
Same here. Panic the same, just different line. Before updating the sources it's been 242, now 237:
|
|
@dasTor, @kyoshiro: Could you please try to set The GuC submission is disabled in your case ( I didn't read the code enough yet, but so far, I don't see where it would skip |
Also works with enable_guc=2 on Framework Laptop Intel Core Ultra. |
|
i am currently seeing the crashes again with drm-kmod master, this pull request and -current from saturday: does it makes sense to test with 15.1-rc and 6.12-lts branch? or are there linuxkpi patches missing in the |
I think it's something external but I'm trying to narrow down what. The changes in this MR seem sane |
|
@dasTor: There are no new linuxkpi changes from me in freebsd-src main branch that stable/15 doesn’t have. There could be changes from others however, I didn’t pay attention to that. I’m building this branch again, after updating freebsd-src to today’s main branch. I will set enabled_guc=2 too. |
Okay testing again with everything properly updated to the latest and I don't see this anymore, KDE working fine. I think the problem was an outdated gpu-firmware packages which I hadn't updated to match my new src checkout. I think this MR is in good shape to land at this point |
I think so too. I'm replying from my laptop running this branch. I'm going to merge it and we can continue to work on issues like the panic @dasTor gets or the computer not powering off with @dasTor: Quick question, how do you load i915kms? |
|
kldloading after boot |
Some recent GPUs require this to work (see freebsd#418). If we need to disable GuC for some GPUs, we can add them in `uc_expand_default_options()` in `drivers/gpu/drm/i915/gt/uc/intel_uc.c`. It will be better than disabling it for everyone, requiring some user to mess with an obscure setting in `/boot/loader.conf`. Sponsored by: The FreeBSD Foundation
... except that GuC submission is still disabled on FreeBSD by default. Some recent GPUs require this to work (see freebsd#418). If we need to disable GuC for some GPUs, we can add them in `uc_expand_default_options()` in `drivers/gpu/drm/i915/gt/uc/intel_uc.c`. It will be better than disabling it for everyone, requiring some user to mess with an obscure setting in `/boot/loader.conf`. As said at the beginning however, we still disable GuC submission by default on FreeBSD. The reason is that is often prevents a computer from powering off: the kernel stops everything, the display is turned off, but the power LED is on and the fans are audible. Sponsored by: The FreeBSD Foundation
|
kldload_master_current.txt.gz i really wish, modern gpus wouldn't consist of multiple separate chips that need some stupid binary blobs to work. |
|
Quick feedback, i went to 15.1-rc2 and drm-kmod branch 6.12-lts is loading and working, thx guys |
Bump from drm_v6.9_1 to master HEAD a72c05b22dc21e to pick up Linux 6.12-based DRM drivers and Meteor Lake / Arrow Lake support. Includes: - Reorder kconfig.mk / bsd.kmod.mk includes in drm/Makefile and i915/Makefile so generated headers (device_if.h, vnode_if.h, ...) resolve and so MKCONFIG-gated SRCS+= blocks (drm_debugfs.c, etc.) are not silently dropped. Without this, drm.ko links but is missing symbols like drm_debugfs_add_files at load time. - Suppress -Waddress-of-packed-member globally in i915 build. - Cherry-pick two commits from amshafer:mtl (PR freebsd/drm-kmod#418): initialize GMADR on Meteor Lake (a2ca1d5) and skip GT1 standalone media GT (0872ce4), without which i915 fails with "Enabling uc failed (-5)" / "declaring it wedged" on MTL. Tested on Lenovo X1 Carbon (Meteor Lake-P, PCI ID 0x7d45) with hw.i915kms.enable_guc=2: GuC firmware loads (mtl_guc_70.bin v70.53.0), GT0 initializes, /dev/dri/{card0,renderD128} are created.
|
With enable_guc=3, current drm-kmod master and drm-kmod-firmware master, Sway starts and mpv works, but after some use the system wedges with: This still happens with enable_psr=0, enable_dc=0, enable_fbc=0. |
|
I was surprised I didn't experience a kernel panic after setting the guc value to 1. I didn't yet experience a freeze or a hang after setting the value of 1, so, hopefully, this is a real solution to the problem. |
|
It turned out it wasn't a solution. I still experienced a hang. |
|
@JustAnotherHumanBeing kind of a long shot but can you apply the following and see if that helps? |
|
I didn't try your approach yet because two days ago, ChatGPT wrote a patch for me in an attempt to fix this issue. I rebooted after applying that patch and haven't yet experienced any GPU-related hangs or crashes. So maybe that patch did fix the issue. Here it is: diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
old mode 100644
new mode 100755
index 5cf3a516cc..7cee95d36b
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -44,6 +44,8 @@ static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)
#define CT_ERROR(_ct, _fmt, ...) \
guc_err(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__)
+#define CT_ERROR_RATELIMITED(_ct, _fmt, ...) \
+ guc_err_ratelimited(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__)
#ifdef CONFIG_DRM_I915_DEBUG_GUC
#define CT_DEBUG(_ct, _fmt, ...) \
guc_dbg(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__)
@@ -53,6 +55,13 @@ static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)
#define CT_PROBE_ERROR(_ct, _fmt, ...) \
guc_probe_error(ct_to_guc(ct), "CT: " _fmt, ##__VA_ARGS__)
+#define G2H_LEN_DW(f) ({ \
+ typeof(f) f_ = (f); \
+ FIELD_GET(INTEL_GUC_CT_SEND_G2H_DW_MASK, f_) ? \
+ FIELD_GET(INTEL_GUC_CT_SEND_G2H_DW_MASK, f_) + \
+ GUC_CTB_HXG_MSG_MIN_LEN : 0; \
+})
+
/**
* DOC: CTB Blob
*
@@ -132,6 +141,7 @@ long intel_guc_ct_max_queue_time_jiffies(void)
static void ct_receive_tasklet_func(struct tasklet_struct *t);
static void ct_incoming_request_worker_func(struct work_struct *w);
+static inline void g2h_release_space(struct intel_guc_ct *ct, u32 g2h_len_dw);
/**
* intel_guc_ct_init_early - Initialize CT state without requiring device access
@@ -348,6 +358,7 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
/* (re)initialize descriptors */
guc_ct_buffer_reset(&ct->ctbs.send);
guc_ct_buffer_reset(&ct->ctbs.recv);
+ memset(ct->requests.async, 0, sizeof(ct->requests.async));
/*
* Register both CT buffers starting with RECV buffer.
@@ -421,6 +432,78 @@ static void ct_track_lost_and_found(struct intel_guc_ct *ct, u32 fence, u32 acti
}
#endif
+static void ct_track_async_request(struct intel_guc_ct *ct,
+ u32 fence, const u32 *action,
+ u32 len, u32 flags)
+{
+ unsigned int n = fence % ARRAY_SIZE(ct->requests.async);
+ unsigned long irqflags;
+
+ if (!(flags & INTEL_GUC_CT_SEND_NB))
+ return;
+
+ spin_lock_irqsave(&ct->requests.lock, irqflags);
+ ct->requests.async[n].fence = fence;
+ ct->requests.async[n].action = action[0];
+ ct->requests.async[n].data0 = len > 1 ? action[1] : 0;
+ ct->requests.async[n].g2h_len_dw = G2H_LEN_DW(flags);
+ ct->requests.async[n].valid = true;
+ spin_unlock_irqrestore(&ct->requests.lock, irqflags);
+}
+
+static void ct_forget_async_request(struct intel_guc_ct *ct, u32 fence,
+ u32 g2h_len_dw)
+{
+ unsigned int n = fence % ARRAY_SIZE(ct->requests.async);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ct->requests.lock, flags);
+ if (ct->requests.async[n].valid &&
+ ct->requests.async[n].fence == fence &&
+ ct->requests.async[n].g2h_len_dw == g2h_len_dw)
+ ct->requests.async[n].valid = false;
+ spin_unlock_irqrestore(&ct->requests.lock, flags);
+}
+
+static bool ct_consume_async_response(struct intel_guc_ct *ct, u32 fence,
+ u32 hxg)
+{
+ unsigned int n = fence % ARRAY_SIZE(ct->requests.async);
+ u32 type = FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg);
+ u16 action;
+ u16 g2h_len_dw;
+ u32 data0;
+
+ lockdep_assert_held(&ct->requests.lock);
+
+ if (!ct->requests.async[n].valid ||
+ ct->requests.async[n].fence != fence)
+ return false;
+
+ action = ct->requests.async[n].action;
+ data0 = ct->requests.async[n].data0;
+ g2h_len_dw = ct->requests.async[n].g2h_len_dw;
+ ct->requests.async[n].valid = false;
+
+ if (g2h_len_dw)
+ g2h_release_space(ct, g2h_len_dw);
+
+ if (type == GUC_HXG_TYPE_RESPONSE_FAILURE) {
+ u32 hint = FIELD_GET(GUC_HXG_FAILURE_MSG_0_HINT, hxg);
+ u32 error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, hxg);
+
+ CT_ERROR_RATELIMITED(ct,
+ "Fast request %#04x data0 %#x failed: error %#x hint %u (fence %u, released %u G2H dw)\n",
+ action, data0, error, hint, fence, g2h_len_dw);
+ } else {
+ CT_ERROR_RATELIMITED(ct,
+ "Fast request %#04x data0 %#x returned unexpected response %#x (fence %u, released %u G2H dw)\n",
+ action, data0, hxg, fence, g2h_len_dw);
+ }
+
+ return true;
+}
+
static u32 ct_get_next_fence(struct intel_guc_ct *ct)
{
/* For now it's trivial */
@@ -496,6 +579,7 @@ static int ct_write(struct intel_guc_ct *ct,
ct_track_lost_and_found(ct, fence,
FIELD_GET(GUC_HXG_EVENT_MSG_0_ACTION, action[0]));
#endif
+ ct_track_async_request(ct, fence, action, len, flags);
/*
* make sure H2G buffer update and LRC tail update (if this triggering a
@@ -671,12 +755,6 @@ static int has_room_nb(struct intel_guc_ct *ct, u32 h2g_dw, u32 g2h_dw)
return 0;
}
-#define G2H_LEN_DW(f) ({ \
- typeof(f) f_ = (f); \
- FIELD_GET(INTEL_GUC_CT_SEND_G2H_DW_MASK, f_) ? \
- FIELD_GET(INTEL_GUC_CT_SEND_G2H_DW_MASK, f_) + \
- GUC_CTB_HXG_MSG_MIN_LEN : 0; \
-})
static int ct_send_nb(struct intel_guc_ct *ct,
const u32 *action,
u32 len,
@@ -1085,6 +1163,9 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
}
#endif
+ if (!found && ct_consume_async_response(ct, fence, hxg[0]))
+ found = true;
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x (fence %u, last %u)\n",
len, hxg[0], fence, ct->requests.last_fence);
@@ -1212,6 +1293,7 @@ static void ct_incoming_request_worker_func(struct work_struct *w)
static int ct_handle_event(struct intel_guc_ct *ct, struct ct_incoming_msg *request)
{
const u32 *hxg = &request->msg[GUC_CTB_MSG_MIN_LEN];
+ u32 fence = FIELD_GET(GUC_CTB_MSG_0_FENCE, request->msg[0]);
u32 action = FIELD_GET(GUC_HXG_EVENT_MSG_0_ACTION, hxg[0]);
unsigned long flags;
@@ -1227,6 +1309,7 @@ static int ct_handle_event(struct intel_guc_ct *ct, struct ct_incoming_msg *requ
case INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE:
case INTEL_GUC_ACTION_TLB_INVALIDATION_DONE:
g2h_release_space(ct, request->size);
+ ct_forget_async_request(ct, fence, request->size);
}
/*
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
old mode 100644
new mode 100755
index 2c4bb9a941..193dd60e7a
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
@@ -83,6 +83,14 @@ struct intel_guc_ct {
struct list_head incoming; /* incoming requests */
struct work_struct worker; /* handler for incoming requests */
+ struct {
+ u16 fence;
+ u16 action;
+ u16 g2h_len_dw;
+ u32 data0;
+ bool valid;
+ } async[SZ_256];
+
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
struct {
u16 fence;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
old mode 100644
new mode 100755
index 9df7927304..692f3e5c46
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
@@ -22,6 +22,9 @@ static bool __guc_rc_selected(struct intel_guc *guc)
if (!intel_guc_rc_is_supported(guc))
return false;
+ if (IS_METEORLAKE(guc_to_i915(guc)))
+ return false;
+
return guc->submission_selected;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h
old mode 100644
new mode 100755
index 57e86c3378..834d9b8801
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.h
@@ -17,7 +17,7 @@ static inline bool intel_guc_rc_is_supported(struct intel_guc *guc)
static inline bool intel_guc_rc_is_wanted(struct intel_guc *guc)
{
- return guc->submission_selected && intel_guc_rc_is_supported(guc);
+ return guc->rc_selected;
}
static inline bool intel_guc_rc_is_used(struct intel_guc *guc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
old mode 100644
new mode 100755
index 706fffca69..49101e4138
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -42,6 +42,9 @@ static bool __guc_slpc_selected(struct intel_guc *guc)
if (!intel_guc_slpc_is_supported(guc))
return false;
+ if (IS_METEORLAKE(guc_to_i915(guc)))
+ return false;
+
return guc->submission_selected;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
old mode 100644
new mode 100755
index 355a21eb48..8e611178fe
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -5114,6 +5114,37 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc,
if (unlikely(!ce))
return -EPROTO;
+ if (unlikely(context_destroyed(ce) && context_pending_disable(ce))) {
+ bool banned;
+
+ trace_intel_context_sched_done(ce);
+
+ /*
+ * The context is already being destroyed, so consume this late
+ * schedule-disable completion without unblocking new work on the
+ * context. Waking ce->guc_state.fences here can let requests run
+ * against a context that is no longer reusable.
+ */
+ intel_context_sched_disable_unpin(ce);
+
+ spin_lock_irqsave(&ce->guc_state.lock, flags);
+ banned = context_banned(ce);
+ clr_context_banned(ce);
+ clr_context_pending_disable(ce);
+ guc_blocked_fence_complete(ce);
+ spin_unlock_irqrestore(&ce->guc_state.lock, flags);
+
+ if (banned) {
+ guc_cancel_context_requests(ce);
+ intel_engine_signal_breadcrumbs(ce->engine);
+ }
+
+ decr_outstanding_submission_g2h(guc);
+ intel_context_put(ce);
+
+ return 0;
+ }
+
if (unlikely(context_destroyed(ce) ||
(!context_pending_enable(ce) &&
!context_pending_disable(ce)))) { |
|
The formatting has made that illegible and without any details as to what it does it's hard to draw conclusions from this. Can you please revert that and try what I sent? I believe what could be happening is we don't properly detect if we can sleep or not so we sleep when we shouldn't, and that causes issues with replies from the GuC properly arriving. |
|
I was wrong when I was thinking that ChatGPT-generated patch got rid of the problem. Even though, after installing the patch, I didn't experience issues for two days, a kernel panic occurred today, which is day 3. I have no idea why it didn't occur earlier than today. I wish I were not as much of a n00b as I actually am... Anyway... I got rid of this patch and tested your patch, amshafer. It didn't fix the issue. The plasma 6 GUI froze when I was running it and I saw these messages when I switched to the text console: "login: drmn0: [drm] ERROR GT0: GUC: CT: Unsolicited response message: len 1, data 0xe000 |
|
Now I am testing another ChatGPT-generated patch; hopefully, it's good: diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ed97984718..fc4ae43c1b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -396,6 +396,49 @@ static inline void set_context_guc_id_invalid(struct intel_context *ce)
ce->guc_id.id = GUC_INVALID_CONTEXT_ID;
}
+static void guc_log_context_sched_state(struct intel_guc *guc,
+ struct intel_context *ce,
+ u32 msg_ctx_id,
+ const char *reason)
+{
+ unsigned long flags;
+ u32 sched_state;
+ u8 prio;
+
+ spin_lock_irqsave(&ce->guc_state.lock, flags);
+ sched_state = ce->guc_state.sched_state;
+ prio = ce->guc_state.prio;
+ spin_unlock_irqrestore(&ce->guc_state.lock, flags);
+
+ guc_err(guc,
+ "%s: msg_ctx_id=%u ce=%p ce_guc_id=%u guc_id_ref=%d sched_state=0x%x "
+ "destroyed=%u pending_enable=%u pending_disable=%u enabled=%u "
+ "registered=%u banned=%u closed=%u blocked=%u prio=%u "
+ "pin_count=%d active_count=%u flags=0x%lx engine=%s ring=%p "
+ "state=%p timeline=%p lrc_reg_state=%p ops=%p\n",
+ reason,
+ msg_ctx_id,
+ ce,
+ ce->guc_id.id,
+ atomic_read(&ce->guc_id.ref),
+ sched_state,
+ !!(sched_state & SCHED_STATE_DESTROYED),
+ !!(sched_state & SCHED_STATE_PENDING_ENABLE),
+ !!(sched_state & SCHED_STATE_PENDING_DISABLE),
+ !!(sched_state & SCHED_STATE_ENABLED),
+ !!(sched_state & SCHED_STATE_REGISTERED),
+ !!(sched_state & SCHED_STATE_BANNED),
+ !!(sched_state & SCHED_STATE_CLOSED),
+ (sched_state & SCHED_STATE_BLOCKED_MASK) >>
+ SCHED_STATE_BLOCKED_SHIFT,
+ prio,
+ atomic_read(&ce->pin_count),
+ ce->active_count,
+ ce->flags,
+ ce->engine ? ce->engine->name : "(null)",
+ ce->ring, ce->state, ce->timeline, ce->lrc_reg_state, ce->ops);
+}
+
static inline struct intel_guc *ce_to_guc(struct intel_context *ce)
{
return gt_to_guc(ce->engine->gt);
@@ -2981,7 +3024,8 @@ static void guc_context_unpin(struct intel_context *ce)
unpin_guc_id(guc, ce);
lrc_unpin(ce);
- if (likely(!intel_context_is_barrier(ce)))
+ if (likely(!intel_context_is_barrier(ce)) &&
+ intel_engine_pm_is_awake(ce->engine))
intel_engine_pm_put_async(ce->engine);
}
@@ -3952,7 +3996,8 @@ static void guc_virtual_context_unpin(struct intel_context *ce)
lrc_unpin(ce);
for_each_engine_masked(engine, ce->engine->gt, mask, tmp)
- intel_engine_pm_put_async(engine);
+ if (intel_engine_pm_is_awake(engine))
+ intel_engine_pm_put_async(engine);
}
static void guc_virtual_context_enter(struct intel_context *ce)
@@ -4776,7 +4821,7 @@ int intel_guc_sched_disable_gucid_threshold_max(struct intel_guc *guc)
* operation. This matches the 30fps game-render + encode (real world) workload this
* knob was tested against.
*/
-#define SCHED_DISABLE_DELAY_MS 34
+#define SCHED_DISABLE_DELAY_MS 0
/*
* A threshold of 75% is a reasonable starting point considering that real world apps
@@ -5053,8 +5098,8 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc,
if (unlikely(context_destroyed(ce) ||
(!context_pending_enable(ce) &&
!context_pending_disable(ce)))) {
- guc_err(guc, "Bad context sched_state 0x%x, ctx_id %u\n",
- ce->guc_state.sched_state, ctx_id);
+ guc_log_context_sched_state(guc, ce, ctx_id,
+ "Bad schedule-done context state");
return -EPROTO;
}
diff --git a/kconfig.mk b/kconfig.mk
index d4aa682536..9f16b640f5 100644
--- a/kconfig.mk
+++ b/kconfig.mk
@@ -14,6 +14,9 @@ KCONFIG= DRM_AMDGPU_CIK \
DRM_I915_FORCE_PROBE='"*"' \
DRM_I915_REQUEST_TIMEOUT=20000 \
DRM_I915_CAPTURE_ERROR \
+ DRM_I915_DEBUG \
+ DRM_I915_DEBUG_MMIO \
+ DRM_I915_DEBUG_WAKEREF \
DRM_I915_USERFAULT_AUTOSUSPEND=250 \
DRM_I915_STOP_TIMEOUT=100 \
DRM_I915_PREEMPT_TIMEOUT=640 \ |
|
Now, a couple of hours later, with the patch I posted above, I still haven't run into the GUC-related 0x6 bug. In my loader.conf, I now have the line hw.i915kms.disable_power_well=0 . Hopefully, this combination is the "cure" for the bug. |
|
Because I continued not experiencing any problems, I started testing the patch that is almost the same as the original one, except that it doesn't have the diagnostics/debugging features. Here it is: --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c.orig 2026-06-23 18:59:54.781024000 -0400
+++ drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 2026-06-23 19:29:58.894820000 -0400
@@ -2981,7 +2981,7 @@
unpin_guc_id(guc, ce);
lrc_unpin(ce);
- if (likely(!intel_context_is_barrier(ce)))
+ if (likely(!intel_context_is_barrier(ce)) && intel_engine_pm_is_awake(ce->engine))
intel_engine_pm_put_async(ce->engine);
}
@@ -3952,6 +3952,7 @@
lrc_unpin(ce);
for_each_engine_masked(engine, ce->engine->gt, mask, tmp)
+ if (intel_engine_pm_is_awake(engine))
intel_engine_pm_put_async(engine);
}
@@ -4776,7 +4777,7 @@
* operation. This matches the 30fps game-render + encode (real world) workload this
* knob was tested against.
*/
-#define SCHED_DISABLE_DELAY_MS 34
+#define SCHED_DISABLE_DELAY_MS 0
/*
* A threshold of 75% is a reasonable starting point considering that real world appsGPU hangs came back after I started testing it, though they were not the "0x6" GUC errors. This result seems to suggest that the diagnostics/debugging thing of the original patch prevented some type of race issue, even though it was strictly a diagnostics/debugging thing. I added hw.i915kms.enable_dc=0 to loader.conf (while the hw.i915kms.disable_power_well=0 thing was still there), and after I did that, I haven't yet experienced any GPU hangs. I just have to repeat now what I said earlier: I hope neither the GPU hangs nor the 0x6 GUC error will return. |
|
I’m incredibly puzzled now. Yet another GPU hang occurred, but as soon as I added a diagnostic log that would record what happens during such hangs from now on, the hangs simply stopped occurring! This is so strange; it’s as if the logging capability itself stopped the hangs from happening. |
|
I finally figured out the cause of this intermittent GPU hang problem. It was triggered by ZFS ARC pressure. The reliable reproducer on my machine was:
With the default auto-sized ARC, launching Plasma after that would reliably produce a GPU hang. After capping ARC with |

These are a few fixes which get GuC based graphics working on meteorlake (and hopefully newer). This finally makes my dell precision 5690 laptop with Arc graphics usable. Details on each fix are in the commit descriptions. Tested with sway, plasma6 (x11), and xfce4.
You'll also want
D55525D55536 in order to prevent panics once we bump the GTT version to 4, which was an existing problem that mtl runs into. On mtl we must have GTT version 4 or else it falls back to the legacy mapping path which mtl does not support.This should fix #373
GuC is disabled by default for now, add
hw.i915kms.enable_guc="2"toloader.confto enable it.