Messages in this thread Patch in this message | | | From | Alistair Francis <> | Subject | [PATCH v2 2/2] selftests: futex: Use a 64-bit time_t | Date | Fri, 15 Oct 2021 10:56:34 +1000 |
| |
From: Alistair Francis <alistair.francis@wdc.com>
Convert the futex selftests to only use a 64-bit time_t. On 64-bit architectures this isn't a functional change. On 32-bit architectures we now only perform 64-bit time_t syscalls (__NR_futex_time64) and use a struct timespec64.
This won't work on kernels before 5.1, but as perf is tied to the kernel that's ok.
This allows the tests to run and pass on RISC-V 32-bit.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com> --- .../futex/functional/futex_requeue.c | 2 +- .../futex/functional/futex_requeue_pi.c | 10 ++--- .../selftests/futex/functional/futex_wait.c | 2 +- .../futex_wait_private_mapped_file.c | 2 +- .../futex/functional/futex_wait_timeout.c | 8 ++-- .../futex/functional/futex_wait_wouldblock.c | 2 +- .../selftests/futex/include/futextest.h | 37 +++++++++++++++---- 7 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/futex/functional/futex_requeue.c b/tools/testing/selftests/futex/functional/futex_requeue.c index 51485be6eb2f1..f51aedffcd161 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue.c +++ b/tools/testing/selftests/futex/functional/futex_requeue.c @@ -27,7 +27,7 @@ void usage(char *prog) void *waiterfn(void *arg) { - struct timespec to; + struct timespec64 to; to.tv_sec = 0; to.tv_nsec = timeout_ns; diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi.c b/tools/testing/selftests/futex/functional/futex_requeue_pi.c index 1ee5518ee6b7f..32d6ee554ec2e 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi.c @@ -48,7 +48,7 @@ static int locked; struct thread_arg { long id; - struct timespec *timeout; + struct timespec64 *timeout; int lock; int ret; }; @@ -281,7 +281,7 @@ int unit_test(int broadcast, long lock, int third_party_owner, long timeout_ns) struct thread_arg blocker_arg = THREAD_ARG_INITIALIZER; struct thread_arg waker_arg = THREAD_ARG_INITIALIZER; pthread_t waiter[THREAD_MAX], waker, blocker; - struct timespec ts, *tsp = NULL; + struct timespec64 ts, *tsp = NULL; struct thread_arg args[THREAD_MAX]; int *waiter_ret; int i, ret = RET_PASS; @@ -290,12 +290,12 @@ int unit_test(int broadcast, long lock, int third_party_owner, long timeout_ns) time_t secs; info("timeout_ns = %ld\n", timeout_ns); - ret = clock_gettime(CLOCK_MONOTONIC, &ts); + ret = gettime64(CLOCK_MONOTONIC, &ts); secs = (ts.tv_nsec + timeout_ns) / 1000000000; ts.tv_nsec = ((int64_t)ts.tv_nsec + timeout_ns) % 1000000000; ts.tv_sec += secs; - info("ts.tv_sec = %ld\n", ts.tv_sec); - info("ts.tv_nsec = %ld\n", ts.tv_nsec); + info("ts.tv_sec = %lld\n", ts.tv_sec); + info("ts.tv_nsec = %lld\n", ts.tv_nsec); tsp = &ts; } diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c index 685140d9b93d2..d1c8a4212c74c 100644 --- a/tools/testing/selftests/futex/functional/futex_wait.c +++ b/tools/testing/selftests/futex/functional/futex_wait.c @@ -30,7 +30,7 @@ void usage(char *prog) static void *waiterfn(void *arg) { - struct timespec to; + struct timespec64 to; unsigned int flags = 0; if (arg) diff --git a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c index fb4148f23fa37..5e84e136ad99e 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c +++ b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c @@ -38,7 +38,7 @@ futex_t val = 1; char pad2[PAGE_SZ] = {1}; #define WAKE_WAIT_US 3000000 -struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0}; +struct timespec64 wait_timeout = { .tv_sec = 5, .tv_nsec = 0}; void usage(char *prog) { diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c index 1f8f6daaf1e70..86b1e847a0246 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c +++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c @@ -71,11 +71,11 @@ static void test_timeout(int res, int *ret, char *test_name, int err) /* * Calculate absolute timeout and correct overflow */ -static int futex_get_abs_timeout(clockid_t clockid, struct timespec *to, +static int futex_get_abs_timeout(clockid_t clockid, struct timespec64 *to, long timeout_ns) { - if (clock_gettime(clockid, to)) { - error("clock_gettime failed\n", errno); + if (gettime64(clockid, to)) { + error("gettime64 failed\n", errno); return errno; } @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) { futex_t f1 = FUTEX_INITIALIZER; int res, ret = RET_PASS; - struct timespec to; + struct timespec64 to; pthread_t thread; int c; diff --git a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c index 0ae390ff81644..76faa664544d6 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c +++ b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c @@ -38,7 +38,7 @@ void usage(char *prog) int main(int argc, char *argv[]) { - struct timespec to = {.tv_sec = 0, .tv_nsec = timeout_ns}; + struct timespec64 to = {.tv_sec = 0, .tv_nsec = timeout_ns}; futex_t f1 = FUTEX_INITIALIZER; int res, ret = RET_PASS; int c; diff --git a/tools/testing/selftests/futex/include/futextest.h b/tools/testing/selftests/futex/include/futextest.h index ddbcfc9b7bac4..67ed97a455274 100644 --- a/tools/testing/selftests/futex/include/futextest.h +++ b/tools/testing/selftests/futex/include/futextest.h @@ -21,6 +21,7 @@ #include <sys/syscall.h> #include <sys/types.h> #include <linux/futex.h> +#include <linux/time_types.h> typedef volatile u_int32_t futex_t; #define FUTEX_INITIALIZER 0 @@ -47,12 +48,14 @@ typedef volatile u_int32_t futex_t; FUTEX_PRIVATE_FLAG) #endif +#define timespec64 __kernel_timespec + /** * futex() - SYS_futex syscall wrapper * @uaddr: address of first futex * @op: futex op code * @val: typically expected value of uaddr, but varies by op - * @timeout: typically an absolute struct timespec (except where noted + * @timeout: typically an absolute struct timespec64 (except where noted * otherwise). Overloaded by some ops * @uaddr2: address of second futex for some ops\ * @val3: varies by op @@ -67,15 +70,35 @@ typedef volatile u_int32_t futex_t; * These argument descriptions are the defaults for all * like-named arguments in the following wrappers except where noted below. */ -#define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \ - syscall(SYS_futex, uaddr, op | opflags, val, timeout, uaddr2, val3) +/** + * We only support 64-bit time_t for the timeout. + * On 64-bit architectures we can use __NR_futex + * On 32-bit architectures we use __NR_futex_time64. This only works on kernel + * versions 5.1+. + */ +#if __BITS_PER_LONG == 64 +# define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \ + syscall(__NR_futex, uaddr, op | opflags, val, timeout, uaddr2, val3) +#else +# define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \ + syscall(__NR_futex_time64, uaddr, op | opflags, val, timeout, uaddr2, val3) +#endif + +static inline int gettime64(clock_t clockid, struct timespec64 *tv) +{ +#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) + return syscall(__NR_clock_gettime, clockid, tv); +#else + return syscall(__NR_clock_gettime64, clockid, tv); +#endif +} /** * futex_wait() - block on uaddr with optional timeout * @timeout: relative timeout */ static inline int -futex_wait(futex_t *uaddr, futex_t val, struct timespec *timeout, int opflags) +futex_wait(futex_t *uaddr, futex_t val, struct timespec64 *timeout, int opflags) { return futex(uaddr, FUTEX_WAIT, val, timeout, NULL, 0, opflags); } @@ -95,7 +118,7 @@ futex_wake(futex_t *uaddr, int nr_wake, int opflags) * @bitset: bitset to be used with futex_wake_bitset */ static inline int -futex_wait_bitset(futex_t *uaddr, futex_t val, struct timespec *timeout, +futex_wait_bitset(futex_t *uaddr, futex_t val, struct timespec64 *timeout, u_int32_t bitset, int opflags) { return futex(uaddr, FUTEX_WAIT_BITSET, val, timeout, NULL, bitset, @@ -118,7 +141,7 @@ futex_wake_bitset(futex_t *uaddr, int nr_wake, u_int32_t bitset, int opflags) * @detect: whether (1) or not (0) to perform deadlock detection */ static inline int -futex_lock_pi(futex_t *uaddr, struct timespec *timeout, int detect, +futex_lock_pi(futex_t *uaddr, struct timespec64 *timeout, int detect, int opflags) { return futex(uaddr, FUTEX_LOCK_PI, detect, timeout, NULL, 0, opflags); @@ -183,7 +206,7 @@ futex_cmp_requeue(futex_t *uaddr, futex_t val, futex_t *uaddr2, int nr_wake, */ static inline int futex_wait_requeue_pi(futex_t *uaddr, futex_t val, futex_t *uaddr2, - struct timespec *timeout, int opflags) + struct timespec64 *timeout, int opflags) { return futex(uaddr, FUTEX_WAIT_REQUEUE_PI, val, timeout, uaddr2, 0, opflags); -- 2.31.1
| |