All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] futex: adjust a futex timeout with a per-timens offset
@ 2020-10-15  7:29 Andrei Vagin
  2020-10-15  7:29 ` [PATCH 2/2] selftests/timens: Add a test for futex() Andrei Vagin
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Andrei Vagin @ 2020-10-15  7:29 UTC (permalink / raw)
  To: Thomas Gleixner, linux-kernel
  Cc: Ingo Molnar, Peter Zijlstra, Darren Hart, Dmitry Safonov,
	Shuah Khan, Andrei Vagin, stable

For all commands except FUTEX_WAIT, timeout is interpreted as an
absolute value. This absolute value is inside the task's time namespace
and has to be converted to the host's time.

Cc: <stable@vger.kernel.org>
Fixes: 5a590f35add9 ("posix-clocks: Wire up clock_gettime() with timens offsets")
Reported-by: Hans van der Laan <j.h.vanderlaan@student.utwente.nl>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
 kernel/futex.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/futex.c b/kernel/futex.c
index a5876694a60e..9ff2b8c5a506 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -39,6 +39,7 @@
 #include <linux/freezer.h>
 #include <linux/memblock.h>
 #include <linux/fault-inject.h>
+#include <linux/time_namespace.h>
 
 #include <asm/futex.h>
 
@@ -3797,6 +3798,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
 		t = timespec64_to_ktime(ts);
 		if (cmd == FUTEX_WAIT)
 			t = ktime_add_safe(ktime_get(), t);
+		else if (!(cmd & FUTEX_CLOCK_REALTIME))
+			t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
 		tp = &t;
 	}
 	/*
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread
* [PATCH 2/2 v2] selftests/timens: Add a test for futex()
@ 2020-10-15 16:00 Andrei Vagin
  2020-10-20 15:11 ` [tip: timers/urgent] " tip-bot2 for Andrei Vagin
  0 siblings, 1 reply; 8+ messages in thread
From: Andrei Vagin @ 2020-10-15 16:00 UTC (permalink / raw)
  To: Thomas Gleixner, linux-kernel
  Cc: Ingo Molnar, Peter Zijlstra, Darren Hart, Dmitry Safonov,
	Shuah Khan, Andrei Vagin

Output on success:
 1..2
 ok 1 futex with the 0 clockid
 ok 2 futex with the 1 clockid
 # Totals: pass:2 fail:0 xfail:0 xpass:0 skip:0 error:0

Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
v2: extend the test to check FUTEX_CLOCK_REALTIME

 tools/testing/selftests/timens/Makefile |   2 +-
 tools/testing/selftests/timens/futex.c  | 110 ++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/timens/futex.c

diff --git a/tools/testing/selftests/timens/Makefile b/tools/testing/selftests/timens/Makefile
index b4fd9a934654..3a5936cc10ab 100644
--- a/tools/testing/selftests/timens/Makefile
+++ b/tools/testing/selftests/timens/Makefile
@@ -1,4 +1,4 @@
-TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs exec
+TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs exec futex
 TEST_GEN_PROGS_EXTENDED := gettime_perf
 
 CFLAGS := -Wall -Werror -pthread
diff --git a/tools/testing/selftests/timens/futex.c b/tools/testing/selftests/timens/futex.c
new file mode 100644
index 000000000000..6b2b9264e851
--- /dev/null
+++ b/tools/testing/selftests/timens/futex.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <sched.h>
+
+#include <linux/unistd.h>
+#include <linux/futex.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "timens.h"
+
+#define NSEC_PER_SEC 1000000000ULL
+
+static int run_test(int clockid)
+{
+	int futex_op = FUTEX_WAIT_BITSET;
+	struct timespec timeout, end;
+	int val = 0;
+
+	if (clockid == CLOCK_REALTIME)
+		futex_op |= FUTEX_CLOCK_REALTIME;
+
+	clock_gettime(clockid, &timeout);
+	timeout.tv_nsec += NSEC_PER_SEC / 10; // 100ms
+	if (timeout.tv_nsec > NSEC_PER_SEC) {
+		timeout.tv_sec++;
+		timeout.tv_nsec -= NSEC_PER_SEC;
+	}
+
+	if (syscall(__NR_futex, &val, futex_op, 0,
+		    &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
+		ksft_test_result_fail("futex didn't return ETIMEDOUT\n");
+		return 1;
+	}
+
+	if (errno != ETIMEDOUT) {
+		ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n",
+							strerror(errno));
+		return 1;
+	}
+
+	clock_gettime(clockid, &end);
+
+	if (end.tv_sec < timeout.tv_sec ||
+	    (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) {
+		ksft_test_result_fail("futex slept less than 100ms\n");
+		return 1;
+	}
+
+
+	ksft_test_result_pass("futex with the %d clockid\n", clockid);
+
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int status, len, fd;
+	char buf[4096];
+	pid_t pid;
+	struct timespec mtime_now;
+
+	nscheck();
+
+	ksft_set_plan(2);
+
+	clock_gettime(CLOCK_MONOTONIC, &mtime_now);
+
+	if (unshare_timens())
+		return 1;
+
+	len = snprintf(buf, sizeof(buf), "%d %d 0",
+			CLOCK_MONOTONIC, 70 * 24 * 3600);
+	fd = open("/proc/self/timens_offsets", O_WRONLY);
+	if (fd < 0)
+		return pr_perror("/proc/self/timens_offsets");
+
+	if (write(fd, buf, len) != len)
+		return pr_perror("/proc/self/timens_offsets");
+
+	close(fd);
+
+	pid = fork();
+	if (pid < 0)
+		return pr_perror("Unable to fork");
+	if (pid == 0) {
+		int ret = 0;
+
+		ret |= run_test(CLOCK_REALTIME);
+		ret |= run_test(CLOCK_MONOTONIC);
+		if (ret)
+			ksft_exit_fail();
+		ksft_exit_pass();
+		return 0;
+	}
+
+	if (waitpid(pid, &status, 0) != pid)
+		return pr_perror("Unable to wait the child process");
+
+	if (WIFEXITED(status))
+		return WEXITSTATUS(status);
+
+	return 1;
+}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-10-20 15:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-15  7:29 [PATCH 1/2] futex: adjust a futex timeout with a per-timens offset Andrei Vagin
2020-10-15  7:29 ` [PATCH 2/2] selftests/timens: Add a test for futex() Andrei Vagin
2020-10-15  9:35   ` [tip: timers/urgent] " tip-bot2 for Andrei Vagin
2020-10-15  9:35 ` [tip: timers/urgent] futex: Adjust futex absolute timeouts with per-timens offset tip-bot2 for Andrei Vagin
2020-10-15 13:26 ` [PATCH 1/2] futex: adjust a futex timeout with a " Dmitry Safonov
2020-10-15 14:13   ` Thomas Gleixner
2020-10-16  8:18     ` Andrei Vagin
2020-10-15 16:00 [PATCH 2/2 v2] selftests/timens: Add a test for futex() Andrei Vagin
2020-10-20 15:11 ` [tip: timers/urgent] " tip-bot2 for Andrei Vagin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.