diff mbox series

sched: add sched sysctl sanity test

Message ID 20230901144433.2526-1-chrubis@suse.cz
State Superseded
Headers show
Series sched: add sched sysctl sanity test | expand

Commit Message

Cyril Hrubis Sept. 1, 2023, 2:44 p.m. UTC
Currently the test fails due to kernel bug, I will send patch to LKML
later on.

The problem with kernel is that sysctl_sched_rt_period is unsigned int
but it's processed with proc_dointvec() which means that you are allowed
to write negative values into the variable even though documentation
says it shouldn't be possible and the kernel code asserts that rt_period
is > 0.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/sched                                 |   2 +
 testcases/kernel/sched/sysctl/.gitignore      |   1 +
 testcases/kernel/sched/sysctl/Makefile        |   7 ++
 .../kernel/sched/sysctl/proc_sched_rt01.c     | 115 ++++++++++++++++++
 4 files changed, 125 insertions(+)
 create mode 100644 testcases/kernel/sched/sysctl/.gitignore
 create mode 100644 testcases/kernel/sched/sysctl/Makefile
 create mode 100644 testcases/kernel/sched/sysctl/proc_sched_rt01.c

Comments

Cyril Hrubis Sept. 1, 2023, 3:53 p.m. UTC | #1
Hi!
> Currently the test fails due to kernel bug, I will send patch to LKML
> later on.

https://lkml.org/lkml/2023/9/1/569
Petr Vorel Sept. 1, 2023, 4:15 p.m. UTC | #2
Hi Cyril,

> Currently the test fails due to kernel bug, I will send patch to LKML
> later on.
+1.

> The problem with kernel is that sysctl_sched_rt_period is unsigned int
> but it's processed with proc_dointvec() which means that you are allowed
> to write negative values into the variable even though documentation
> says it shouldn't be possible and the kernel code asserts that rt_period
> is > 0.

Interesting.

LTP patch uses sometimes spaces instead of tabs:

$ make check-proc_sched_rt01
CHECK testcases/kernel/sched/sysctl/proc_sched_rt01.c
proc_sched_rt01.c:49: ERROR: code indent should use tabs where possible
proc_sched_rt01.c:55: ERROR: code indent should use tabs where possible
proc_sched_rt01.c:57: ERROR: code indent should use tabs where possible
proc_sched_rt01.c:63: ERROR: code indent should use tabs where possible
proc_sched_rt01.c:76: ERROR: code indent should use tabs where possible

...
> diff --git a/testcases/kernel/sched/sysctl/.gitignore b/testcases/kernel/sched/sysctl/.gitignore
> new file mode 100644
> index 000000000..29b859b81
> --- /dev/null
> +++ b/testcases/kernel/sched/sysctl/.gitignore
> @@ -0,0 +1 @@
> +proc_sched_rt01
nit: We usually put / in the front:
/proc_sched_rt01

...
> +++ b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Sanity tests for the /proc/sys/kernel/sched_r* files.
> + *
> + * - The sched_rt_period_us range is 1 to INT_MAX
> + *   try invalid values and check for EINVAL
> + *
> + * - The sched_rt_runtime_us range is -1 to INT_MAX
> + *   try invalid values and check for EINVAL
> + *
> + * - The sched_rt_runtime_us must be less or equal to sched_rt_period_us
> + *
> + * - Reset sched_rr_timeslice_ms to default value by writing -1 and check that
> + *   we get the default value on next read.
very nit: If you use dot at the end of this sentence, please add it also to the
previous sentences.

> + *
> + *   This is a regression test for a commit:
> + *
> + *   commit c1fc6484e1fb7cc2481d169bfef129a1b0676abe
> + *   Author: Cyril Hrubis <chrubis@suse.cz>
> + *   Date:   Wed Aug 2 17:19:06 2023 +0200
> + *
> + *       sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset

nit: this makes docparse formatting ugly. This would be nicer:
c1fc6484e1fb ("sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset")
(Unless we really prefer to have the date in the output, but in that case adding
a note which kernel version was fixing it would be IMHO more informative than
the date.)

> + */
> +
> +#include <stdio.h>
> +#include "tst_test.h"
> +
> +#define RT_PERIOD_US "/proc/sys/kernel/sched_rt_period_us"
> +#define RT_RUNTIME_US "/proc/sys/kernel/sched_rt_runtime_us"
> +#define RR_TIMESLICE_MS "/proc/sys/kernel/sched_rr_timeslice_ms"
> +
> +static int period_fd;
> +static int runtime_fd;
> +
> +static void rr_timeslice_ms_reset(void)
> +{
> +	long timeslice_ms;
> +
> +	SAFE_FILE_PRINTF(RR_TIMESLICE_MS, "-1");
> +	SAFE_FILE_SCANF(RR_TIMESLICE_MS, "%li", &timeslice_ms);
> +
> +	TST_EXP_EXPR(timeslice_ms > 0,
> +	             "timeslice_ms > 0 after reset to default");
> +}
> +
> +static void rt_period_us_einval(void)
> +{
> +	TST_EXP_FAIL(write(period_fd, "0", 2), EINVAL,
Why not 1 as 3rd write() parameter?

> +	             "echo 0 > "RT_PERIOD_US);
nit: I'd add blank line here (readability).
> +	TST_EXP_FAIL(write(period_fd, "-1", 2), EINVAL,
> +	             "echo -1 > "RT_PERIOD_US);
> +}
> +
> +static void rt_runtime_us_einval(void)
> +{
> +	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
> +	             "echo -2 > "RT_RUNTIME_US);
> +}
> +
> +static void rt_runtime_us_le_period_us(void)
> +{
> +	int period_us;
> +	char buf[32];
> +
> +	SAFE_FILE_SCANF(RT_PERIOD_US, "%i", &period_us);
> +
> +	sprintf(buf, "%i", period_us+1);
> +
> +	TST_EXP_FAIL(write(runtime_fd, buf, strlen(buf)), EINVAL,
> +	             "echo rt_period_us+1 > "RT_RUNTIME_US);
4x use of the same code, but I agree it's not worth of creating a function, as
the code is simple enough and probably more readable.

> +}
> +
> +static void verify_sched_proc(void)
> +{
Is there any value to print content of /proc/sys/kernel/sched_rt_runtime_us
before writing into it?

The rest LGTM.

Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr
Petr Vorel Sept. 1, 2023, 5:48 p.m. UTC | #3
Hi Cyril,

...
> +++ b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Sanity tests for the /proc/sys/kernel/sched_r* files.
> + *
> + * - The sched_rt_period_us range is 1 to INT_MAX
> + *   try invalid values and check for EINVAL
> + *
> + * - The sched_rt_runtime_us range is -1 to INT_MAX
> + *   try invalid values and check for EINVAL

As I wrote to the kernel patch, Documentation/scheduller/sched-rt-group.rst [1]
specifies this as values from -1 to (INT_MAX - 1).

Kind regards,
Petr

[1] https://www.kernel.org/doc/html/latest/scheduler/sched-rt-group.html#system-wide-settings
Richard Palethorpe Oct. 2, 2023, 8:26 a.m. UTC | #4
Hello,

[This is a resend because I had some network issues; sorry if it comes
through twice]

Cyril Hrubis <chrubis@suse.cz> writes:

> Currently the test fails due to kernel bug, I will send patch to LKML
> later on.
>
> The problem with kernel is that sysctl_sched_rt_period is unsigned int
> but it's processed with proc_dointvec() which means that you are allowed
> to write negative values into the variable even though documentation
> says it shouldn't be possible and the kernel code asserts that rt_period
> is > 0.
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>  runtest/sched                                 |   2 +
>  testcases/kernel/sched/sysctl/.gitignore      |   1 +
>  testcases/kernel/sched/sysctl/Makefile        |   7 ++
>  .../kernel/sched/sysctl/proc_sched_rt01.c     | 115 ++++++++++++++++++
>  4 files changed, 125 insertions(+)
>  create mode 100644 testcases/kernel/sched/sysctl/.gitignore
>  create mode 100644 testcases/kernel/sched/sysctl/Makefile
>  create mode 100644 testcases/kernel/sched/sysctl/proc_sched_rt01.c
>
> diff --git a/runtest/sched b/runtest/sched
> index 172fe4174..3457114f4 100644
> --- a/runtest/sched
> +++ b/runtest/sched
> @@ -16,3 +16,5 @@ sched_cli_serv run_sched_cliserv.sh
>  sched_stress sched_stress.sh
>  
>  autogroup01 autogroup01
> +
> +proc_sched_rt01
> diff --git a/testcases/kernel/sched/sysctl/.gitignore b/testcases/kernel/sched/sysctl/.gitignore
> new file mode 100644
> index 000000000..29b859b81
> --- /dev/null
> +++ b/testcases/kernel/sched/sysctl/.gitignore
> @@ -0,0 +1 @@
> +proc_sched_rt01
> diff --git a/testcases/kernel/sched/sysctl/Makefile b/testcases/kernel/sched/sysctl/Makefile
> new file mode 100644
> index 000000000..18896b6f2
> --- /dev/null
> +++ b/testcases/kernel/sched/sysctl/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/sched/sysctl/proc_sched_rt01.c b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
> new file mode 100644
> index 000000000..b30256792
> --- /dev/null
> +++ b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) Cyril Hrubis <chrubis@suse.cz>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Sanity tests for the /proc/sys/kernel/sched_r* files.
> + *
> + * - The sched_rt_period_us range is 1 to INT_MAX
> + *   try invalid values and check for EINVAL
> + *
> + * - The sched_rt_runtime_us range is -1 to INT_MAX
> + *   try invalid values and check for EINVAL
> + *
> + * - The sched_rt_runtime_us must be less or equal to sched_rt_period_us
> + *
> + * - Reset sched_rr_timeslice_ms to default value by writing -1 and check that
> + *   we get the default value on next read.
> + *
> + *   This is a regression test for a commit:
> + *
> + *   commit c1fc6484e1fb7cc2481d169bfef129a1b0676abe
> + *   Author: Cyril Hrubis <chrubis@suse.cz>
> + *   Date:   Wed Aug 2 17:19:06 2023 +0200
> + *
> + *       sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset
> + */
> +
> +#include <stdio.h>
> +#include "tst_test.h"
> +
> +#define RT_PERIOD_US "/proc/sys/kernel/sched_rt_period_us"
> +#define RT_RUNTIME_US "/proc/sys/kernel/sched_rt_runtime_us"
> +#define RR_TIMESLICE_MS "/proc/sys/kernel/sched_rr_timeslice_ms"
> +
> +static int period_fd;
> +static int runtime_fd;
> +
> +static void rr_timeslice_ms_reset(void)
> +{
> +	long timeslice_ms;
> +
> +	SAFE_FILE_PRINTF(RR_TIMESLICE_MS, "-1");
> +	SAFE_FILE_SCANF(RR_TIMESLICE_MS, "%li", &timeslice_ms);
> +
> +	TST_EXP_EXPR(timeslice_ms > 0,
> +	             "timeslice_ms > 0 after reset to default");
> +}
> +
> +static void rt_period_us_einval(void)
> +{
> +	TST_EXP_FAIL(write(period_fd, "0", 2), EINVAL,
> +	             "echo 0 > "RT_PERIOD_US);
> +	TST_EXP_FAIL(write(period_fd, "-1", 2), EINVAL,
> +	             "echo -1 > "RT_PERIOD_US);
> +}
> +
> +static void rt_runtime_us_einval(void)
> +{
> +	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
> +	             "echo -2 > "RT_RUNTIME_US);
> +}

I would happily add my tags to the test except that as a general
principal, I don't want to deal with tests that fail if an unexpected
error number is returned.

Unless something can be done (e.g. with meta-data), so that TST_EXP_FAIL
and similar can be reduced to a TCONF when the wrong errno is returned.

For instance, this would allow running the tests with a seccomp BPF
profile, LSM, CGroup or /proc bind mount that blocks the write.

Or you could just seperate the tests I guess. Then the reset can be
checked while skipping the errno checks.

> +
> +static void rt_runtime_us_le_period_us(void)
> +{
> +	int period_us;
> +	char buf[32];
> +
> +	SAFE_FILE_SCANF(RT_PERIOD_US, "%i", &period_us);
> +
> +	sprintf(buf, "%i", period_us+1);
> +
> +	TST_EXP_FAIL(write(runtime_fd, buf, strlen(buf)), EINVAL,
> +	             "echo rt_period_us+1 > "RT_RUNTIME_US);
> +}
> +
> +static void verify_sched_proc(void)
> +{
> +	rr_timeslice_ms_reset();
> +	rt_period_us_einval();
> +	rt_runtime_us_einval();
> +	rt_runtime_us_le_period_us();
> +}
> +
> +static void setup(void)
> +{
> +	period_fd = open(RT_PERIOD_US, O_RDWR);
> +	runtime_fd = open(RT_RUNTIME_US, O_RDWR);
> +}
> +
> +static void cleanup(void)
> +{
> +	if (period_fd > 0)
> +		SAFE_CLOSE(period_fd);
> +
> +	if (runtime_fd > 0)
> +		SAFE_CLOSE(runtime_fd);
> +}
> +
> +static struct tst_test test = {
> +	.needs_root = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_sched_proc,
> +	.tags = (struct tst_tag []) {
> +		{"linux-git", "c1fc6484e1fb"},
> +		{}
> +	},
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_SYSCTL",
> +		NULL
> +	},
> +};
> -- 
> 2.41.0
Cyril Hrubis Oct. 2, 2023, 11:09 a.m. UTC | #5
Hi!
> > +static void rt_runtime_us_einval(void)
> > +{
> > +	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
> > +	             "echo -2 > "RT_RUNTIME_US);
> > +}
> 
> I would happily add my tags to the test except that as a general
> principal, I don't want to deal with tests that fail if an unexpected
> error number is returned.
> 
> Unless something can be done (e.g. with meta-data), so that TST_EXP_FAIL
> and similar can be reduced to a TCONF when the wrong errno is returned.
> 
> For instance, this would allow running the tests with a seccomp BPF
> profile, LSM, CGroup or /proc bind mount that blocks the write.
> 
> Or you could just seperate the tests I guess. Then the reset can be
> checked while skipping the errno checks.

Hmm, so I guess that with LSM we are able to open these files R/W but we
can stil get EPERM from the write() right? I'm reluctant to add wildcard
TCONF on any errno, but I guess that we can add a TST_EXP_FAIL macro
version that would have one errno for PASS and one errno for TCONF.
Richard Palethorpe Oct. 3, 2023, 8:18 a.m. UTC | #6
Hello,

Cyril Hrubis <chrubis@suse.cz> writes:

> Hi!
>> > +static void rt_runtime_us_einval(void)
>> > +{
>> > +	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
>> > +	             "echo -2 > "RT_RUNTIME_US);
>> > +}
>> 
>> I would happily add my tags to the test except that as a general
>> principal, I don't want to deal with tests that fail if an unexpected
>> error number is returned.
>> 
>> Unless something can be done (e.g. with meta-data), so that TST_EXP_FAIL
>> and similar can be reduced to a TCONF when the wrong errno is returned.
>> 
>> For instance, this would allow running the tests with a seccomp BPF
>> profile, LSM, CGroup or /proc bind mount that blocks the write.
>> 
>> Or you could just seperate the tests I guess. Then the reset can be
>> checked while skipping the errno checks.
>
> Hmm, so I guess that with LSM we are able to open these files R/W but we
> can stil get EPERM from the write() right?

Sorry, I thought there was an LSM hook in read, but AFAICT there is
not. It's possible that another hook get's called
(e.g. security_inode_getattr), but it's not immediately clear to me.

This still leaves seccomp bpf, FUSE, kernel module, etc. whatever is
mounted at /proc doesn't have to be the original file system. Container
runtimes do something with /proc to filter it. This situation seems to
get more complicated each year.

> I'm reluctant to add wildcard
> TCONF on any errno, but I guess that we can add a TST_EXP_FAIL macro
> version that would have one errno for PASS and one errno for TCONF.

I'm leaning increasingly towards partitioning the test, so that bits can
be filtered out somehow. Then people can focus on the bits they really
care about.
Cyril Hrubis Oct. 3, 2023, 8:54 a.m. UTC | #7
Hi!
> Hmm, so I guess that with LSM we are able to open these files R/W but we
> can stil get EPERM from the write() right? I'm reluctant to add wildcard
> TCONF on any errno, but I guess that we can add a TST_EXP_FAIL macro
> version that would have one errno for PASS and one errno for TCONF.

I was thinking about this yesterday and maybe best solution would be to
introduce a global switch (env variable) that would switch the
TST_EXP_FAIL() macros to a more forgiving mode so that EINVAL and EPERM
and possibly a few more errnos would be converted into TCONF
automatically. What do you think?
Richard Palethorpe Oct. 4, 2023, 9:22 a.m. UTC | #8
Hello,

Cyril Hrubis <chrubis@suse.cz> writes:

> Hi!
>> Hmm, so I guess that with LSM we are able to open these files R/W but we
>> can stil get EPERM from the write() right? I'm reluctant to add wildcard
>> TCONF on any errno, but I guess that we can add a TST_EXP_FAIL macro
>> version that would have one errno for PASS and one errno for TCONF.
>
> I was thinking about this yesterday and maybe best solution would be to
> introduce a global switch (env variable) that would switch the
> TST_EXP_FAIL() macros to a more forgiving mode so that EINVAL and EPERM
> and possibly a few more errnos would be converted into TCONF
> automatically. What do you think?

It sounds reasonable, I think it would also make sense to have an option
to allow any value in the full errno range.
diff mbox series

Patch

diff --git a/runtest/sched b/runtest/sched
index 172fe4174..3457114f4 100644
--- a/runtest/sched
+++ b/runtest/sched
@@ -16,3 +16,5 @@  sched_cli_serv run_sched_cliserv.sh
 sched_stress sched_stress.sh
 
 autogroup01 autogroup01
+
+proc_sched_rt01
diff --git a/testcases/kernel/sched/sysctl/.gitignore b/testcases/kernel/sched/sysctl/.gitignore
new file mode 100644
index 000000000..29b859b81
--- /dev/null
+++ b/testcases/kernel/sched/sysctl/.gitignore
@@ -0,0 +1 @@ 
+proc_sched_rt01
diff --git a/testcases/kernel/sched/sysctl/Makefile b/testcases/kernel/sched/sysctl/Makefile
new file mode 100644
index 000000000..18896b6f2
--- /dev/null
+++ b/testcases/kernel/sched/sysctl/Makefile
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/sched/sysctl/proc_sched_rt01.c b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
new file mode 100644
index 000000000..b30256792
--- /dev/null
+++ b/testcases/kernel/sched/sysctl/proc_sched_rt01.c
@@ -0,0 +1,115 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * [Description]
+ *
+ * Sanity tests for the /proc/sys/kernel/sched_r* files.
+ *
+ * - The sched_rt_period_us range is 1 to INT_MAX
+ *   try invalid values and check for EINVAL
+ *
+ * - The sched_rt_runtime_us range is -1 to INT_MAX
+ *   try invalid values and check for EINVAL
+ *
+ * - The sched_rt_runtime_us must be less or equal to sched_rt_period_us
+ *
+ * - Reset sched_rr_timeslice_ms to default value by writing -1 and check that
+ *   we get the default value on next read.
+ *
+ *   This is a regression test for a commit:
+ *
+ *   commit c1fc6484e1fb7cc2481d169bfef129a1b0676abe
+ *   Author: Cyril Hrubis <chrubis@suse.cz>
+ *   Date:   Wed Aug 2 17:19:06 2023 +0200
+ *
+ *       sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset
+ */
+
+#include <stdio.h>
+#include "tst_test.h"
+
+#define RT_PERIOD_US "/proc/sys/kernel/sched_rt_period_us"
+#define RT_RUNTIME_US "/proc/sys/kernel/sched_rt_runtime_us"
+#define RR_TIMESLICE_MS "/proc/sys/kernel/sched_rr_timeslice_ms"
+
+static int period_fd;
+static int runtime_fd;
+
+static void rr_timeslice_ms_reset(void)
+{
+	long timeslice_ms;
+
+	SAFE_FILE_PRINTF(RR_TIMESLICE_MS, "-1");
+	SAFE_FILE_SCANF(RR_TIMESLICE_MS, "%li", &timeslice_ms);
+
+	TST_EXP_EXPR(timeslice_ms > 0,
+	             "timeslice_ms > 0 after reset to default");
+}
+
+static void rt_period_us_einval(void)
+{
+	TST_EXP_FAIL(write(period_fd, "0", 2), EINVAL,
+	             "echo 0 > "RT_PERIOD_US);
+	TST_EXP_FAIL(write(period_fd, "-1", 2), EINVAL,
+	             "echo -1 > "RT_PERIOD_US);
+}
+
+static void rt_runtime_us_einval(void)
+{
+	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
+	             "echo -2 > "RT_RUNTIME_US);
+}
+
+static void rt_runtime_us_le_period_us(void)
+{
+	int period_us;
+	char buf[32];
+
+	SAFE_FILE_SCANF(RT_PERIOD_US, "%i", &period_us);
+
+	sprintf(buf, "%i", period_us+1);
+
+	TST_EXP_FAIL(write(runtime_fd, buf, strlen(buf)), EINVAL,
+	             "echo rt_period_us+1 > "RT_RUNTIME_US);
+}
+
+static void verify_sched_proc(void)
+{
+	rr_timeslice_ms_reset();
+	rt_period_us_einval();
+	rt_runtime_us_einval();
+	rt_runtime_us_le_period_us();
+}
+
+static void setup(void)
+{
+	period_fd = open(RT_PERIOD_US, O_RDWR);
+	runtime_fd = open(RT_RUNTIME_US, O_RDWR);
+}
+
+static void cleanup(void)
+{
+	if (period_fd > 0)
+		SAFE_CLOSE(period_fd);
+
+	if (runtime_fd > 0)
+		SAFE_CLOSE(runtime_fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_sched_proc,
+	.tags = (struct tst_tag []) {
+		{"linux-git", "c1fc6484e1fb"},
+		{}
+	},
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_SYSCTL",
+		NULL
+	},
+};