@@ -256,14 +256,64 @@ static ssize_t wedged_mode_show(struct file *f, char __user *ubuf,
256256 return simple_read_from_buffer (ubuf , size , pos , buf , len );
257257}
258258
259+ static int __wedged_mode_set_reset_policy (struct xe_gt * gt , enum xe_wedged_mode mode )
260+ {
261+ bool enable_engine_reset ;
262+ int ret ;
263+
264+ enable_engine_reset = (mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET );
265+ ret = xe_guc_ads_scheduler_policy_toggle_reset (& gt -> uc .guc .ads ,
266+ enable_engine_reset );
267+ if (ret )
268+ xe_gt_err (gt , "Failed to update GuC ADS scheduler policy (%pe)\n" , ERR_PTR (ret ));
269+
270+ return ret ;
271+ }
272+
273+ static int wedged_mode_set_reset_policy (struct xe_device * xe , enum xe_wedged_mode mode )
274+ {
275+ struct xe_gt * gt ;
276+ int ret ;
277+ u8 id ;
278+
279+ guard (xe_pm_runtime )(xe );
280+ for_each_gt (gt , xe , id ) {
281+ ret = __wedged_mode_set_reset_policy (gt , mode );
282+ if (ret ) {
283+ if (id > 0 ) {
284+ xe -> wedged .inconsistent_reset = true;
285+ drm_err (& xe -> drm , "Inconsistent reset policy state between GTs\n" );
286+ }
287+ return ret ;
288+ }
289+ }
290+
291+ xe -> wedged .inconsistent_reset = false;
292+
293+ return 0 ;
294+ }
295+
296+ static bool wedged_mode_needs_policy_update (struct xe_device * xe , enum xe_wedged_mode mode )
297+ {
298+ if (xe -> wedged .inconsistent_reset )
299+ return true;
300+
301+ if (xe -> wedged .mode == mode )
302+ return false;
303+
304+ if (xe -> wedged .mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET ||
305+ mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET )
306+ return true;
307+
308+ return false;
309+ }
310+
259311static ssize_t wedged_mode_set (struct file * f , const char __user * ubuf ,
260312 size_t size , loff_t * pos )
261313{
262314 struct xe_device * xe = file_inode (f )-> i_private ;
263- struct xe_gt * gt ;
264315 u32 wedged_mode ;
265316 ssize_t ret ;
266- u8 id ;
267317
268318 ret = kstrtouint_from_user (ubuf , size , 0 , & wedged_mode );
269319 if (ret )
@@ -272,22 +322,14 @@ static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf,
272322 if (wedged_mode > 2 )
273323 return - EINVAL ;
274324
275- if (xe -> wedged .mode == wedged_mode )
276- return size ;
325+ if (wedged_mode_needs_policy_update (xe , wedged_mode )) {
326+ ret = wedged_mode_set_reset_policy (xe , wedged_mode );
327+ if (ret )
328+ return ret ;
329+ }
277330
278331 xe -> wedged .mode = wedged_mode ;
279332
280- xe_pm_runtime_get (xe );
281- for_each_gt (gt , xe , id ) {
282- ret = xe_guc_ads_scheduler_policy_toggle_reset (& gt -> uc .guc .ads );
283- if (ret ) {
284- xe_gt_err (gt , "Failed to update GuC ADS scheduler policy. GuC may still cause engine reset even with wedged_mode=2\n" );
285- xe_pm_runtime_put (xe );
286- return - EIO ;
287- }
288- }
289- xe_pm_runtime_put (xe );
290-
291333 return size ;
292334}
293335
0 commit comments