32
32
33
33
#include "i915_drv.h"
34
34
#include "i915_reg.h"
35
+ #include "i915_irq.h"
35
36
#include "i915_trace.h"
36
37
37
38
/**
@@ -1935,6 +1936,12 @@ void intel_guc_submission_cancel_requests(struct intel_guc *guc)
1935
1936
1936
1937
/* GuC is blown away, drop all references to contexts */
1937
1938
xa_destroy (& guc -> context_lookup );
1939
+
1940
+ /*
1941
+ * Wedged GT won't respond to any TLB invalidation request. Simply
1942
+ * release all the blocked waiters.
1943
+ */
1944
+ wake_up_all_tlb_invalidate (guc );
1938
1945
}
1939
1946
1940
1947
void intel_guc_submission_reset_finish (struct intel_guc * guc )
@@ -4749,10 +4756,19 @@ static long must_wait_woken(struct wait_queue_entry *wq_entry, long timeout)
4749
4756
return timeout ;
4750
4757
}
4751
4758
4759
+ static bool intel_gt_is_enabled (const struct intel_gt * gt )
4760
+ {
4761
+ /* Check if GT is wedged or suspended */
4762
+ if (intel_gt_is_wedged (gt ) || !intel_irqs_enabled (gt -> i915 ))
4763
+ return false;
4764
+ return true;
4765
+ }
4766
+
4752
4767
static int guc_send_invalidate_tlb (struct intel_guc * guc ,
4753
4768
enum intel_guc_tlb_invalidation_type type )
4754
4769
{
4755
4770
struct intel_guc_tlb_wait _wq , * wq = & _wq ;
4771
+ struct intel_gt * gt = guc_to_gt (guc );
4756
4772
DEFINE_WAIT_FUNC (wait , woken_wake_function );
4757
4773
int err ;
4758
4774
u32 seqno ;
@@ -4766,6 +4782,13 @@ static int guc_send_invalidate_tlb(struct intel_guc *guc,
4766
4782
};
4767
4783
u32 size = ARRAY_SIZE (action );
4768
4784
4785
+ /*
4786
+ * Early guard against GT enablement. TLB invalidation should not be
4787
+ * attempted if the GT is disabled due to suspend/wedge.
4788
+ */
4789
+ if (!intel_gt_is_enabled (gt ))
4790
+ return - EINVAL ;
4791
+
4769
4792
init_waitqueue_head (& _wq .wq );
4770
4793
4771
4794
if (xa_alloc_cyclic_irq (& guc -> tlb_lookup , & seqno , wq ,
@@ -4798,7 +4821,14 @@ static int guc_send_invalidate_tlb(struct intel_guc *guc,
4798
4821
if (err )
4799
4822
goto out ;
4800
4823
4801
- if (!must_wait_woken (& wait , intel_guc_ct_max_queue_time_jiffies ())) {
4824
+ /*
4825
+ * Late guard against GT enablement. It is not an error for the TLB
4826
+ * invalidation to time out if the GT is disabled during the process
4827
+ * due to suspend/wedge. In fact, the TLB invalidation is cancelled
4828
+ * in this case.
4829
+ */
4830
+ if (!must_wait_woken (& wait , intel_guc_ct_max_queue_time_jiffies ()) &&
4831
+ intel_gt_is_enabled (gt )) {
4802
4832
guc_err (guc ,
4803
4833
"TLB invalidation response timed out for seqno %u\n" , seqno );
4804
4834
err = - ETIME ;
0 commit comments