Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: intel-xe@lists.freedesktop.org
Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Subject: [RFC PATCH] drm/xe/tests: Add drm_exec locking benchmark kunit test
Date: Fri,  5 Jun 2026 13:27:00 +0200	[thread overview]
Message-ID: <20260605112700.181040-4-thomas.hellstrom@linux.intel.com> (raw)
In-Reply-To: <20260605112700.181040-1-thomas.hellstrom@linux.intel.com>

Add a live kunit test that benchmarks the drm_exec wound-wait locking
sequence with a set of GEM buffer objects.  Lock, iterate, and fini
phases are timed and reported separately, along with the retry count.

Assisted-by: GitHub_Copilot:claude-sonnet-4.6
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/xe/tests/Makefile            |   3 +-
 drivers/gpu/drm/xe/tests/xe_drm_exec_kunit.c | 130 +++++++++++++++++++
 drivers/gpu/drm/xe/tests/xe_live_test_mod.c  |   2 +
 drivers/gpu/drm/xe/xe_bo.c                   |   3 +
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/xe/tests/xe_drm_exec_kunit.c

diff --git a/drivers/gpu/drm/xe/tests/Makefile b/drivers/gpu/drm/xe/tests/Makefile
index f7aa47f11a36..bdb85d33f23a 100644
--- a/drivers/gpu/drm/xe/tests/Makefile
+++ b/drivers/gpu/drm/xe/tests/Makefile
@@ -2,7 +2,8 @@
 
 # "live" kunit tests
 obj-$(CONFIG_DRM_XE_KUNIT_TEST) += xe_live_test.o
-xe_live_test-y = xe_live_test_mod.o
+xe_live_test-y = xe_live_test_mod.o \
+	xe_drm_exec_kunit.o
 
 # Normal kunit tests
 obj-$(CONFIG_DRM_XE_KUNIT_TEST) += xe_test.o
diff --git a/drivers/gpu/drm/xe/tests/xe_drm_exec_kunit.c b/drivers/gpu/drm/xe/tests/xe_drm_exec_kunit.c
new file mode 100644
index 000000000000..b5592ff94607
--- /dev/null
+++ b/drivers/gpu/drm/xe/tests/xe_drm_exec_kunit.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include <kunit/test.h>
+#include <kunit/visibility.h>
+
+#include <linux/ktime.h>
+#include <linux/slab.h>
+
+#include <drm/drm_exec.h>
+#include <uapi/drm/xe_drm.h>
+
+#include "tests/xe_kunit_helpers.h"
+#include "tests/xe_pci_test.h"
+
+#include "xe_bo.h"
+#include "xe_device.h"
+
+#define DRME_BENCH_NUM_OBJECTS 256
+
+/**
+ * DOC: drm_exec benchmark
+ *
+ * Measures the time to lock a set of GEM objects via a drm_exec sequence,
+ * iterate over all locked objects, and finalize (unlock) the exec context.
+ * Each phase is timed independently and reported via kunit_info().
+ */
+
+static void xe_drm_exec_bench_kunit(struct kunit *test)
+{
+	struct xe_device *xe = test->priv;
+	struct xe_bo **bos;
+	struct drm_gem_object *obj;
+	struct drm_exec exec;
+	ktime_t t_start, t_lock, t_iter, t_fini;
+	s64 ns_lock, ns_iter, ns_fini;
+	unsigned int count = 0;
+	unsigned int retries = 0;
+	int i;
+
+	bos = kunit_kcalloc(test, DRME_BENCH_NUM_OBJECTS, sizeof(*bos), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, bos);
+
+	for (i = 0; i < DRME_BENCH_NUM_OBJECTS; i++) {
+		bos[i] = xe_bo_create_user(xe, NULL, PAGE_SIZE,
+					   DRM_XE_GEM_CPU_CACHING_WB,
+					   XE_BO_FLAG_SYSTEM |
+					   XE_BO_FLAG_DEFER_BACKING, NULL);
+		if (IS_ERR(bos[i])) {
+			KUNIT_FAIL(test, "bo[%d] create failed: %pe\n", i,
+				   bos[i]);
+			bos[i] = NULL;
+			goto out_put;
+		}
+	}
+
+	t_start = ktime_get();
+
+	drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, DRME_BENCH_NUM_OBJECTS);
+
+	drm_exec_until_all_locked(&exec) {
+		for (i = 0; i < DRME_BENCH_NUM_OBJECTS; i++) {
+			int err = drm_exec_lock_obj(&exec, &bos[i]->ttm.base);
+			if (err == -EDEADLK)
+				retries++;
+			drm_exec_retry_on_contention(&exec);
+			if (err) {
+				KUNIT_FAIL(test, "bo[%d] lock failed: %pe\n",
+					   i, ERR_PTR(err));
+				drm_exec_fini(&exec);
+				goto out_put;
+			}
+		}
+	}
+
+	t_lock = ktime_get();
+	ns_lock = ktime_to_ns(ktime_sub(t_lock, t_start));
+
+	t_start = ktime_get();
+
+	drm_exec_for_each_locked_object(&exec, obj) {
+		READ_ONCE(obj->resv);
+		count++;
+	}
+
+	t_iter = ktime_get();
+	ns_iter = ktime_to_ns(ktime_sub(t_iter, t_start));
+
+	KUNIT_EXPECT_EQ(test, count, DRME_BENCH_NUM_OBJECTS);
+
+	/*
+	 * With CONFIG_DEBUG_WW_MUTEX_SLOWPATH the kernel injects artificial
+	 * -EDEADLK cases to exercise the slowpath, so retries are expected.
+	 * Without it, no other thread holds these objects, so any retry
+	 * indicates a real locking bug.
+	 */
+	if (!IS_ENABLED(CONFIG_DEBUG_WW_MUTEX_SLOWPATH))
+		KUNIT_EXPECT_EQ_MSG(test, retries, 0,
+				    "unexpected ww-mutex retries on uncontested objects\n");
+
+	t_start = ktime_get();
+	drm_exec_fini(&exec);
+	t_fini = ktime_get();
+	ns_fini = ktime_to_ns(ktime_sub(t_fini, t_start));
+
+	kunit_info(test,
+		   "drm_exec bench: %u objects: lock=%lldns iter=%lldns fini=%lldns retries=%u\n",
+		   DRME_BENCH_NUM_OBJECTS, ns_lock, ns_iter, ns_fini, retries);
+
+out_put:
+	for (i = 0; i < DRME_BENCH_NUM_OBJECTS; i++) {
+		if (bos[i])
+			xe_bo_put(bos[i]);
+	}
+}
+
+static struct kunit_case xe_drm_exec_bench_cases[] = {
+	KUNIT_CASE_PARAM(xe_drm_exec_bench_kunit, xe_pci_live_device_gen_param),
+	{}
+};
+
+VISIBLE_IF_KUNIT
+struct kunit_suite xe_drm_exec_bench_test_suite = {
+	.name = "xe_drm_exec_bench",
+	.test_cases = xe_drm_exec_bench_cases,
+	.init = xe_kunit_helper_xe_device_live_test_init,
+};
+EXPORT_SYMBOL_IF_KUNIT(xe_drm_exec_bench_test_suite);
diff --git a/drivers/gpu/drm/xe/tests/xe_live_test_mod.c b/drivers/gpu/drm/xe/tests/xe_live_test_mod.c
index c55e46f1ae92..926868d9e0cc 100644
--- a/drivers/gpu/drm/xe/tests/xe_live_test_mod.c
+++ b/drivers/gpu/drm/xe/tests/xe_live_test_mod.c
@@ -8,6 +8,7 @@
 extern struct kunit_suite xe_bo_test_suite;
 extern struct kunit_suite xe_bo_shrink_test_suite;
 extern struct kunit_suite xe_dma_buf_test_suite;
+extern struct kunit_suite xe_drm_exec_bench_test_suite;
 extern struct kunit_suite xe_migrate_test_suite;
 extern struct kunit_suite xe_mocs_test_suite;
 extern struct kunit_suite xe_guc_g2g_test_suite;
@@ -15,6 +16,7 @@ extern struct kunit_suite xe_guc_g2g_test_suite;
 kunit_test_suite(xe_bo_test_suite);
 kunit_test_suite(xe_bo_shrink_test_suite);
 kunit_test_suite(xe_dma_buf_test_suite);
+kunit_test_suite(xe_drm_exec_bench_test_suite);
 kunit_test_suite(xe_migrate_test_suite);
 kunit_test_suite(xe_mocs_test_suite);
 kunit_test_suite(xe_guc_g2g_test_suite);
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 4c80bac67622..2c1e47fdd3f5 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -5,6 +5,7 @@
 
 #include "xe_bo.h"
 
+#include <kunit/visibility.h>
 #include <linux/dma-buf.h>
 #include <linux/nospec.h>
 
@@ -2641,6 +2642,7 @@ struct xe_bo *xe_bo_create_user(struct xe_device *xe,
 
 	return bo;
 }
+EXPORT_SYMBOL_IF_KUNIT(xe_bo_create_user);
 
 /**
  * xe_bo_create_pin_range_novm() - Create and pin a BO with range options.
@@ -3839,6 +3841,7 @@ void xe_bo_put(struct xe_bo *bo)
 		drm_gem_object_put(&bo->ttm.base);
 	}
 }
+EXPORT_SYMBOL_IF_KUNIT(xe_bo_put);
 
 /**
  * xe_bo_dumb_create - Create a dumb bo as backing for a fb
-- 
2.54.0


  parent reply	other threads:[~2026-06-05 11:27 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-05 11:26 [RFC PATCH 0/3] Use a dma_resv wound-wait transaction API for drm_exec Thomas Hellström
2026-06-05 11:26 ` [RFC PATCH] dma-buf: Add generic dma_resv wound-wait transaction API Thomas Hellström
2026-06-05 11:26 ` [RFC PATCH] drm/exec: Rebuild drm_exec on top of dma_resv_txn Thomas Hellström
2026-06-05 11:27 ` Thomas Hellström [this message]
2026-06-05 12:16 ` ✗ CI.checkpatch: warning for drm/xe/tests: Add drm_exec locking benchmark kunit test Patchwork
2026-06-05 12:18 ` ✓ CI.KUnit: success " Patchwork
2026-06-05 13:13 ` ✓ Xe.CI.BAT: " Patchwork
2026-06-05 23:49 ` ✓ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260605112700.181040-4-thomas.hellstrom@linux.intel.com \
    --to=thomas.hellstrom@linux.intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox