Home | History | Annotate | Line # | Download | only in gt
      1  1.1  riastrad /*	$NetBSD: selftest_reset.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad // SPDX-License-Identifier: MIT
      4  1.1  riastrad /*
      5  1.1  riastrad  * Copyright  2018 Intel Corporation
      6  1.1  riastrad  */
      7  1.1  riastrad 
      8  1.1  riastrad #include <sys/cdefs.h>
      9  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: selftest_reset.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $");
     10  1.1  riastrad 
     11  1.1  riastrad #include "i915_selftest.h"
     12  1.1  riastrad #include "selftests/igt_reset.h"
     13  1.1  riastrad #include "selftests/igt_atomic.h"
     14  1.1  riastrad 
     15  1.1  riastrad static int igt_global_reset(void *arg)
     16  1.1  riastrad {
     17  1.1  riastrad 	struct intel_gt *gt = arg;
     18  1.1  riastrad 	unsigned int reset_count;
     19  1.1  riastrad 	intel_wakeref_t wakeref;
     20  1.1  riastrad 	int err = 0;
     21  1.1  riastrad 
     22  1.1  riastrad 	/* Check that we can issue a global GPU reset */
     23  1.1  riastrad 
     24  1.1  riastrad 	igt_global_reset_lock(gt);
     25  1.1  riastrad 	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
     26  1.1  riastrad 
     27  1.1  riastrad 	reset_count = i915_reset_count(&gt->i915->gpu_error);
     28  1.1  riastrad 
     29  1.1  riastrad 	intel_gt_reset(gt, ALL_ENGINES, NULL);
     30  1.1  riastrad 
     31  1.1  riastrad 	if (i915_reset_count(&gt->i915->gpu_error) == reset_count) {
     32  1.1  riastrad 		pr_err("No GPU reset recorded!\n");
     33  1.1  riastrad 		err = -EINVAL;
     34  1.1  riastrad 	}
     35  1.1  riastrad 
     36  1.1  riastrad 	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
     37  1.1  riastrad 	igt_global_reset_unlock(gt);
     38  1.1  riastrad 
     39  1.1  riastrad 	if (intel_gt_is_wedged(gt))
     40  1.1  riastrad 		err = -EIO;
     41  1.1  riastrad 
     42  1.1  riastrad 	return err;
     43  1.1  riastrad }
     44  1.1  riastrad 
     45  1.1  riastrad static int igt_wedged_reset(void *arg)
     46  1.1  riastrad {
     47  1.1  riastrad 	struct intel_gt *gt = arg;
     48  1.1  riastrad 	intel_wakeref_t wakeref;
     49  1.1  riastrad 
     50  1.1  riastrad 	/* Check that we can recover a wedged device with a GPU reset */
     51  1.1  riastrad 
     52  1.1  riastrad 	igt_global_reset_lock(gt);
     53  1.1  riastrad 	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
     54  1.1  riastrad 
     55  1.1  riastrad 	intel_gt_set_wedged(gt);
     56  1.1  riastrad 
     57  1.1  riastrad 	GEM_BUG_ON(!intel_gt_is_wedged(gt));
     58  1.1  riastrad 	intel_gt_reset(gt, ALL_ENGINES, NULL);
     59  1.1  riastrad 
     60  1.1  riastrad 	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
     61  1.1  riastrad 	igt_global_reset_unlock(gt);
     62  1.1  riastrad 
     63  1.1  riastrad 	return intel_gt_is_wedged(gt) ? -EIO : 0;
     64  1.1  riastrad }
     65  1.1  riastrad 
     66  1.1  riastrad static int igt_atomic_reset(void *arg)
     67  1.1  riastrad {
     68  1.1  riastrad 	struct intel_gt *gt = arg;
     69  1.1  riastrad 	const typeof(*igt_atomic_phases) *p;
     70  1.1  riastrad 	int err = 0;
     71  1.1  riastrad 
     72  1.1  riastrad 	/* Check that the resets are usable from atomic context */
     73  1.1  riastrad 
     74  1.1  riastrad 	intel_gt_pm_get(gt);
     75  1.1  riastrad 	igt_global_reset_lock(gt);
     76  1.1  riastrad 
     77  1.1  riastrad 	/* Flush any requests before we get started and check basics */
     78  1.1  riastrad 	if (!igt_force_reset(gt))
     79  1.1  riastrad 		goto unlock;
     80  1.1  riastrad 
     81  1.1  riastrad 	for (p = igt_atomic_phases; p->name; p++) {
     82  1.1  riastrad 		intel_engine_mask_t awake;
     83  1.1  riastrad 
     84  1.1  riastrad 		GEM_TRACE("__intel_gt_reset under %s\n", p->name);
     85  1.1  riastrad 
     86  1.1  riastrad 		awake = reset_prepare(gt);
     87  1.1  riastrad 		p->critical_section_begin();
     88  1.1  riastrad 
     89  1.1  riastrad 		err = __intel_gt_reset(gt, ALL_ENGINES);
     90  1.1  riastrad 
     91  1.1  riastrad 		p->critical_section_end();
     92  1.1  riastrad 		reset_finish(gt, awake);
     93  1.1  riastrad 
     94  1.1  riastrad 		if (err) {
     95  1.1  riastrad 			pr_err("__intel_gt_reset failed under %s\n", p->name);
     96  1.1  riastrad 			break;
     97  1.1  riastrad 		}
     98  1.1  riastrad 	}
     99  1.1  riastrad 
    100  1.1  riastrad 	/* As we poke around the guts, do a full reset before continuing. */
    101  1.1  riastrad 	igt_force_reset(gt);
    102  1.1  riastrad 
    103  1.1  riastrad unlock:
    104  1.1  riastrad 	igt_global_reset_unlock(gt);
    105  1.1  riastrad 	intel_gt_pm_put(gt);
    106  1.1  riastrad 
    107  1.1  riastrad 	return err;
    108  1.1  riastrad }
    109  1.1  riastrad 
    110  1.1  riastrad static int igt_atomic_engine_reset(void *arg)
    111  1.1  riastrad {
    112  1.1  riastrad 	struct intel_gt *gt = arg;
    113  1.1  riastrad 	const typeof(*igt_atomic_phases) *p;
    114  1.1  riastrad 	struct intel_engine_cs *engine;
    115  1.1  riastrad 	enum intel_engine_id id;
    116  1.1  riastrad 	int err = 0;
    117  1.1  riastrad 
    118  1.1  riastrad 	/* Check that the resets are usable from atomic context */
    119  1.1  riastrad 
    120  1.1  riastrad 	if (!intel_has_reset_engine(gt))
    121  1.1  riastrad 		return 0;
    122  1.1  riastrad 
    123  1.1  riastrad 	if (USES_GUC_SUBMISSION(gt->i915))
    124  1.1  riastrad 		return 0;
    125  1.1  riastrad 
    126  1.1  riastrad 	intel_gt_pm_get(gt);
    127  1.1  riastrad 	igt_global_reset_lock(gt);
    128  1.1  riastrad 
    129  1.1  riastrad 	/* Flush any requests before we get started and check basics */
    130  1.1  riastrad 	if (!igt_force_reset(gt))
    131  1.1  riastrad 		goto out_unlock;
    132  1.1  riastrad 
    133  1.1  riastrad 	for_each_engine(engine, gt, id) {
    134  1.1  riastrad 		tasklet_disable(&engine->execlists.tasklet);
    135  1.1  riastrad 		intel_engine_pm_get(engine);
    136  1.1  riastrad 
    137  1.1  riastrad 		for (p = igt_atomic_phases; p->name; p++) {
    138  1.1  riastrad 			GEM_TRACE("intel_engine_reset(%s) under %s\n",
    139  1.1  riastrad 				  engine->name, p->name);
    140  1.1  riastrad 
    141  1.1  riastrad 			p->critical_section_begin();
    142  1.1  riastrad 			err = intel_engine_reset(engine, NULL);
    143  1.1  riastrad 			p->critical_section_end();
    144  1.1  riastrad 
    145  1.1  riastrad 			if (err) {
    146  1.1  riastrad 				pr_err("intel_engine_reset(%s) failed under %s\n",
    147  1.1  riastrad 				       engine->name, p->name);
    148  1.1  riastrad 				break;
    149  1.1  riastrad 			}
    150  1.1  riastrad 		}
    151  1.1  riastrad 
    152  1.1  riastrad 		intel_engine_pm_put(engine);
    153  1.1  riastrad 		tasklet_enable(&engine->execlists.tasklet);
    154  1.1  riastrad 		if (err)
    155  1.1  riastrad 			break;
    156  1.1  riastrad 	}
    157  1.1  riastrad 
    158  1.1  riastrad 	/* As we poke around the guts, do a full reset before continuing. */
    159  1.1  riastrad 	igt_force_reset(gt);
    160  1.1  riastrad 
    161  1.1  riastrad out_unlock:
    162  1.1  riastrad 	igt_global_reset_unlock(gt);
    163  1.1  riastrad 	intel_gt_pm_put(gt);
    164  1.1  riastrad 
    165  1.1  riastrad 	return err;
    166  1.1  riastrad }
    167  1.1  riastrad 
    168  1.1  riastrad int intel_reset_live_selftests(struct drm_i915_private *i915)
    169  1.1  riastrad {
    170  1.1  riastrad 	static const struct i915_subtest tests[] = {
    171  1.1  riastrad 		SUBTEST(igt_global_reset), /* attempt to recover GPU first */
    172  1.1  riastrad 		SUBTEST(igt_wedged_reset),
    173  1.1  riastrad 		SUBTEST(igt_atomic_reset),
    174  1.1  riastrad 		SUBTEST(igt_atomic_engine_reset),
    175  1.1  riastrad 	};
    176  1.1  riastrad 	struct intel_gt *gt = &i915->gt;
    177  1.1  riastrad 
    178  1.1  riastrad 	if (!intel_has_gpu_reset(gt))
    179  1.1  riastrad 		return 0;
    180  1.1  riastrad 
    181  1.1  riastrad 	if (intel_gt_is_wedged(gt))
    182  1.1  riastrad 		return -EIO; /* we're long past hope of a successful reset */
    183  1.1  riastrad 
    184  1.1  riastrad 	return intel_gt_live_subtests(tests, gt);
    185  1.1  riastrad }
    186