Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'timers-urgent-2020-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Thomas Gleixner:
"A time namespace fix and a matching selftest. The futex absolute
timeouts which are based on CLOCK_MONOTONIC require time namespace
corrected. This was missed in the original time namesapce support"

* tag 'timers-urgent-2020-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
selftests/timens: Add a test for futex()
futex: Adjust absolute futex timeouts with per time namespace offset

+116 -1
+5
kernel/futex.c
··· 39 39 #include <linux/freezer.h> 40 40 #include <linux/memblock.h> 41 41 #include <linux/fault-inject.h> 42 + #include <linux/time_namespace.h> 42 43 43 44 #include <asm/futex.h> 44 45 ··· 3798 3797 t = timespec64_to_ktime(ts); 3799 3798 if (cmd == FUTEX_WAIT) 3800 3799 t = ktime_add_safe(ktime_get(), t); 3800 + else if (!(op & FUTEX_CLOCK_REALTIME)) 3801 + t = timens_ktime_to_host(CLOCK_MONOTONIC, t); 3801 3802 tp = &t; 3802 3803 } 3803 3804 /* ··· 3992 3989 t = timespec64_to_ktime(ts); 3993 3990 if (cmd == FUTEX_WAIT) 3994 3991 t = ktime_add_safe(ktime_get(), t); 3992 + else if (!(op & FUTEX_CLOCK_REALTIME)) 3993 + t = timens_ktime_to_host(CLOCK_MONOTONIC, t); 3995 3994 tp = &t; 3996 3995 } 3997 3996 if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
+1 -1
tools/testing/selftests/timens/Makefile
··· 1 - TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs exec 1 + TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs exec futex 2 2 TEST_GEN_PROGS_EXTENDED := gettime_perf 3 3 4 4 CFLAGS := -Wall -Werror -pthread
+110
tools/testing/selftests/timens/futex.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #define _GNU_SOURCE 3 + #include <sched.h> 4 + 5 + #include <linux/unistd.h> 6 + #include <linux/futex.h> 7 + #include <stdio.h> 8 + #include <string.h> 9 + #include <sys/syscall.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <time.h> 13 + #include <unistd.h> 14 + 15 + #include "log.h" 16 + #include "timens.h" 17 + 18 + #define NSEC_PER_SEC 1000000000ULL 19 + 20 + static int run_test(int clockid) 21 + { 22 + int futex_op = FUTEX_WAIT_BITSET; 23 + struct timespec timeout, end; 24 + int val = 0; 25 + 26 + if (clockid == CLOCK_REALTIME) 27 + futex_op |= FUTEX_CLOCK_REALTIME; 28 + 29 + clock_gettime(clockid, &timeout); 30 + timeout.tv_nsec += NSEC_PER_SEC / 10; // 100ms 31 + if (timeout.tv_nsec > NSEC_PER_SEC) { 32 + timeout.tv_sec++; 33 + timeout.tv_nsec -= NSEC_PER_SEC; 34 + } 35 + 36 + if (syscall(__NR_futex, &val, futex_op, 0, 37 + &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) { 38 + ksft_test_result_fail("futex didn't return ETIMEDOUT\n"); 39 + return 1; 40 + } 41 + 42 + if (errno != ETIMEDOUT) { 43 + ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n", 44 + strerror(errno)); 45 + return 1; 46 + } 47 + 48 + clock_gettime(clockid, &end); 49 + 50 + if (end.tv_sec < timeout.tv_sec || 51 + (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) { 52 + ksft_test_result_fail("futex slept less than 100ms\n"); 53 + return 1; 54 + } 55 + 56 + 57 + ksft_test_result_pass("futex with the %d clockid\n", clockid); 58 + 59 + return 0; 60 + } 61 + 62 + int main(int argc, char *argv[]) 63 + { 64 + int status, len, fd; 65 + char buf[4096]; 66 + pid_t pid; 67 + struct timespec mtime_now; 68 + 69 + nscheck(); 70 + 71 + ksft_set_plan(2); 72 + 73 + clock_gettime(CLOCK_MONOTONIC, &mtime_now); 74 + 75 + if (unshare_timens()) 76 + return 1; 77 + 78 + len = snprintf(buf, sizeof(buf), "%d %d 0", 79 + CLOCK_MONOTONIC, 70 * 24 * 3600); 80 + fd = open("/proc/self/timens_offsets", O_WRONLY); 81 + if (fd < 0) 82 + return pr_perror("/proc/self/timens_offsets"); 83 + 84 + if (write(fd, buf, len) != len) 85 + return pr_perror("/proc/self/timens_offsets"); 86 + 87 + close(fd); 88 + 89 + pid = fork(); 90 + if (pid < 0) 91 + return pr_perror("Unable to fork"); 92 + if (pid == 0) { 93 + int ret = 0; 94 + 95 + ret |= run_test(CLOCK_REALTIME); 96 + ret |= run_test(CLOCK_MONOTONIC); 97 + if (ret) 98 + ksft_exit_fail(); 99 + ksft_exit_pass(); 100 + return 0; 101 + } 102 + 103 + if (waitpid(pid, &status, 0) != pid) 104 + return pr_perror("Unable to wait the child process"); 105 + 106 + if (WIFEXITED(status)) 107 + return WEXITSTATUS(status); 108 + 109 + return 1; 110 + }