drm/sched: Add basic priority tests
authorTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Mon, 24 Mar 2025 09:26:31 +0000 (09:26 +0000)
committerPhilipp Stanner <phasta@kernel.org>
Mon, 24 Mar 2025 09:41:54 +0000 (10:41 +0100)
Add some basic tests for exercising entity priority handling.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Philipp Stanner <phasta@kernel.org>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20250324092633.49746-5-tvrtko.ursulin@igalia.com
drivers/gpu/drm/scheduler/tests/tests_basic.c

index 0e1fa4767b0d8848b02a3b9151ed62f32ec9c89d..10378b7ca457debf65a6b0a9b2f30e67d120a638 100644 (file)
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2025 Valve Corporation */
 
+#include <linux/delay.h>
+
 #include "sched_tests.h"
 
 /*
@@ -254,5 +256,96 @@ static struct kunit_suite drm_sched_timeout = {
        .test_cases = drm_sched_timeout_tests,
 };
 
+static void drm_sched_priorities(struct kunit *test)
+{
+       struct drm_mock_sched_entity *entity[DRM_SCHED_PRIORITY_COUNT];
+       struct drm_mock_scheduler *sched = test->priv;
+       struct drm_mock_sched_job *job;
+       const unsigned int qd = 100;
+       unsigned int i, cur_ent = 0;
+       enum drm_sched_priority p;
+       bool done;
+
+       /*
+        * Submit a bunch of jobs against entities configured with different
+        * priorities.
+        */
+
+       BUILD_BUG_ON(DRM_SCHED_PRIORITY_KERNEL > DRM_SCHED_PRIORITY_LOW);
+       BUILD_BUG_ON(ARRAY_SIZE(entity) != DRM_SCHED_PRIORITY_COUNT);
+
+       for (p = DRM_SCHED_PRIORITY_KERNEL; p <= DRM_SCHED_PRIORITY_LOW; p++)
+               entity[p] = drm_mock_sched_entity_new(test, p, sched);
+
+       for (i = 0; i < qd; i++) {
+               job = drm_mock_sched_job_new(test, entity[cur_ent++]);
+               cur_ent %= ARRAY_SIZE(entity);
+               drm_mock_sched_job_set_duration_us(job, 1000);
+               drm_mock_sched_job_submit(job);
+       }
+
+       done = drm_mock_sched_job_wait_finished(job, HZ);
+       KUNIT_ASSERT_TRUE(test, done);
+
+       for (i = 0; i < ARRAY_SIZE(entity); i++)
+               drm_mock_sched_entity_free(entity[i]);
+}
+
+static void drm_sched_change_priority(struct kunit *test)
+{
+       struct drm_mock_sched_entity *entity[DRM_SCHED_PRIORITY_COUNT];
+       struct drm_mock_scheduler *sched = test->priv;
+       struct drm_mock_sched_job *job;
+       const unsigned int qd = 1000;
+       unsigned int i, cur_ent = 0;
+       enum drm_sched_priority p;
+
+       /*
+        * Submit a bunch of jobs against entities configured with different
+        * priorities and while waiting for them to complete, periodically keep
+        * changing their priorities.
+        *
+        * We set up the queue-depth (qd) and job duration so the priority
+        * changing loop has some time to interact with submissions to the
+        * backend and job completions as they progress.
+        */
+
+       for (p = DRM_SCHED_PRIORITY_KERNEL; p <= DRM_SCHED_PRIORITY_LOW; p++)
+               entity[p] = drm_mock_sched_entity_new(test, p, sched);
+
+       for (i = 0; i < qd; i++) {
+               job = drm_mock_sched_job_new(test, entity[cur_ent++]);
+               cur_ent %= ARRAY_SIZE(entity);
+               drm_mock_sched_job_set_duration_us(job, 1000);
+               drm_mock_sched_job_submit(job);
+       }
+
+       do {
+               drm_sched_entity_set_priority(&entity[cur_ent]->base,
+                                             (entity[cur_ent]->base.priority + 1) %
+                                             DRM_SCHED_PRIORITY_COUNT);
+               cur_ent++;
+               cur_ent %= ARRAY_SIZE(entity);
+               usleep_range(200, 500);
+       } while (!drm_mock_sched_job_is_finished(job));
+
+       for (i = 0; i < ARRAY_SIZE(entity); i++)
+               drm_mock_sched_entity_free(entity[i]);
+}
+
+static struct kunit_case drm_sched_priority_tests[] = {
+       KUNIT_CASE(drm_sched_priorities),
+       KUNIT_CASE(drm_sched_change_priority),
+       {}
+};
+
+static struct kunit_suite drm_sched_priority = {
+       .name = "drm_sched_basic_priority_tests",
+       .init = drm_sched_basic_init,
+       .exit = drm_sched_basic_exit,
+       .test_cases = drm_sched_priority_tests,
+};
+
 kunit_test_suites(&drm_sched_basic,
-                 &drm_sched_timeout);
+                 &drm_sched_timeout,
+                 &drm_sched_priority);