1 | // SPDX-License-Identifier: MIT |
2 | /* |
3 | * Copyright © 2021 Intel Corporation |
4 | */ |
5 | |
6 | #include <linux/jiffies.h> |
7 | |
8 | //#include "gt/intel_engine_user.h" |
9 | #include "gt/intel_gt.h" |
10 | #include "i915_drv.h" |
11 | #include "i915_selftest.h" |
12 | |
13 | #include "selftests/intel_scheduler_helpers.h" |
14 | |
15 | #define REDUCED_TIMESLICE 5 |
16 | #define REDUCED_PREEMPT 10 |
17 | #define WAIT_FOR_RESET_TIME_MS 10000 |
18 | |
19 | struct intel_engine_cs *intel_selftest_find_any_engine(struct intel_gt *gt) |
20 | { |
21 | struct intel_engine_cs *engine; |
22 | enum intel_engine_id id; |
23 | |
24 | for_each_engine(engine, gt, id) |
25 | return engine; |
26 | |
27 | pr_err("No valid engine found!\n" ); |
28 | return NULL; |
29 | } |
30 | |
31 | int intel_selftest_modify_policy(struct intel_engine_cs *engine, |
32 | struct intel_selftest_saved_policy *saved, |
33 | enum selftest_scheduler_modify modify_type) |
34 | { |
35 | int err; |
36 | |
37 | saved->reset = engine->i915->params.reset; |
38 | saved->flags = engine->flags; |
39 | saved->timeslice = engine->props.timeslice_duration_ms; |
40 | saved->preempt_timeout = engine->props.preempt_timeout_ms; |
41 | |
42 | switch (modify_type) { |
43 | case SELFTEST_SCHEDULER_MODIFY_FAST_RESET: |
44 | /* |
45 | * Enable force pre-emption on time slice expiration |
46 | * together with engine reset on pre-emption timeout. |
47 | * This is required to make the GuC notice and reset |
48 | * the single hanging context. |
49 | * Also, reduce the preemption timeout to something |
50 | * small to speed the test up. |
51 | */ |
52 | engine->i915->params.reset = 2; |
53 | engine->flags |= I915_ENGINE_WANT_FORCED_PREEMPTION; |
54 | engine->props.timeslice_duration_ms = REDUCED_TIMESLICE; |
55 | engine->props.preempt_timeout_ms = REDUCED_PREEMPT; |
56 | break; |
57 | |
58 | case SELFTEST_SCHEDULER_MODIFY_NO_HANGCHECK: |
59 | engine->props.preempt_timeout_ms = 0; |
60 | break; |
61 | |
62 | default: |
63 | pr_err("Invalid scheduler policy modification type: %d!\n" , modify_type); |
64 | return -EINVAL; |
65 | } |
66 | |
67 | if (!intel_engine_uses_guc(engine)) |
68 | return 0; |
69 | |
70 | err = intel_guc_global_policies_update(guc: &engine->gt->uc.guc); |
71 | if (err) |
72 | intel_selftest_restore_policy(engine, saved); |
73 | |
74 | return err; |
75 | } |
76 | |
77 | int intel_selftest_restore_policy(struct intel_engine_cs *engine, |
78 | struct intel_selftest_saved_policy *saved) |
79 | { |
80 | /* Restore the original policies */ |
81 | engine->i915->params.reset = saved->reset; |
82 | engine->flags = saved->flags; |
83 | engine->props.timeslice_duration_ms = saved->timeslice; |
84 | engine->props.preempt_timeout_ms = saved->preempt_timeout; |
85 | |
86 | if (!intel_engine_uses_guc(engine)) |
87 | return 0; |
88 | |
89 | return intel_guc_global_policies_update(guc: &engine->gt->uc.guc); |
90 | } |
91 | |
92 | int intel_selftest_wait_for_rq(struct i915_request *rq) |
93 | { |
94 | long ret; |
95 | |
96 | ret = i915_request_wait(rq, flags: 0, timeout: msecs_to_jiffies(WAIT_FOR_RESET_TIME_MS)); |
97 | if (ret < 0) |
98 | return ret; |
99 | |
100 | return 0; |
101 | } |
102 | |