Skip to content

Commit 2cb38bb

Browse files
committed
drm/xe: Allow to trigger GT resets using debugfs writes
Today we allow to trigger GT resest by reading dedicated debugfs files "force_reset" and "force_reset_sync" that we are exposing using drm_info_list[] and drm_debugfs_create_files(). To avoid triggering potentially disruptive actions during otherwise "safe" read operations, expose those two attributes using debugfs function where we can specify file permissions and provide custom "write" handler to trigger the GT resets also from there. This step would allow us to drop triggering GT resets during read operations, which we leave just to give users more time to switch. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://lore.kernel.org/r/20250519200914.216-1-michal.wajdeczko@intel.com
1 parent 22eba3b commit 2cb38bb

File tree

1 file changed

+76
-20
lines changed

1 file changed

+76
-20
lines changed

drivers/gpu/drm/xe/xe_gt_debugfs.c

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,24 +122,6 @@ static int powergate_info(struct xe_gt *gt, struct drm_printer *p)
122122
return ret;
123123
}
124124

125-
static int force_reset(struct xe_gt *gt, struct drm_printer *p)
126-
{
127-
xe_pm_runtime_get(gt_to_xe(gt));
128-
xe_gt_reset_async(gt);
129-
xe_pm_runtime_put(gt_to_xe(gt));
130-
131-
return 0;
132-
}
133-
134-
static int force_reset_sync(struct xe_gt *gt, struct drm_printer *p)
135-
{
136-
xe_pm_runtime_get(gt_to_xe(gt));
137-
xe_gt_reset(gt);
138-
xe_pm_runtime_put(gt_to_xe(gt));
139-
140-
return 0;
141-
}
142-
143125
static int sa_info(struct xe_gt *gt, struct drm_printer *p)
144126
{
145127
struct xe_tile *tile = gt_to_tile(gt);
@@ -306,8 +288,6 @@ static int hwconfig(struct xe_gt *gt, struct drm_printer *p)
306288
* - without access to the PF specific data
307289
*/
308290
static const struct drm_info_list vf_safe_debugfs_list[] = {
309-
{"force_reset", .show = xe_gt_debugfs_simple_show, .data = force_reset},
310-
{"force_reset_sync", .show = xe_gt_debugfs_simple_show, .data = force_reset_sync},
311291
{"sa_info", .show = xe_gt_debugfs_simple_show, .data = sa_info},
312292
{"topology", .show = xe_gt_debugfs_simple_show, .data = topology},
313293
{"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt},
@@ -332,6 +312,78 @@ static const struct drm_info_list pf_only_debugfs_list[] = {
332312
{"steering", .show = xe_gt_debugfs_simple_show, .data = steering},
333313
};
334314

315+
static ssize_t write_to_gt_call(const char __user *userbuf, size_t count, loff_t *ppos,
316+
void (*call)(struct xe_gt *), struct xe_gt *gt)
317+
{
318+
bool yes;
319+
int ret;
320+
321+
if (*ppos)
322+
return -EINVAL;
323+
ret = kstrtobool_from_user(userbuf, count, &yes);
324+
if (ret < 0)
325+
return ret;
326+
if (yes)
327+
call(gt);
328+
return count;
329+
}
330+
331+
static void force_reset(struct xe_gt *gt)
332+
{
333+
struct xe_device *xe = gt_to_xe(gt);
334+
335+
xe_pm_runtime_get(xe);
336+
xe_gt_reset_async(gt);
337+
xe_pm_runtime_put(xe);
338+
}
339+
340+
static ssize_t force_reset_write(struct file *file,
341+
const char __user *userbuf,
342+
size_t count, loff_t *ppos)
343+
{
344+
struct seq_file *s = file->private_data;
345+
struct xe_gt *gt = s->private;
346+
347+
return write_to_gt_call(userbuf, count, ppos, force_reset, gt);
348+
}
349+
350+
static int force_reset_show(struct seq_file *s, void *unused)
351+
{
352+
struct xe_gt *gt = s->private;
353+
354+
force_reset(gt); /* to be deprecated! */
355+
return 0;
356+
}
357+
DEFINE_SHOW_STORE_ATTRIBUTE(force_reset);
358+
359+
static void force_reset_sync(struct xe_gt *gt)
360+
{
361+
struct xe_device *xe = gt_to_xe(gt);
362+
363+
xe_pm_runtime_get(xe);
364+
xe_gt_reset(gt);
365+
xe_pm_runtime_put(xe);
366+
}
367+
368+
static ssize_t force_reset_sync_write(struct file *file,
369+
const char __user *userbuf,
370+
size_t count, loff_t *ppos)
371+
{
372+
struct seq_file *s = file->private_data;
373+
struct xe_gt *gt = s->private;
374+
375+
return write_to_gt_call(userbuf, count, ppos, force_reset_sync, gt);
376+
}
377+
378+
static int force_reset_sync_show(struct seq_file *s, void *unused)
379+
{
380+
struct xe_gt *gt = s->private;
381+
382+
force_reset_sync(gt); /* to be deprecated! */
383+
return 0;
384+
}
385+
DEFINE_SHOW_STORE_ATTRIBUTE(force_reset_sync);
386+
335387
void xe_gt_debugfs_register(struct xe_gt *gt)
336388
{
337389
struct xe_device *xe = gt_to_xe(gt);
@@ -355,6 +407,10 @@ void xe_gt_debugfs_register(struct xe_gt *gt)
355407
*/
356408
root->d_inode->i_private = gt;
357409

410+
/* VF safe */
411+
debugfs_create_file("force_reset", 0600, root, gt, &force_reset_fops);
412+
debugfs_create_file("force_reset_sync", 0600, root, gt, &force_reset_sync_fops);
413+
358414
drm_debugfs_create_files(vf_safe_debugfs_list,
359415
ARRAY_SIZE(vf_safe_debugfs_list),
360416
root, minor);

0 commit comments

Comments
 (0)