@@ -1140,9 +1140,8 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
11401140
11411141 /* Check in case we rollback so far we wrap [size/2] */
11421142 if (intel_ring_direction (rq -> ring ,
1143- intel_ring_wrap (rq -> ring ,
1144- rq -> tail ),
1145- rq -> ring -> tail ) > 0 )
1143+ rq -> tail ,
1144+ rq -> ring -> tail + 8 ) > 0 )
11461145 rq -> context -> lrc .desc |= CTX_DESC_FORCE_RESTORE ;
11471146
11481147 active = rq ;
@@ -2464,7 +2463,7 @@ cancel_port_requests(struct intel_engine_execlists * const execlists)
24642463}
24652464
24662465static inline void
2467- invalidate_csb_entries (const u32 * first , const u32 * last )
2466+ invalidate_csb_entries (const u64 * first , const u64 * last )
24682467{
24692468 clflush ((void * )first );
24702469 clflush ((void * )last );
@@ -2496,14 +2495,25 @@ invalidate_csb_entries(const u32 *first, const u32 *last)
24962495 * bits 47-57: sw context id of the lrc the GT switched away from
24972496 * bits 58-63: sw counter of the lrc the GT switched away from
24982497 */
2499- static inline bool
2500- gen12_csb_parse (const struct intel_engine_execlists * execlists , const u32 * csb )
2501- {
2502- u32 lower_dw = csb [0 ];
2503- u32 upper_dw = csb [1 ];
2504- bool ctx_to_valid = GEN12_CSB_CTX_VALID (lower_dw );
2505- bool ctx_away_valid = GEN12_CSB_CTX_VALID (upper_dw );
2506- bool new_queue = lower_dw & GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE ;
2498+ static inline bool gen12_csb_parse (const u64 * csb )
2499+ {
2500+ bool ctx_away_valid ;
2501+ bool new_queue ;
2502+ u64 entry ;
2503+
2504+ /* HSD#22011248461 */
2505+ entry = READ_ONCE (* csb );
2506+ if (unlikely (entry == -1 )) {
2507+ preempt_disable ();
2508+ if (wait_for_atomic_us ((entry = READ_ONCE (* csb )) != -1 , 50 ))
2509+ GEM_WARN_ON ("50us CSB timeout" );
2510+ preempt_enable ();
2511+ }
2512+ WRITE_ONCE (* (u64 * )csb , -1 );
2513+
2514+ ctx_away_valid = GEN12_CSB_CTX_VALID (upper_32_bits (entry ));
2515+ new_queue =
2516+ lower_32_bits (entry ) & GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE ;
25072517
25082518 /*
25092519 * The context switch detail is not guaranteed to be 5 when a preemption
@@ -2513,7 +2523,7 @@ gen12_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
25132523 * would require some extra handling, but we don't support that.
25142524 */
25152525 if (!ctx_away_valid || new_queue ) {
2516- GEM_BUG_ON (!ctx_to_valid );
2526+ GEM_BUG_ON (!GEN12_CSB_CTX_VALID ( lower_32_bits ( entry )) );
25172527 return true;
25182528 }
25192529
@@ -2522,20 +2532,19 @@ gen12_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
25222532 * context switch on an unsuccessful wait instruction since we always
25232533 * use polling mode.
25242534 */
2525- GEM_BUG_ON (GEN12_CTX_SWITCH_DETAIL (upper_dw ));
2535+ GEM_BUG_ON (GEN12_CTX_SWITCH_DETAIL (upper_32_bits ( entry ) ));
25262536 return false;
25272537}
25282538
2529- static inline bool
2530- gen8_csb_parse (const struct intel_engine_execlists * execlists , const u32 * csb )
2539+ static inline bool gen8_csb_parse (const u64 * csb )
25312540{
25322541 return * csb & (GEN8_CTX_STATUS_IDLE_ACTIVE | GEN8_CTX_STATUS_PREEMPTED );
25332542}
25342543
25352544static void process_csb (struct intel_engine_cs * engine )
25362545{
25372546 struct intel_engine_execlists * const execlists = & engine -> execlists ;
2538- const u32 * const buf = execlists -> csb_status ;
2547+ const u64 * const buf = execlists -> csb_status ;
25392548 const u8 num_entries = execlists -> csb_size ;
25402549 u8 head , tail ;
25412550
@@ -2616,12 +2625,14 @@ static void process_csb(struct intel_engine_cs *engine)
26162625 */
26172626
26182627 ENGINE_TRACE (engine , "csb[%d]: status=0x%08x:0x%08x\n" ,
2619- head , buf [2 * head + 0 ], buf [2 * head + 1 ]);
2628+ head ,
2629+ upper_32_bits (buf [head ]),
2630+ lower_32_bits (buf [head ]));
26202631
26212632 if (INTEL_GEN (engine -> i915 ) >= 12 )
2622- promote = gen12_csb_parse (execlists , buf + 2 * head );
2633+ promote = gen12_csb_parse (buf + head );
26232634 else
2624- promote = gen8_csb_parse (execlists , buf + 2 * head );
2635+ promote = gen8_csb_parse (buf + head );
26252636 if (promote ) {
26262637 struct i915_request * const * old = execlists -> active ;
26272638
@@ -2649,6 +2660,9 @@ static void process_csb(struct intel_engine_cs *engine)
26492660 smp_wmb (); /* complete the seqlock */
26502661 WRITE_ONCE (execlists -> active , execlists -> inflight );
26512662
2663+ /* XXX Magic delay for tgl */
2664+ ENGINE_POSTING_READ (engine , RING_CONTEXT_STATUS_PTR );
2665+
26522666 WRITE_ONCE (execlists -> pending [0 ], NULL );
26532667 } else {
26542668 if (GEM_WARN_ON (!* execlists -> active )) {
@@ -4005,6 +4019,8 @@ static void reset_csb_pointers(struct intel_engine_cs *engine)
40054019 WRITE_ONCE (* execlists -> csb_write , reset_value );
40064020 wmb (); /* Make sure this is visible to HW (paranoia?) */
40074021
4022+ /* Check that the GPU does indeed update the CSB entries! */
4023+ memset (execlists -> csb_status , -1 , (reset_value + 1 ) * sizeof (u64 ));
40084024 invalidate_csb_entries (& execlists -> csb_status [0 ],
40094025 & execlists -> csb_status [reset_value ]);
40104026
@@ -5157,7 +5173,7 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine)
51575173 }
51585174
51595175 execlists -> csb_status =
5160- & engine -> status_page .addr [I915_HWS_CSB_BUF0_INDEX ];
5176+ ( u64 * ) & engine -> status_page .addr [I915_HWS_CSB_BUF0_INDEX ];
51615177
51625178 execlists -> csb_write =
51635179 & engine -> status_page .addr [intel_hws_csb_write_index (i915 )];
0 commit comments