[LTP] [PATCH v1] syscalls/ioprio: add ioprio_get/ioprio_set tests

Cyril Hrubis chrubis@suse.cz
Thu Apr 11 11:07:17 CEST 2019


Hi!
> Signed-off-by: Christian Amann <camann@suse.com>
> ---
>  testcases/kernel/syscalls/ioprio/.gitignore |   2 +
>  testcases/kernel/syscalls/ioprio/Makefile   |  14 ++++
>  testcases/kernel/syscalls/ioprio/ioprio01.c | 106 ++++++++++++++++++++++++++++
>  testcases/kernel/syscalls/ioprio/ioprio02.c |  88 +++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 testcases/kernel/syscalls/ioprio/.gitignore
>  create mode 100644 testcases/kernel/syscalls/ioprio/Makefile
>  create mode 100644 testcases/kernel/syscalls/ioprio/ioprio01.c
>  create mode 100644 testcases/kernel/syscalls/ioprio/ioprio02.c
> 
> diff --git a/testcases/kernel/syscalls/ioprio/.gitignore b/testcases/kernel/syscalls/ioprio/.gitignore
> new file mode 100644
> index 000000000..35e759777
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ioprio/.gitignore
> @@ -0,0 +1,2 @@
> +/ioprio01
> +/ioprio02
> diff --git a/testcases/kernel/syscalls/ioprio/Makefile b/testcases/kernel/syscalls/ioprio/Makefile
> new file mode 100644
> index 000000000..d89eb7797
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ioprio/Makefile
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +#   Copyright (c) 2019 SUSE LLC
> +#
> +#   Author: Christian Amann <camann@suse.com>
> +#
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> +
> +ioprio01: CFLAGS += -pthread
> diff --git a/testcases/kernel/syscalls/ioprio/ioprio01.c b/testcases/kernel/syscalls/ioprio/ioprio01.c
> new file mode 100644
> index 000000000..b35dcd09e
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ioprio/ioprio01.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 SUSE LLC
> + * Author: Christian Amann <camann@suse.com>
> + *
> + */
> +
> +/*
> + * Tests the functionality to set I/O priority using
> + * ioprio_set and then checks if it was set correctly
> + * using ioprio_get
> + *
> + * 1) Set the priority using the process ID to best-effort scheduling
> + * 2) Set the priority using the process ID to idle scheduling
> + * 3) Set the priority using the group ID to best-effort scheduling
> + * 4) Set the priority using the ID of a thread to real-time scheduling
> + * 5) Set the priority using the user ID to best-effort scheduling
> + *
> + */
> +
> +#include <stdlib.h>
> +#include "config.h"
> +#include "tst_test.h"
> +#include "tst_safe_pthread.h"
> +#include "lapi/syscalls.h"
> +#include "sys/types.h"

This shuld be <sys/types.h> since it's system header.

> +#include "../utils/ioprio.h"

Definitions from this header should be moved to lapi/ioprio.h

> +#define gettid() tst_syscall(__NR_gettid)
> +
> +static int uid;
> +static int pid;
> +static int gid;
> +static int tid;
> +
> +static struct tcase {
> +	int	which;
> +	int	*who;
> +	int	priority;
> +	int	sched_class;
> +} tcases[] = {
> +	{IOPRIO_WHO_PROCESS, &pid, 0, IOPRIO_CLASS_BE},
> +	{IOPRIO_WHO_PROCESS, &pid, 7, IOPRIO_CLASS_IDLE},
> +	{IOPRIO_WHO_PGRP, &gid, 0, IOPRIO_CLASS_BE},
> +	{IOPRIO_WHO_PROCESS, &tid, 7, IOPRIO_CLASS_RT},
> +	{IOPRIO_WHO_USER, &uid, 3, IOPRIO_CLASS_BE},
> +};
> +
> +static int sys_ioprio_get(int which, int who)
> +{
> +	return tst_syscall(__NR_ioprio_get, which, who);
> +}
> +static int sys_ioprio_set(int which, int who, int ioprio)
> +{
> +	return tst_syscall(__NR_ioprio_set, which, who, ioprio);
> +}

And these wrappers should be put into the lapi/ioprio.h header as well.

> +static void verify_ioprio(unsigned int n)
> +{
> +	struct tcase *tc = &tcases[n];
> +	int setIOprio, getIOprio;

Mixed case is frowned upon in LKML coding style, set_io_prio and
get_io_prio.

> +	setIOprio = IOPRIO_PRIO_VALUE(tc->sched_class, tc->priority);
> +
> +	TEST(sys_ioprio_set(tc->which, *tc->who, setIOprio));
> +
> +	if (TST_RET != 0) {
> +		tst_res(TFAIL, "ioprio_set failed with error %s",
> +				tst_strerrno(TST_ERR));
> +		return;
> +	}
> +
> +	TEST(getIOprio = sys_ioprio_get(tc->which, *tc->who));

If you use the TEST() macro the return value is stored in TST_RET and
errno in TST_ERR, which is the whole point of the macro, assigning the
return value to a variable inside of that macro defeats its purpose.

> +	if (setIOprio != getIOprio) {
> +		tst_res(TFAIL, "ioprio_get returned wrong IO priority");
> +		return;
> +	}
> +
> +	tst_res(TPASS, "ioprio_set set correct IO priority");
> +}
> +
> +static void io_thread(void)
> +{
> +	tid = gettid();
> +	pause();
> +}
> +
> +static void setup(void)
> +{
> +	uid = getuid();
> +	gid = getgid();
> +	pid = getpid();
> +	pthread_t thread;
> +
> +	SAFE_PTHREAD_CREATE(&thread, NULL,
> +			(void * (*)(void *)) io_thread, NULL);

This cast is ugly, what we generally do in LTP is to match prototype
function and avoid warnings with this trick:


static void *thread_fn(void *unused)
{
	...

	return unused;
}

> +}
> +
> +static struct tst_test test = {
> +	.test = verify_ioprio,
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.setup = setup,
> +	.needs_root = 1,
> +	.min_kver = "2.6.13",
> +};

The same minor comments apply to the second test as well.


Also I do wonder if we can write a functional test for the syscall, I
guess that we can run two threads doing I/O with a different priorities
and check if the one with higher priority did more.

-- 
Cyril Hrubis
chrubis@suse.cz


More information about the ltp mailing list