^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #define _GNU_SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/futex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/syscall.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "timens.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define NSEC_PER_SEC 1000000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int run_test(int clockid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int futex_op = FUTEX_WAIT_BITSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct timespec timeout, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (clockid == CLOCK_REALTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) futex_op |= FUTEX_CLOCK_REALTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) clock_gettime(clockid, &timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) timeout.tv_nsec += NSEC_PER_SEC / 10; // 100ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (timeout.tv_nsec > NSEC_PER_SEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) timeout.tv_sec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) timeout.tv_nsec -= NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (syscall(__NR_futex, &val, futex_op, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ksft_test_result_fail("futex didn't return ETIMEDOUT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (errno != ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) clock_gettime(clockid, &end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (end.tv_sec < timeout.tv_sec ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ksft_test_result_fail("futex slept less than 100ms\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ksft_test_result_pass("futex with the %d clockid\n", clockid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int status, len, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) char buf[4096];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct timespec mtime_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nscheck();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ksft_set_plan(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) clock_gettime(CLOCK_MONOTONIC, &mtime_now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (unshare_timens())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) len = snprintf(buf, sizeof(buf), "%d %d 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) CLOCK_MONOTONIC, 70 * 24 * 3600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) fd = open("/proc/self/timens_offsets", O_WRONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return pr_perror("/proc/self/timens_offsets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (write(fd, buf, len) != len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return pr_perror("/proc/self/timens_offsets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) pid = fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (pid < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return pr_perror("Unable to fork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (pid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ret |= run_test(CLOCK_REALTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret |= run_test(CLOCK_MONOTONIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ksft_exit_fail();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ksft_exit_pass();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (waitpid(pid, &status, 0) != pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return pr_perror("Unable to wait the child process");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (WIFEXITED(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return WEXITSTATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }