From nobody Sun Feb 8 04:13:16 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55BEF86277 for ; Tue, 20 Jan 2026 20:52:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768942366; cv=none; b=VACiDHUojPJO50FrFomNDZ+Ea16PQupmgmE5hVHYUQ5QYb00Hv6zl9hXRisFTXXW7ZG+HqzEYULy71Wk6bfUKdbU3rD2fLEzNbsNmNSEHQyflfulLfNS3vi29YIuuVtThWHPlcbGpSkcIHfPxAzDwP3zyfjqPdgAH1drbOsz7Gk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768942366; c=relaxed/simple; bh=FkJUk4iteiVnmLa0RmRV7NvjRIitkuLKRf/Dq94tlz0=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=VioOzo/MoKIyu48LzyZC33O4dV2UgVKtOsFJgK5Ok2A+U0cI6bkzMw4jNpz69YJMptjlghpEBumcBPJEzPxiQtwWGysKKGcqghQfYwfecAMsgIh8Uqc5Ks/5aDcfIBemLDRTBNPi7ajhfYnaDsiyuYt1bru8auTHwOwBCw38kDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=RGifak9/; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=YwCfdv2e; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="RGifak9/"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="YwCfdv2e" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768942363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=gZsQHtvSF6rIYrYSsrnHHNu4UydWwEVQwV5U0Co97a8=; b=RGifak9/3WLxrCc97k3oL1ZFFgVtZWLZx4Xo1grNrL4Q2JYrIOt25/yl9JtMAxs6/a5ldY MNhcnQ7Kxr8X+L5NFbD9AUR2KsUkL6X9G/hUIrtzG7gES4bGh61rB7JVOWbrzNXBXTM6KJ 2wsYJVtmHUd/PKvD7hSHmLRaJkr+tj8= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-365-j6LRMBJJNVm5jFGa6rGCHw-1; Tue, 20 Jan 2026 15:52:41 -0500 X-MC-Unique: j6LRMBJJNVm5jFGa6rGCHw-1 X-Mimecast-MFC-AGG-ID: j6LRMBJJNVm5jFGa6rGCHw_1768942361 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-4358f90fe8dso133774f8f.0 for ; Tue, 20 Jan 2026 12:52:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1768942361; x=1769547161; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=gZsQHtvSF6rIYrYSsrnHHNu4UydWwEVQwV5U0Co97a8=; b=YwCfdv2e7GJiifSGHKjeBTNf7cLkwQvHvOPcwv+UM42vaYWUJlqbDZbWZVr4ezLtwK Bza7adZy4sL0THGZfkBEC0iHdZL34HjVPnhwwBEqoLy3uFznxDQjX+MpWRovfbj+6XLa Gzu6y3Ugm5DqbpzG1Av4XWXoVnGXAat/rwSlZTsnOXLSfbEdeAnRsDW6nZ23cvlWJYaE /IF6WZHp+z/G1nYarZuDVOWFyhOGQBm+vpBjI4Y/i+Wvip163bFY6v4NSn0Jw120Z5BJ 9PfixSRtGeWbWliz9LDE+PdWuqDgKGHeWnaCMPPxJYV+ro5gmqh0mfJTrJqYs2dhIBUc cxhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768942361; x=1769547161; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gZsQHtvSF6rIYrYSsrnHHNu4UydWwEVQwV5U0Co97a8=; b=g3g3hwTVEBQpcCInrSJH+zKlE7hjQ+MnswiBHsJBi1jdfP31Xk93qCWybjpin9Uipe Bq9ocOVQzvixS5HV4eHuU8Um1wM+PrbrWVIjS0kKVGkkVO11k+MUDfjXJE1rbqf7OiVB 1M9a6RG1HjRrlX+8IYfj1ECPPDTt2bnG7fDzYqwixKmPqYH9by7m/8NOU8XoaAdCZLIe OZugyKs4u3M5Mf+Buw6s+Q+KDwzWprbYDNGaRGDVTuwKXxzwiDvuJAeOTM+fnboDTm0k Dt9hvbyzkma01HelcpntR7Oh07vliiI+75s3hfbdOCpvwbEtbGBeP1NZqt+bZhv2y1v5 GAHw== X-Forwarded-Encrypted: i=1; AJvYcCWQQubP962JCMLOh8RWPLEsi0kfUnkrfEFAN0g6xwmpv0YI70RIO/kLdR7oV1EbsKSoJ79tU81IMHALNIE=@vger.kernel.org X-Gm-Message-State: AOJu0YxBNb5bJcpUFsWzgLgkXfg+cfnWpUTIiUyiyAP071tTqZ50I/yh mFCn/xvxuKNHMq+Lb8hPr8JWi90j6Hl6w5qlRIgkDyDqQUm7o9FDvJQkVKfeG9SgbEac1XDvXmx rxN9brg5d164LKtrmPbQeZi7LgjN5trSyaSS6REmNmz4jBs04Vg7DSeieSK6wGvgT X-Gm-Gg: AZuq6aLBDWJGcIPdtG44eCdtZ838Xkim/vBrOObPg4eYh+Nq2kmM7sFmU96Nz5oYpJO 5YaTg1Irp00e55bw74LzZvcnsFehHLwvizUQjM2A/moKL7YdrytTul1zdhDuiCmKikY9IsLTefi SrZbgpus34hxeRtSNlGaZr33QFsd2Uaz1iCS3qqTOosqPyd7vsaEbWj5YG1aq9dTXRO2BAJ3Y1w /HbonrpBhLtdCrmx8x4tb3hzUNoR8ph0nnc3AxZMuasQAJtKf+be33I3H++DzdQ1Z2c0L416Ovg bhCTDnNlxMVhq8LZLYcwikv+MEDJsEmNiUmKpxHrRd4vn5iV9UBeFgLAQo0htZKPQ6DqJM7vkRM 83YauY5y4+3y+p3f/zzc5r/VfxeIJDD3ngpn6pqsSpnSn6cZ0bPdGVs0= X-Received: by 2002:a05:6000:2505:b0:432:88c4:e180 with SMTP id ffacd0b85a97d-434d75c16a2mr29467607f8f.15.1768942360558; Tue, 20 Jan 2026 12:52:40 -0800 (PST) X-Received: by 2002:a05:6000:2505:b0:432:88c4:e180 with SMTP id ffacd0b85a97d-434d75c16a2mr29467575f8f.15.1768942360134; Tue, 20 Jan 2026 12:52:40 -0800 (PST) Received: from neptune.lan (host-82-62-247-97.business.telecomitalia.it. [82.62.247.97]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43595609c8asm3420478f8f.34.2026.01.20.12.52.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jan 2026 12:52:39 -0800 (PST) From: Marco Pagani To: Matthew Brost , Danilo Krummrich , Philipp Stanner , =?UTF-8?q?Christian=20K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: Marco Pagani , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH] drm/sched: Add new KUnit test suite for concurrent job submission Date: Tue, 20 Jan 2026 21:52:34 +0100 Message-ID: <20260120205236.322086-1-marpagan@redhat.com> X-Mailer: git-send-email 2.52.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new test suite to simulate concurrent job submissions from userspace. The suite includes a basic test case where each worker submits a single job, and a more advanced case involving the submission of multiple jobs. Signed-off-by: Marco Pagani --- drivers/gpu/drm/scheduler/tests/tests_basic.c | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/drivers/gpu/drm/scheduler/tests/tests_basic.c b/drivers/gpu/dr= m/scheduler/tests/tests_basic.c index 82a41a456b0a..7c25bcbbe7c9 100644 --- a/drivers/gpu/drm/scheduler/tests/tests_basic.c +++ b/drivers/gpu/drm/scheduler/tests/tests_basic.c @@ -2,6 +2,7 @@ /* Copyright (c) 2025 Valve Corporation */ =20 #include +#include =20 #include "sched_tests.h" =20 @@ -235,6 +236,179 @@ static void drm_sched_basic_cancel(struct kunit *test) KUNIT_ASSERT_EQ(test, job->hw_fence.error, -ECANCELED); } =20 +struct sched_concurrent_test_context { + struct drm_mock_scheduler *sched; + struct workqueue_struct *sub_wq; + struct completion wait_go; +}; + +KUNIT_DEFINE_ACTION_WRAPPER(destroy_workqueue_wrap, destroy_workqueue, + struct workqueue_struct *); + +KUNIT_DEFINE_ACTION_WRAPPER(drm_mock_sched_fini_wrap, drm_mock_sched_fini, + struct drm_mock_scheduler *); + +KUNIT_DEFINE_ACTION_WRAPPER(drm_mock_sched_entity_free_wrap, drm_mock_sche= d_entity_free, + struct drm_mock_sched_entity *); + +static int drm_sched_concurrent_init(struct kunit *test) +{ + struct sched_concurrent_test_context *ctx; + int ret; + + ctx =3D kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + + init_completion(&ctx->wait_go); + + ctx->sched =3D drm_mock_sched_new(test, MAX_SCHEDULE_TIMEOUT); + + ret =3D kunit_add_action_or_reset(test, drm_mock_sched_fini_wrap, ctx->sc= hed); + KUNIT_ASSERT_EQ(test, ret, 0); + + /* Use an unbounded workqueue to maximize job submission concurrency */ + ctx->sub_wq =3D alloc_workqueue("drm-sched-submitters-wq", WQ_UNBOUND, + WQ_UNBOUND_MAX_ACTIVE); + KUNIT_ASSERT_NOT_NULL(test, ctx->sub_wq); + + ret =3D kunit_add_action_or_reset(test, destroy_workqueue_wrap, ctx->sub_= wq); + KUNIT_ASSERT_EQ(test, ret, 0); + + test->priv =3D ctx; + + return 0; +} + +struct drm_sched_concurrent_params { + const char *description; + unsigned int job_base_us; + unsigned int num_jobs; + unsigned int num_subs; +}; + +static const struct drm_sched_concurrent_params drm_sched_concurrent_cases= [] =3D { + { + .description =3D "Concurrently submit a single job in a single entity", + .job_base_us =3D 1000, + .num_jobs =3D 1, + .num_subs =3D 32, + }, + { + .description =3D "Concurrently submit multiple jobs in a single entity", + .job_base_us =3D 1000, + .num_jobs =3D 10, + .num_subs =3D 64, + }, +}; + +static void +drm_sched_concurrent_desc(const struct drm_sched_concurrent_params *params= , char *desc) +{ + strscpy(desc, params->description, KUNIT_PARAM_DESC_SIZE); +} + +KUNIT_ARRAY_PARAM(drm_sched_concurrent, drm_sched_concurrent_cases, drm_sc= hed_concurrent_desc); + +struct submitter_data { + struct work_struct work; + struct sched_concurrent_test_context *ctx; + struct drm_mock_sched_entity *entity; + struct drm_mock_sched_job **jobs; + struct kunit *test; + unsigned int id; + bool timedout; +}; + +static void drm_sched_submitter_worker(struct work_struct *work) +{ + const struct drm_sched_concurrent_params *params; + struct sched_concurrent_test_context *ctx; + struct submitter_data *sub_data; + unsigned int i, duration_us; + unsigned long timeout_jiffies; + bool done; + + sub_data =3D container_of(work, struct submitter_data, work); + ctx =3D sub_data->ctx; + params =3D sub_data->test->param_value; + + wait_for_completion(&ctx->wait_go); + + for (i =3D 0; i < params->num_jobs; i++) { + duration_us =3D params->job_base_us + (sub_data->id * 10); + drm_mock_sched_job_set_duration_us(sub_data->jobs[i], duration_us); + drm_mock_sched_job_submit(sub_data->jobs[i]); + } + + timeout_jiffies =3D usecs_to_jiffies(params->job_base_us * params->num_su= bs * + params->num_jobs * 10); + for (i =3D 0; i < params->num_jobs; i++) { + done =3D drm_mock_sched_job_wait_finished(sub_data->jobs[i], + timeout_jiffies); + if (!done) + sub_data->timedout =3D true; + } +} + +static void drm_sched_concurrent_submit_test(struct kunit *test) +{ + struct sched_concurrent_test_context *ctx =3D test->priv; + const struct drm_sched_concurrent_params *params =3D test->param_value; + struct submitter_data *subs_data; + unsigned int i, j; + int ret; + + subs_data =3D kunit_kcalloc(test, params->num_subs, sizeof(*subs_data), + GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, subs_data); + + /* + * Pre-allocate entities and jobs in the main thread to avoid KUnit + * assertions in submitters threads + */ + for (i =3D 0; i < params->num_subs; i++) { + subs_data[i].id =3D i; + subs_data[i].ctx =3D ctx; + subs_data[i].test =3D test; + subs_data[i].timedout =3D false; + subs_data[i].entity =3D drm_mock_sched_entity_new(test, + DRM_SCHED_PRIORITY_NORMAL, + ctx->sched); + + ret =3D kunit_add_action_or_reset(test, drm_mock_sched_entity_free_wrap, + subs_data[i].entity); + KUNIT_ASSERT_EQ(test, ret, 0); + + subs_data[i].jobs =3D kunit_kcalloc(test, params->num_jobs, + sizeof(*subs_data[i].jobs), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, subs_data[i].jobs); + + for (j =3D 0; j < params->num_jobs; j++) + subs_data[i].jobs[j] =3D drm_mock_sched_job_new(test, + subs_data[i].entity); + + INIT_WORK(&subs_data[i].work, drm_sched_submitter_worker); + queue_work(ctx->sub_wq, &subs_data[i].work); + } + + complete_all(&ctx->wait_go); + flush_workqueue(ctx->sub_wq); + + for (i =3D 0; i < params->num_subs; i++) + KUNIT_ASSERT_FALSE_MSG(test, subs_data[i].timedout, + "Job submitter worker %u timedout", i); +} + +static struct kunit_case drm_sched_concurrent_tests[] =3D { + KUNIT_CASE_PARAM(drm_sched_concurrent_submit_test, drm_sched_concurrent_g= en_params), + {} +}; + +static struct kunit_suite drm_sched_concurrent =3D { + .name =3D "drm_sched_concurrent_tests", + .init =3D drm_sched_concurrent_init, + .test_cases =3D drm_sched_concurrent_tests, +}; + static struct kunit_case drm_sched_cancel_tests[] =3D { KUNIT_CASE(drm_sched_basic_cancel), {} @@ -556,6 +730,7 @@ static struct kunit_suite drm_sched_credits =3D { }; =20 kunit_test_suites(&drm_sched_basic, + &drm_sched_concurrent, &drm_sched_timeout, &drm_sched_cancel, &drm_sched_priority, --=20 2.52.0