public inbox for sched-ext@lists.linux.dev
 help / color / mirror / Atom feed
From: Andrea Righi <arighi@nvidia.com>
To: zhidao su <soolaugust@gmail.com>
Cc: tj@kernel.org, sched-ext@lists.linux.dev,
	linux-kernel@vger.kernel.org, void@manifault.com,
	changwoo@igalia.com, linux-kselftest@vger.kernel.org,
	Su Zhidao <suzhidao@xiaomi.com>
Subject: Re: [PATCH 4/5] sched_ext/selftests: Add bypass mode operational test
Date: Fri, 6 Mar 2026 16:02:17 +0100	[thread overview]
Message-ID: <aarseQkKjysu83E3@gpd4> (raw)
In-Reply-To: <20260306140325.2710927-5-suzhidao@xiaomi.com>

Hi,

On Fri, Mar 06, 2026 at 10:03:24PM +0800, zhidao su wrote:
> From: Su Zhidao <suzhidao@xiaomi.com>
> 
> Add a test that verifies the sched_ext bypass mechanism does not
> prevent tasks from running to completion.
> 
> The test attaches a minimal global FIFO scheduler, spawns worker
> processes that complete a fixed computation, detaches the scheduler
> (which triggers bypass mode while workers are still active), and
> verifies all workers complete successfully under bypass mode.
> 
> This exercises the scheduler attach/detach lifecycle and verifies
> that bypass mode (activated during unregistration to guarantee
> forward progress) does not stall running tasks.

I'm not sure this selftest adds much value. Implicitly we're already
testing the validity of bypass in the other sched_ext kselftests: if a task
is missed or gets stuck due to bypass mode, we would trigger a soft lockup,
a hung task timeout, or something similar.

> 
> Signed-off-by: Su Zhidao <suzhidao@xiaomi.com>
> ---
>  tools/testing/selftests/sched_ext/Makefile    |   1 +
>  .../testing/selftests/sched_ext/bypass.bpf.c  |  32 ++++++
>  tools/testing/selftests/sched_ext/bypass.c    | 105 ++++++++++++++++++
>  3 files changed, 138 insertions(+)
>  create mode 100644 tools/testing/selftests/sched_ext/bypass.bpf.c
>  create mode 100644 tools/testing/selftests/sched_ext/bypass.c
> 
> diff --git a/tools/testing/selftests/sched_ext/Makefile b/tools/testing/selftests/sched_ext/Makefile
> index a3bbe2c7911b..5fb6278d3f97 100644
> --- a/tools/testing/selftests/sched_ext/Makefile
> +++ b/tools/testing/selftests/sched_ext/Makefile
> @@ -162,6 +162,7 @@ endef
>  all_test_bpfprogs := $(foreach prog,$(wildcard *.bpf.c),$(INCLUDE_DIR)/$(patsubst %.c,%.skel.h,$(prog)))
>  
>  auto-test-targets :=			\
> +	bypass				\
>  	create_dsq			\
>  	dequeue				\
>  	enq_last_no_enq_fails		\
> diff --git a/tools/testing/selftests/sched_ext/bypass.bpf.c b/tools/testing/selftests/sched_ext/bypass.bpf.c
> new file mode 100644
> index 000000000000..cb37c8df6834
> --- /dev/null
> +++ b/tools/testing/selftests/sched_ext/bypass.bpf.c
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * BPF scheduler for bypass mode operational test.
> + *
> + * Implements a minimal global FIFO scheduler. The userspace side
> + * attaches this scheduler, runs worker tasks to completion, and
> + * verifies that tasks complete successfully.
> + *
> + * Copyright (c) 2026 Xiaomi Corporation.
> + */
> +#include <scx/common.bpf.h>
> +
> +char _license[] SEC("license") = "GPL";
> +
> +UEI_DEFINE(uei);
> +
> +void BPF_STRUCT_OPS(bypass_enqueue, struct task_struct *p, u64 enq_flags)
> +{
> +	scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
> +}

We could also remove bypass_enqueue() and sched_ext core will do exactly
the same (implicitly enqueue to SCX_DSQ_GLOBAL).

> +
> +void BPF_STRUCT_OPS(bypass_exit, struct scx_exit_info *ei)
> +{
> +	UEI_RECORD(uei, ei);
> +}
> +
> +SEC(".struct_ops.link")
> +struct sched_ext_ops bypass_ops = {
> +	.enqueue		= (void *)bypass_enqueue,
> +	.exit			= (void *)bypass_exit,
> +	.name			= "bypass_test",
> +};
> diff --git a/tools/testing/selftests/sched_ext/bypass.c b/tools/testing/selftests/sched_ext/bypass.c
> new file mode 100644
> index 000000000000..952f09d76bdb
> --- /dev/null
> +++ b/tools/testing/selftests/sched_ext/bypass.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Verify the sched_ext bypass mechanism: spawn worker tasks and ensure
> + * they run to completion while a BPF scheduler is active.
> + *
> + * The bypass mechanism (activated on scheduler unregistration) must
> + * guarantee forward progress. This test verifies that worker tasks
> + * complete successfully when the scheduler is detached.
> + *
> + * Copyright (c) 2026 Xiaomi Corporation.
> + */
> +#define _GNU_SOURCE
> +#include <unistd.h>
> +#include <sys/wait.h>
> +#include <bpf/bpf.h>
> +#include <scx/common.h>
> +#include "scx_test.h"
> +#include "bypass.bpf.skel.h"
> +
> +#define NUM_BYPASS_WORKERS 4
> +
> +static void worker_fn(void)
> +{
> +	volatile int sum = 0;
> +	int i;
> +
> +	/*
> +	 * Do enough work to still be running when bpf_link__destroy()
> +	 * is called, ensuring tasks are active during bypass mode.
> +	 */
> +	for (i = 0; i < 10000000; i++)
> +		sum += i;
> +}
> +
> +static enum scx_test_status setup(void **ctx)
> +{
> +	struct bypass *skel;
> +
> +	skel = bypass__open();
> +	SCX_FAIL_IF(!skel, "Failed to open bypass skel");
> +	SCX_ENUM_INIT(skel);
> +	SCX_FAIL_IF(bypass__load(skel), "Failed to load bypass skel");
> +
> +	*ctx = skel;
> +	return SCX_TEST_PASS;
> +}
> +
> +static enum scx_test_status run(void *ctx)
> +{
> +	struct bypass *skel = ctx;
> +	struct bpf_link *link;
> +	pid_t pids[NUM_BYPASS_WORKERS];
> +	int i, status;
> +
> +	link = bpf_map__attach_struct_ops(skel->maps.bypass_ops);
> +	SCX_FAIL_IF(!link, "Failed to attach bypass scheduler");
> +
> +	/*
> +	 * Spawn worker processes. These must complete successfully
> +	 * even as the scheduler is active and then detached (which
> +	 * triggers bypass mode).
> +	 */
> +	for (i = 0; i < NUM_BYPASS_WORKERS; i++) {
> +		pids[i] = fork();
> +		SCX_FAIL_IF(pids[i] < 0, "fork() failed for worker %d", i);
> +
> +		if (pids[i] == 0) {
> +			worker_fn();
> +			_exit(0);
> +		}
> +	}

There's no synchronization with the parent, so on a fast system the workers
may even finish the loop before the parent ever detaches the scheduler.

> +
> +	/*
> +	 * Detach the scheduler while workers are still running. This
> +	 * triggers bypass mode, which must guarantee forward progress
> +	 * for all active tasks.
> +	 */
> +	bpf_link__destroy(link);
> +
> +	/* Workers must complete successfully under bypass mode */
> +	for (i = 0; i < NUM_BYPASS_WORKERS; i++) {
> +		SCX_FAIL_IF(waitpid(pids[i], &status, 0) != pids[i],
> +			    "waitpid failed for worker %d", i);
> +		SCX_FAIL_IF(!WIFEXITED(status) || WEXITSTATUS(status) != 0,
> +			    "Worker %d did not exit cleanly", i);
> +	}
> +
> +	SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG));
> +
> +	return SCX_TEST_PASS;
> +}
> +
> +static void cleanup(void *ctx)
> +{
> +	bypass__destroy(ctx);
> +}
> +
> +struct scx_test bypass_test = {
> +	.name		= "bypass",
> +	.description	= "Verify tasks complete during bypass mode",
> +	.setup		= setup,
> +	.run		= run,
> +	.cleanup	= cleanup,
> +};
> +REGISTER_SCX_TEST(&bypass_test)
> -- 
> 2.43.0
> 

Thanks,
-Andrea

  reply	other threads:[~2026-03-06 15:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-06 14:03 [PATCH 0/5] sched_ext: bypass state machine cleanup and selftest zhidao su
2026-03-06 14:03 ` [PATCH 1/5] sched_ext: Remove deprecated SCX_OPS_HAS_CGROUP_WEIGHT flag zhidao su
2026-03-06 14:03 ` [PATCH 2/5] sched_ext: Add comments to scx_bypass() for bypass depth semantics zhidao su
2026-03-06 14:03 ` [PATCH 3/5] sched_ext: Use rcu_dereference_bh() in scx_bypass_lb_timerfn() zhidao su
2026-03-06 14:03 ` [PATCH 4/5] sched_ext/selftests: Add bypass mode operational test zhidao su
2026-03-06 15:02   ` Andrea Righi [this message]
2026-03-06 14:03 ` [PATCH 5/5] sched_ext: Document scx_bypass_depth migration path zhidao su
2026-03-06 15:02 ` [PATCH 0/5] sched_ext: bypass state machine cleanup and selftest Andrea Righi
  -- strict thread matches above, loose matches on Subject: below --
2026-03-06 12:49 [PATCH 4/5] sched_ext/selftests: Add bypass mode operational test zhidao su

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=aarseQkKjysu83E3@gpd4 \
    --to=arighi@nvidia.com \
    --cc=changwoo@igalia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=sched-ext@lists.linux.dev \
    --cc=soolaugust@gmail.com \
    --cc=suzhidao@xiaomi.com \
    --cc=tj@kernel.org \
    --cc=void@manifault.com \
    /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