diff mbox series

[V10,1/2] syscalls/semtimedop: Add support for semtimedop and its time64 version

Message ID 551441b4bce2d9dfd1567ffcd536f50f14a049d0.1599041148.git.viresh.kumar@linaro.org
State Superseded
Headers show
Series [V10,1/2] syscalls/semtimedop: Add support for semtimedop and its time64 version | expand

Commit Message

Viresh Kumar Sept. 2, 2020, 10:10 a.m. UTC
This adds support for semtimedop() and its time64 variant to the
existing semop() syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V10:
- Update comment in semop02.c.
- Let callers call tst_ts_get() on the timeout.

 testcases/kernel/syscalls/ipc/semop/semop.h   | 55 +++++++++++++++++++
 testcases/kernel/syscalls/ipc/semop/semop01.c | 26 ++++++++-
 testcases/kernel/syscalls/ipc/semop/semop02.c | 44 +++++++++++----
 testcases/kernel/syscalls/ipc/semop/semop03.c | 15 ++++-
 4 files changed, 125 insertions(+), 15 deletions(-)
 create mode 100644 testcases/kernel/syscalls/ipc/semop/semop.h

Comments

Cyril Hrubis Sept. 2, 2020, 11:58 a.m. UTC | #1
Hi!
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V10:
> - Update comment in semop02.c.
> - Let callers call tst_ts_get() on the timeout.
> 
>  testcases/kernel/syscalls/ipc/semop/semop.h   | 55 +++++++++++++++++++
>  testcases/kernel/syscalls/ipc/semop/semop01.c | 26 ++++++++-
>  testcases/kernel/syscalls/ipc/semop/semop02.c | 44 +++++++++++----
>  testcases/kernel/syscalls/ipc/semop/semop03.c | 15 ++++-
>  4 files changed, 125 insertions(+), 15 deletions(-)
>  create mode 100644 testcases/kernel/syscalls/ipc/semop/semop.h
> 
> diff --git a/testcases/kernel/syscalls/ipc/semop/semop.h b/testcases/kernel/syscalls/ipc/semop/semop.h
> new file mode 100644
> index 000000000000..1fac31818108
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/semop/semop.h
> @@ -0,0 +1,55 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#ifndef SEMOP_VAR__
> +#define SEMOP_VAR__
> +
> +#include <sys/sem.h>
> +#include "tst_timer.h"
> +
> +static inline int sys_semtimedop(int semid, struct sembuf *sops, size_t nsops,
> +		void *timeout)
> +{
> +	return tst_syscall(__NR_semtimedop, semid, sops, nsops, timeout);
> +}
> +
> +static inline int sys_semtimedop_time64(int semid, struct sembuf *sops,
> +					size_t nsops, void *timeout)
> +{
> +	return tst_syscall(__NR_semtimedop_time64, semid, sops, nsops, timeout);
> +}
> +
> +struct test_variants {
> +	int (*semop)(int semid, struct sembuf *sops, size_t nsops);
> +	int (*semtimedop)(int semid, struct sembuf *sops, size_t nsops, void *timeout);
> +	enum tst_ts_type type;
> +	char *desc;
> +} variants[] = {
> +	{ .semop = semop, .type = TST_LIBC_TIMESPEC, .desc = "semop: syscall"},
> +
> +#if (__NR_semtimedop != __LTP__NR_INVALID_SYSCALL)
> +	{ .semtimedop = sys_semtimedop, .type = TST_KERN_OLD_TIMESPEC, .desc = "semtimedop: syscall with old kernel spec"},
> +#endif
> +
> +#if (__NR_semtimedop_time64 != __LTP__NR_INVALID_SYSCALL)
> +	{ .semtimedop = sys_semtimedop_time64, .type = TST_KERN_TIMESPEC, .desc = "semtimedop: syscall time64 with kernel spec"},
> +#endif
> +};
> +
> +static inline int call_semop(struct test_variants *tv, int semid,
> +		struct sembuf *sops, size_t nsops, void *timeout)
> +{
> +	if (tv->semop)
> +		return tv->semop(semid, sops, nsops);
> +
> +	return tv->semtimedop(semid, sops, nsops, timeout);
> +}
> +
> +static inline void semop_supported_by_kernel(struct test_variants *tv)
> +{
> +       /* Check if the syscall is implemented on the platform */
> +       TEST(call_semop(tv, 0, NULL, 0, NULL));
> +       if (TST_RET == -1 && TST_ERR == ENOSYS)
> +               tst_brk(TCONF, "Test not supported on kernel/platform");
> +}
> +
> +#endif /* SEMOP_VAR__ */
> diff --git a/testcases/kernel/syscalls/ipc/semop/semop01.c b/testcases/kernel/syscalls/ipc/semop/semop01.c
> index 2daf6bbc5c4e..0524a8098e23 100644
> --- a/testcases/kernel/syscalls/ipc/semop/semop01.c
> +++ b/testcases/kernel/syscalls/ipc/semop/semop01.c
> @@ -12,6 +12,7 @@
>  #include "tst_test.h"
>  #include "libnewipc.h"
>  #include "lapi/semun.h"
> +#include "semop.h"
>  
>  #define NSEMS 4
>  
> @@ -21,14 +22,23 @@ static key_t semkey;
>  static unsigned short int sarr[PSEMS];
>  static union semun get_arr = {.array = sarr};
>  static struct sembuf sops[PSEMS];
> +static struct tst_ts timeout;
>  
> -static void run(void)
> +static struct test_case_t {
> +	struct tst_ts *to;
> +} tc[] = {
> +	{NULL},
> +	{&timeout}
> +};
> +
> +static void run(unsigned int n)
>  {
> +	struct test_variants *tv = &variants[tst_variant];
>  	union semun arr = { .val = 0 };
>  	int fail = 0;
>  	int i;
>  
> -	TEST(semop(sem_id, sops, NSEMS));
> +	TEST(call_semop(tv, sem_id, sops, NSEMS, tst_ts_get(tc[n].to)));
>  	if (TST_RET == -1) {
>  		tst_res(TFAIL | TTERRNO, "semop() failed");
>  		return;
> @@ -56,8 +66,16 @@ static void run(void)
>  
>  static void setup(void)
>  {
> +	struct test_variants *tv = &variants[tst_variant];
>  	int i;
>  
> +	tst_res(TINFO, "Testing variant: %s", tv->desc);
> +	semop_supported_by_kernel(tv);
> +
> +	timeout.type = tv->type;
> +	tst_ts_set_sec(&timeout, 1);
> +	tst_ts_set_nsec(&timeout, 10000);
> +
>  	semkey = GETIPCKEY();
>  
>  	sem_id = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
> @@ -80,7 +98,9 @@ static void cleanup(void)
>  }
>  
>  static struct tst_test test = {
> -	.test_all = run,
> +	.test = run,
> +	.tcnt = ARRAY_SIZE(tc),
> +	.test_variants = ARRAY_SIZE(variants),
>  	.setup = setup,
>  	.cleanup = cleanup,
>  	.needs_tmpdir = 1,
> diff --git a/testcases/kernel/syscalls/ipc/semop/semop02.c b/testcases/kernel/syscalls/ipc/semop/semop02.c
> index 0dff8e537719..22fdb5cbef4c 100644
> --- a/testcases/kernel/syscalls/ipc/semop/semop02.c
> +++ b/testcases/kernel/syscalls/ipc/semop/semop02.c
> @@ -10,6 +10,8 @@
>   * EFBIG   - sem_num > number of semaphores in a set
>   * EAGAIN  - semop = 0 for non-zero semaphore and IPC_NOWAIT passed in flags
>   * EAGAIN  - semop = -1 for zero semaphore and IPC_NOWAIT passed in flags
> + * EAGAIN  - semop = 0 and timeout happens
> + * EAGAIN  - semop = -1 and timeout happens
>   *
>   * Copyright (c) International Business Machines  Corp., 2001
>   *	03/2001 - Written by Wayne Boyer
> @@ -23,17 +25,20 @@
>  #include "tst_test.h"
>  #include "libnewipc.h"
>  #include "lapi/semun.h"
> +#include "semop.h"
>  
>  static int valid_sem_id = -1;
>  static int noperm_sem_id = -1;
>  static int bad_sem_id = -1;
>  static short sem_op_max, sem_op_1 = 1, sem_op_negative = -1, sem_op_zero = 0;
>  static struct sembuf *faulty_buf;
> +static struct tst_ts timeout;
>  
>  #define NSOPS	1
>  #define	BIGOPS	1024
>  
>  static struct test_case_t {
> +	int all_variants;

Something as needs_timeout, or semtimedop_only would be a bit more
descriptive.

>  	int *semid;
>  	struct sembuf **buf;
>  	short *sem_op;
> @@ -44,25 +49,35 @@ static struct test_case_t {
>  	int arr_val;
>  	int error;
>  } tc[] = {
> -	{&valid_sem_id, NULL, &sem_op_1, 0, 0, 0, BIGOPS, 1, E2BIG},
> -	{&noperm_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EACCES},
> -	{&valid_sem_id, &faulty_buf, &sem_op_1, 0, 0, 0, NSOPS, 1, EFAULT},
> -	{&valid_sem_id, NULL, &sem_op_1, 0, 0, 0, 0, 1, EINVAL},
> -	{&bad_sem_id,   NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EINVAL},
> -	{&valid_sem_id, NULL, &sem_op_max, 0, 0, 0, 1, 1, ERANGE},
> -	{&valid_sem_id, NULL, &sem_op_1, 0, -1, SEM_UNDO, 1, 1, EFBIG},
> -	{&valid_sem_id, NULL, &sem_op_1, 0, PSEMS + 1, SEM_UNDO, 1, 1, EFBIG},
> -	{&valid_sem_id, NULL, &sem_op_zero, 2, 2, IPC_NOWAIT, 1, 1, EAGAIN},
> -	{&valid_sem_id, NULL, &sem_op_negative, 2, 2, IPC_NOWAIT, 1, 0, EAGAIN}
> +	{1, &valid_sem_id, NULL, &sem_op_1, 0, 0, 0, BIGOPS, 1, E2BIG},
> +	{1, &noperm_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EACCES},
> +	{1, &valid_sem_id, &faulty_buf, &sem_op_1, 0, 0, 0, NSOPS, 1, EFAULT},
> +	{1, &valid_sem_id, NULL, &sem_op_1, 0, 0, 0, 0, 1, EINVAL},
> +	{1, &bad_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EINVAL},
> +	{1, &valid_sem_id, NULL, &sem_op_max, 0, 0, 0, 1, 1, ERANGE},
> +	{1, &valid_sem_id, NULL, &sem_op_1, 0, -1, SEM_UNDO, 1, 1, EFBIG},
> +	{1, &valid_sem_id, NULL, &sem_op_1, 0, PSEMS + 1, SEM_UNDO, 1, 1, EFBIG},
> +	{1, &valid_sem_id, NULL, &sem_op_zero, 2, 2, IPC_NOWAIT, 1, 1, EAGAIN},
> +	{1, &valid_sem_id, NULL, &sem_op_negative, 2, 2, IPC_NOWAIT, 1, 0, EAGAIN},
> +	{0, &valid_sem_id, NULL, &sem_op_zero, 0, 0, SEM_UNDO, 1, 1, EAGAIN},
> +	{0, &valid_sem_id, NULL, &sem_op_negative, 0, 0, SEM_UNDO, 1, 0, EAGAIN},
>  };
>  
>  static void setup(void)
>  {
> +	struct test_variants *tv = &variants[tst_variant];
>  	struct passwd *ltpuser;
>  	key_t semkey;
>  	union semun arr;
>  	struct seminfo ipc_buf;
>  
> +	tst_res(TINFO, "Testing variant: %s", tv->desc);
> +	semop_supported_by_kernel(tv);
> +
> +	timeout.type = tv->type;
> +	tst_ts_set_sec(&timeout, 1);
> +	tst_ts_set_nsec(&timeout, 10000);

One second is way too much, can we please make it just 10000ns ?

LTP runs on many automated labs, adding a useless second to a test adds
up to years of wasted runtime.
diff mbox series

Patch

diff --git a/testcases/kernel/syscalls/ipc/semop/semop.h b/testcases/kernel/syscalls/ipc/semop/semop.h
new file mode 100644
index 000000000000..1fac31818108
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/semop/semop.h
@@ -0,0 +1,55 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef SEMOP_VAR__
+#define SEMOP_VAR__
+
+#include <sys/sem.h>
+#include "tst_timer.h"
+
+static inline int sys_semtimedop(int semid, struct sembuf *sops, size_t nsops,
+		void *timeout)
+{
+	return tst_syscall(__NR_semtimedop, semid, sops, nsops, timeout);
+}
+
+static inline int sys_semtimedop_time64(int semid, struct sembuf *sops,
+					size_t nsops, void *timeout)
+{
+	return tst_syscall(__NR_semtimedop_time64, semid, sops, nsops, timeout);
+}
+
+struct test_variants {
+	int (*semop)(int semid, struct sembuf *sops, size_t nsops);
+	int (*semtimedop)(int semid, struct sembuf *sops, size_t nsops, void *timeout);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+	{ .semop = semop, .type = TST_LIBC_TIMESPEC, .desc = "semop: syscall"},
+
+#if (__NR_semtimedop != __LTP__NR_INVALID_SYSCALL)
+	{ .semtimedop = sys_semtimedop, .type = TST_KERN_OLD_TIMESPEC, .desc = "semtimedop: syscall with old kernel spec"},
+#endif
+
+#if (__NR_semtimedop_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .semtimedop = sys_semtimedop_time64, .type = TST_KERN_TIMESPEC, .desc = "semtimedop: syscall time64 with kernel spec"},
+#endif
+};
+
+static inline int call_semop(struct test_variants *tv, int semid,
+		struct sembuf *sops, size_t nsops, void *timeout)
+{
+	if (tv->semop)
+		return tv->semop(semid, sops, nsops);
+
+	return tv->semtimedop(semid, sops, nsops, timeout);
+}
+
+static inline void semop_supported_by_kernel(struct test_variants *tv)
+{
+       /* Check if the syscall is implemented on the platform */
+       TEST(call_semop(tv, 0, NULL, 0, NULL));
+       if (TST_RET == -1 && TST_ERR == ENOSYS)
+               tst_brk(TCONF, "Test not supported on kernel/platform");
+}
+
+#endif /* SEMOP_VAR__ */
diff --git a/testcases/kernel/syscalls/ipc/semop/semop01.c b/testcases/kernel/syscalls/ipc/semop/semop01.c
index 2daf6bbc5c4e..0524a8098e23 100644
--- a/testcases/kernel/syscalls/ipc/semop/semop01.c
+++ b/testcases/kernel/syscalls/ipc/semop/semop01.c
@@ -12,6 +12,7 @@ 
 #include "tst_test.h"
 #include "libnewipc.h"
 #include "lapi/semun.h"
+#include "semop.h"
 
 #define NSEMS 4
 
@@ -21,14 +22,23 @@  static key_t semkey;
 static unsigned short int sarr[PSEMS];
 static union semun get_arr = {.array = sarr};
 static struct sembuf sops[PSEMS];
+static struct tst_ts timeout;
 
-static void run(void)
+static struct test_case_t {
+	struct tst_ts *to;
+} tc[] = {
+	{NULL},
+	{&timeout}
+};
+
+static void run(unsigned int n)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	union semun arr = { .val = 0 };
 	int fail = 0;
 	int i;
 
-	TEST(semop(sem_id, sops, NSEMS));
+	TEST(call_semop(tv, sem_id, sops, NSEMS, tst_ts_get(tc[n].to)));
 	if (TST_RET == -1) {
 		tst_res(TFAIL | TTERRNO, "semop() failed");
 		return;
@@ -56,8 +66,16 @@  static void run(void)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	int i;
 
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+	semop_supported_by_kernel(tv);
+
+	timeout.type = tv->type;
+	tst_ts_set_sec(&timeout, 1);
+	tst_ts_set_nsec(&timeout, 10000);
+
 	semkey = GETIPCKEY();
 
 	sem_id = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
@@ -80,7 +98,9 @@  static void cleanup(void)
 }
 
 static struct tst_test test = {
-	.test_all = run,
+	.test = run,
+	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.cleanup = cleanup,
 	.needs_tmpdir = 1,
diff --git a/testcases/kernel/syscalls/ipc/semop/semop02.c b/testcases/kernel/syscalls/ipc/semop/semop02.c
index 0dff8e537719..22fdb5cbef4c 100644
--- a/testcases/kernel/syscalls/ipc/semop/semop02.c
+++ b/testcases/kernel/syscalls/ipc/semop/semop02.c
@@ -10,6 +10,8 @@ 
  * EFBIG   - sem_num > number of semaphores in a set
  * EAGAIN  - semop = 0 for non-zero semaphore and IPC_NOWAIT passed in flags
  * EAGAIN  - semop = -1 for zero semaphore and IPC_NOWAIT passed in flags
+ * EAGAIN  - semop = 0 and timeout happens
+ * EAGAIN  - semop = -1 and timeout happens
  *
  * Copyright (c) International Business Machines  Corp., 2001
  *	03/2001 - Written by Wayne Boyer
@@ -23,17 +25,20 @@ 
 #include "tst_test.h"
 #include "libnewipc.h"
 #include "lapi/semun.h"
+#include "semop.h"
 
 static int valid_sem_id = -1;
 static int noperm_sem_id = -1;
 static int bad_sem_id = -1;
 static short sem_op_max, sem_op_1 = 1, sem_op_negative = -1, sem_op_zero = 0;
 static struct sembuf *faulty_buf;
+static struct tst_ts timeout;
 
 #define NSOPS	1
 #define	BIGOPS	1024
 
 static struct test_case_t {
+	int all_variants;
 	int *semid;
 	struct sembuf **buf;
 	short *sem_op;
@@ -44,25 +49,35 @@  static struct test_case_t {
 	int arr_val;
 	int error;
 } tc[] = {
-	{&valid_sem_id, NULL, &sem_op_1, 0, 0, 0, BIGOPS, 1, E2BIG},
-	{&noperm_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EACCES},
-	{&valid_sem_id, &faulty_buf, &sem_op_1, 0, 0, 0, NSOPS, 1, EFAULT},
-	{&valid_sem_id, NULL, &sem_op_1, 0, 0, 0, 0, 1, EINVAL},
-	{&bad_sem_id,   NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EINVAL},
-	{&valid_sem_id, NULL, &sem_op_max, 0, 0, 0, 1, 1, ERANGE},
-	{&valid_sem_id, NULL, &sem_op_1, 0, -1, SEM_UNDO, 1, 1, EFBIG},
-	{&valid_sem_id, NULL, &sem_op_1, 0, PSEMS + 1, SEM_UNDO, 1, 1, EFBIG},
-	{&valid_sem_id, NULL, &sem_op_zero, 2, 2, IPC_NOWAIT, 1, 1, EAGAIN},
-	{&valid_sem_id, NULL, &sem_op_negative, 2, 2, IPC_NOWAIT, 1, 0, EAGAIN}
+	{1, &valid_sem_id, NULL, &sem_op_1, 0, 0, 0, BIGOPS, 1, E2BIG},
+	{1, &noperm_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EACCES},
+	{1, &valid_sem_id, &faulty_buf, &sem_op_1, 0, 0, 0, NSOPS, 1, EFAULT},
+	{1, &valid_sem_id, NULL, &sem_op_1, 0, 0, 0, 0, 1, EINVAL},
+	{1, &bad_sem_id, NULL, &sem_op_1, 0, 0, 0, NSOPS, 1, EINVAL},
+	{1, &valid_sem_id, NULL, &sem_op_max, 0, 0, 0, 1, 1, ERANGE},
+	{1, &valid_sem_id, NULL, &sem_op_1, 0, -1, SEM_UNDO, 1, 1, EFBIG},
+	{1, &valid_sem_id, NULL, &sem_op_1, 0, PSEMS + 1, SEM_UNDO, 1, 1, EFBIG},
+	{1, &valid_sem_id, NULL, &sem_op_zero, 2, 2, IPC_NOWAIT, 1, 1, EAGAIN},
+	{1, &valid_sem_id, NULL, &sem_op_negative, 2, 2, IPC_NOWAIT, 1, 0, EAGAIN},
+	{0, &valid_sem_id, NULL, &sem_op_zero, 0, 0, SEM_UNDO, 1, 1, EAGAIN},
+	{0, &valid_sem_id, NULL, &sem_op_negative, 0, 0, SEM_UNDO, 1, 0, EAGAIN},
 };
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	struct passwd *ltpuser;
 	key_t semkey;
 	union semun arr;
 	struct seminfo ipc_buf;
 
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+	semop_supported_by_kernel(tv);
+
+	timeout.type = tv->type;
+	tst_ts_set_sec(&timeout, 1);
+	tst_ts_set_nsec(&timeout, 10000);
+
 	ltpuser = SAFE_GETPWNAM("nobody");
 	SAFE_SETUID(ltpuser->pw_uid);
 
@@ -88,6 +103,7 @@  static void setup(void)
 
 static void run(unsigned int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	union semun arr = {.val = tc[i].arr_val};
 	struct sembuf buf = {
 		.sem_op = *tc[i].sem_op,
@@ -96,6 +112,11 @@  static void run(unsigned int i)
 	};
 	struct sembuf *ptr = &buf;
 
+	if (!tc[i].all_variants && tv->semop == semop) {
+		tst_res(TCONF, "Test not supported for variant");
+		return;
+	}
+
 	if (*tc[i].semid == valid_sem_id) {
 		if (semctl(valid_sem_id, tc[i].ctl_sem_num, SETVAL, arr) == -1)
 			tst_brk(TBROK | TERRNO, "semctl() SETVAL failed");
@@ -104,7 +125,7 @@  static void run(unsigned int i)
 	if (tc[i].buf)
 		ptr = *tc[i].buf;
 
-	TEST(semop(*(tc[i].semid), ptr, tc[i].t_ops));
+	TEST(call_semop(tv, *(tc[i].semid), ptr, tc[i].t_ops, tst_ts_get(&timeout)));
 
 	if (TST_RET != -1) {
 		tst_res(TFAIL | TTERRNO, "call succeeded unexpectedly");
@@ -136,6 +157,7 @@  static void cleanup(void)
 static struct tst_test test = {
 	.test = run,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.cleanup = cleanup,
 	.needs_tmpdir = 1,
diff --git a/testcases/kernel/syscalls/ipc/semop/semop03.c b/testcases/kernel/syscalls/ipc/semop/semop03.c
index 25123f08c239..19f3d7fb1499 100644
--- a/testcases/kernel/syscalls/ipc/semop/semop03.c
+++ b/testcases/kernel/syscalls/ipc/semop/semop03.c
@@ -15,9 +15,11 @@ 
 #include "tst_test.h"
 #include "libnewipc.h"
 #include "lapi/semun.h"
+#include "semop.h"
 
 static key_t semkey;
 static int sem_id = -1;
+static struct tst_ts timeout;
 
 struct test_case_t {
 	union semun semunptr;
@@ -34,13 +36,14 @@  struct test_case_t {
 
 static void do_child(int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	struct sembuf s_buf = {
 		.sem_op = tc[i].op,
 		.sem_flg = tc[i].flg,
 		.sem_num = tc[i].num,
 	};
 
-	TEST(semop(sem_id, &s_buf, 1));
+	TEST(call_semop(tv, sem_id, &s_buf, 1, tst_ts_get(&timeout)));
 	if (TST_RET != -1) {
 		tst_res(TFAIL, "call succeeded when error expected");
 		exit(0);
@@ -62,6 +65,15 @@  static void sighandler(int sig)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+	semop_supported_by_kernel(tv);
+
+	timeout.type = tv->type;
+	tst_ts_set_sec(&timeout, 1);
+	tst_ts_set_nsec(&timeout, 10000);
+
 	SAFE_SIGNAL(SIGHUP, sighandler);
 	semkey = GETIPCKEY();
 
@@ -119,6 +131,7 @@  static void run(unsigned int i)
 static struct tst_test test = {
 	.test = run,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.cleanup = cleanup,
 	.needs_tmpdir = 1,