[PATCH] tests/amd_queue_reset: Refactor ring sequence for job submissions
vitaly.prosyak at amd.com
vitaly.prosyak at amd.com
Fri Aug 16 01:15:34 UTC 2024
From: Vitaly Prosyak <vitaly.prosyak at amd.com>
This refactoring includes the following changes:
- For each declared error, submit the appropriate good job to ring 0
and the bad job to ring 1 for COMPUTE IP.
- After a successful queue_reset on ring 1, submit a good job to ring 1
to validate successful queue/pipe recovery, then submit a bad job to
ring 2, and repeat the process.
- For cases with a single ring, such as GFX, submit a bad packet or
shader to GFX. Simultaneously, submit good jobs to a different IP,
like COMPUTE, from another background process.
These changes ensure a more structured and reliable approach to testing
queue resets and validating the recovery process using next step.
Cc: Jesse Zhang <jesse.zhang at amd.com>
Cc: Alex Deucher <alexander.deucher at amd.com>
Cc: Christian Koenig <christian.koenig at amd.com>
Signed-off-by: Vitaly Prosyak <vitaly.prosyak at amd.com>
---
tests/amdgpu/amd_queue_reset.c | 95 +++++++++++++++++++++++++---------
1 file changed, 70 insertions(+), 25 deletions(-)
diff --git a/tests/amdgpu/amd_queue_reset.c b/tests/amdgpu/amd_queue_reset.c
index 6819892e0..d8dccda65 100644
--- a/tests/amdgpu/amd_queue_reset.c
+++ b/tests/amdgpu/amd_queue_reset.c
@@ -290,6 +290,7 @@ static void set_next_test_to_run(struct shmbuf *sh_mem, unsigned int error,
bool is_dispatch;
is_dispatch_shader_test(error, error_str, &is_dispatch);
+
get_ip_type(ip_good, ip_good_str);
get_ip_type(ip_bad, ip_bad_str);
@@ -852,35 +853,74 @@ free_contexts(amdgpu_device_handle device, amdgpu_context_handle *p_contexts,
}
static bool
-get_next_rings(unsigned int ring_begin, struct drm_amdgpu_info_hw_ip info[],
- unsigned int *good_job_ring, unsigned int *bad_job_ring, unsigned int order)
+adjust_begin_index(unsigned int *ring_begin, unsigned int available_good_rings)
{
- unsigned int ring_id;
+ unsigned int ring_id = *ring_begin;
+
+ if (!((1 << ring_id) & available_good_rings)) {
+ *ring_begin = 0;
+ return true;
+ }
+ return false;
+}
+
+static bool
+allow_same_ring_id(bool are_rings_of_differant_ip, unsigned int ring_id_bad, unsigned int ring_id_good)
+{
+ if (are_rings_of_differant_ip == true)
+ return true;
+
+ return ring_id_bad != ring_id_good;
+}
+
+static bool
+get_next_rings(unsigned int *ring_begin_good, unsigned int *ring_begin_bad,
+ unsigned int available_good_rings, unsigned int available_bad_rings,
+ bool are_rings_of_differant_ip, unsigned int *good_job_ring,
+ unsigned int *bad_job_ring)
+{
+ unsigned int ring_id_good, ring_id_bad;
+
+ for (ring_id_good = *ring_begin_good; ring_id_good < 32; ring_id_good++) {
+ if ((1 << ring_id_good) & available_good_rings) {
+ *good_job_ring = ring_id_good;
+
+ for (ring_id_bad = *ring_begin_bad; ring_id_bad < 32; ring_id_bad++) {
+ if ((1 << ring_id_bad) & available_bad_rings &&
+ allow_same_ring_id(are_rings_of_differant_ip, ring_id_bad, ring_id_good)) {
+ *bad_job_ring = ring_id_bad;
+
+ // Update the starting points for the next call
+ *ring_begin_good = ring_id_good + 1;
+ *ring_begin_bad = ring_id_bad + 1;
+
+ if (adjust_begin_index(ring_begin_bad, available_bad_rings))
+ *ring_begin_good += 1;
+
+ adjust_begin_index(ring_begin_good, available_good_rings);
- /* Check good job ring is available. By default good job run on compute ring */
- for (ring_id = ring_begin; (1 << ring_id) & info[0].available_rings; ring_id++) {
- if ((1 << *good_job_ring) & info[0].available_rings) {
- *good_job_ring = ring_id;
- /* check bad job ring is available */
- for (ring_id = ring_begin; (1 << ring_id) & info[order].available_rings; ring_id++) {
- /* if order is 0, bad job run on compute ring,
- * It should skip good ring and find next ring to run bad job.
- */
- if (!order)
- *bad_job_ring = *good_job_ring + 1;
- else
- *bad_job_ring = ring_id;
- if ((1 << *bad_job_ring) & info[order].available_rings) {
return true;
}
}
+ // Reset ring_begin_bad for the next good ring
+ *ring_begin_bad = 0;
}
}
return false;
}
+static void
+reset_rings_numbers(unsigned int *ring_id_good, unsigned int *ring_id_bad,
+ unsigned int *ring_id_job_good, unsigned int *ring_id_job_bad)
+{
+ *ring_id_good = 0;
+ *ring_id_bad = 0;
+ *ring_id_job_good = 0;
+ *ring_id_job_bad = 0;
+}
+
igt_main
{
char cmdline[2048];
@@ -901,8 +941,10 @@ igt_main
int r;
bool arr_cap[AMD_IP_MAX] = {0};
- unsigned int ring_id_good = 0;
- unsigned int ring_id_bad = 1;
+ unsigned int ring_id_good;
+ unsigned int ring_id_bad;
+ unsigned int ring_id_job_good;
+ unsigned int ring_id_job_bad;
enum amd_ip_block_type ip_tests[2] = {AMD_IP_COMPUTE/*keep first*/, AMD_IP_GFX};
enum amd_ip_block_type ip_background = AMD_IP_COMPUTE;
@@ -926,7 +968,7 @@ igt_main
// "Stressful-and-multiple-cs-of-bad and good reg-operations-using-multiple-processes"},
{BACKEND_SE_GC_SHADER_INVALID_PROGRAM_ADDR, "BACKEND_SE_GC_SHADER_INVALID_PROGRAM_ADDR",
"Stressful-and-multiple-cs-of-bad and good shader-operations-using-multiple-processes"},
- //TODO KGQ cannot revocer by queue reset, it maybe need a fw bugfix on naiv31
+ //TODO KGQ cannot recover by queue reset, it maybe need a fw bugfix on naiv31
//{BACKEND_SE_GC_SHADER_INVALID_PROGRAM_SETTING,"BACKEND_SE_GC_SHADER_INVALID_PROGRAM_SETTING",
// "Stressful-and-multiple-cs-of-bad and good shader-operations-using-multiple-processes"},
{BACKEND_SE_GC_SHADER_INVALID_USER_DATA, "BACKEND_SE_GC_SHADER_INVALID_USER_DATA",
@@ -996,12 +1038,15 @@ igt_main
}
for (int i = 0; i < ARRAY_SIZE(ip_tests); i++) {
+ reset_rings_numbers(&ring_id_good, &ring_id_bad, &ring_id_job_good, &ring_id_job_bad);
for (struct dynamic_test *it = &arr_err[0]; it->name; it++) {
- igt_describe("Stressful-and-multiple-cs-of-bad and good length-operations-using-multiple-processes");
- igt_subtest_with_dynamic_f("amdgpu-%s-%s", ip_tests[i] == AMD_IP_COMPUTE ? "COMPUTE":"GRAFIX", it->name) {
- if (arr_cap[ip_tests[i]] && get_next_rings(ring_id_good, info, &ring_id_good, &ring_id_bad, i)) {
- igt_dynamic_f("amdgpu-%s-ring-good-%d-bad-%d-%s", it->name,ring_id_good, ring_id_bad, ip_tests[i] == AMD_IP_COMPUTE ? "COMPUTE":"GRAFIX")
- set_next_test_to_run(sh_mem, it->test, ip_background, ip_tests[i], ring_id_good, ring_id_bad);
+ igt_describe("Stressful-and-multiple-cs-of-bad-and-good-length-operations-using-multiple-processes");
+ igt_subtest_with_dynamic_f("amdgpu-%s-%s", ip_tests[i] == AMD_IP_COMPUTE ? "COMPUTE":"GFX", it->name) {
+ if (arr_cap[ip_tests[i]] && get_next_rings(&ring_id_good, &ring_id_bad, info[0].available_rings,
+ info[i].available_rings, ip_background != ip_tests[i], &ring_id_job_good, &ring_id_job_bad)) {
+ igt_dynamic_f("amdgpu-%s-ring-good-%d-bad-%d-%s", it->name, ring_id_job_good, ring_id_job_bad,
+ ip_tests[i] == AMD_IP_COMPUTE ? "COMPUTE":"GFX")
+ set_next_test_to_run(sh_mem, it->test, ip_background, ip_tests[i], ring_id_job_good, ring_id_job_bad);
}
}
}
--
2.25.1
More information about the igt-dev
mailing list