* [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] selftests/timens: Add a test for futex()
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 ` 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
2 siblings, 1 reply; 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
Output on success:
$ ./futex
1..1
ok 1 futex
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0
Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
tools/testing/selftests/timens/Makefile | 2 +-
tools/testing/selftests/timens/futex.c | 107 ++++++++++++++++++++++++
2 files changed, 108 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..173760d3fce6
--- /dev/null
+++ b/tools/testing/selftests/timens/futex.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <sched.h>
+
+#include <linux/unistd.h>
+#include <linux/futex.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.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(void)
+{
+ struct timespec timeout, end;
+ int val = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, &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_WAIT_BITSET, 0,
+ &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
+ ksft_test_result_fail("futex didn't return ETIMEDOUT");
+ return 1;
+ }
+
+ if (errno != ETIMEDOUT) {
+ ksft_test_result_fail("futex didn't return ETIMEDOUT: %s",
+ strerror(errno));
+ return 1;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &end);
+
+ if (end.tv_sec < timeout.tv_sec ||
+ (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_sec)) {
+ ksft_test_result_fail("futex slept less than 100ms");
+ return 1;
+ }
+
+
+ ksft_test_result_pass("futex\n");
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int status, len, fd;
+ char buf[4096];
+ pid_t pid;
+ struct timespec mtime_now;
+
+ nscheck();
+
+ check_supported_timers();
+
+ ksft_set_plan(1);
+
+ 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) {
+ if (run_test())
+ 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
* [tip: timers/urgent] selftests/timens: Add a test for futex()
2020-10-15 7:29 ` [PATCH 2/2] selftests/timens: Add a test for futex() Andrei Vagin
@ 2020-10-15 9:35 ` tip-bot2 for Andrei Vagin
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot2 for Andrei Vagin @ 2020-10-15 9:35 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Andrei Vagin, Thomas Gleixner, x86, LKML
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: 4cdf42596216e08051c0ccc4c896dcb8b2d22f10
Gitweb: https://git.kernel.org/tip/4cdf42596216e08051c0ccc4c896dcb8b2d22f10
Author: Andrei Vagin <avagin@gmail.com>
AuthorDate: Thu, 15 Oct 2020 00:29:09 -07:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 15 Oct 2020 11:24:04 +02:00
selftests/timens: Add a test for futex()
Output on success:
$ ./futex
1..1
ok 1 futex
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0
Signed-off-by: Andrei Vagin <avagin@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201015072909.271426-2-avagin@gmail.com
---
tools/testing/selftests/timens/Makefile | 2 +-
tools/testing/selftests/timens/futex.c | 107 +++++++++++++++++++++++-
2 files changed, 108 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 b4fd9a9..3a5936c 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 0000000..173760d
--- /dev/null
+++ b/tools/testing/selftests/timens/futex.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <sched.h>
+
+#include <linux/unistd.h>
+#include <linux/futex.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.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(void)
+{
+ struct timespec timeout, end;
+ int val = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, &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_WAIT_BITSET, 0,
+ &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
+ ksft_test_result_fail("futex didn't return ETIMEDOUT");
+ return 1;
+ }
+
+ if (errno != ETIMEDOUT) {
+ ksft_test_result_fail("futex didn't return ETIMEDOUT: %s",
+ strerror(errno));
+ return 1;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &end);
+
+ if (end.tv_sec < timeout.tv_sec ||
+ (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_sec)) {
+ ksft_test_result_fail("futex slept less than 100ms");
+ return 1;
+ }
+
+
+ ksft_test_result_pass("futex\n");
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int status, len, fd;
+ char buf[4096];
+ pid_t pid;
+ struct timespec mtime_now;
+
+ nscheck();
+
+ check_supported_timers();
+
+ ksft_set_plan(1);
+
+ 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) {
+ if (run_test())
+ 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;
+}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip: timers/urgent] futex: Adjust futex absolute timeouts with per-timens offset
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-bot2 for Andrei Vagin
2020-10-15 13:26 ` [PATCH 1/2] futex: adjust a futex timeout with a " Dmitry Safonov
2 siblings, 0 replies; 8+ messages in thread
From: tip-bot2 for Andrei Vagin @ 2020-10-15 9:35 UTC (permalink / raw)
To: linux-tip-commits
Cc: Hans van der Laan, Andrei Vagin, Thomas Gleixner, stable, x86, LKML
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: 06764291690f8650a9f96dea42cc0dd4138d47d5
Gitweb: https://git.kernel.org/tip/06764291690f8650a9f96dea42cc0dd4138d47d5
Author: Andrei Vagin <avagin@gmail.com>
AuthorDate: Thu, 15 Oct 2020 00:29:08 -07:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 15 Oct 2020 11:24:04 +02:00
futex: Adjust futex absolute timeouts with per-timens offset
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.
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>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20201015072909.271426-1-avagin@gmail.com
---
kernel/futex.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/futex.c b/kernel/futex.c
index a587669..9ff2b8c 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;
}
/*
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] futex: adjust a futex timeout with a per-timens offset
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] futex: Adjust futex absolute timeouts with per-timens offset tip-bot2 for Andrei Vagin
@ 2020-10-15 13:26 ` Dmitry Safonov
2020-10-15 14:13 ` Thomas Gleixner
2 siblings, 1 reply; 8+ messages in thread
From: Dmitry Safonov @ 2020-10-15 13:26 UTC (permalink / raw)
To: Andrei Vagin, Thomas Gleixner, linux-kernel
Cc: Ingo Molnar, Peter Zijlstra, Darren Hart, Shuah Khan, stable
On 10/15/20 8:29 AM, Andrei Vagin wrote:
> 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>[..]
> @@ -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);
Err, it probably should be
: else if (!(op & FUTEX_CLOCK_REALTIME))
And there's also
: SYSCALL_DEFINE6(futex_time32, ...)
which wants to be patched.
Thanks,
Dmitry
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] futex: adjust a futex timeout with a per-timens offset
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
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Gleixner @ 2020-10-15 14:13 UTC (permalink / raw)
To: Dmitry Safonov, Andrei Vagin, linux-kernel
Cc: Ingo Molnar, Peter Zijlstra, Darren Hart, Shuah Khan, stable
On Thu, Oct 15 2020 at 14:26, Dmitry Safonov wrote:
> On 10/15/20 8:29 AM, Andrei Vagin wrote:
>> 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>[..]
>> @@ -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);
>
> Err, it probably should be
> : else if (!(op & FUTEX_CLOCK_REALTIME))
Duh, you are right. I stared at it for a while and did not spot it.
> And there's also
> : SYSCALL_DEFINE6(futex_time32, ...)
> which wants to be patched.
Indeed. I zapped the commits.
Thanks,
tglx
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] futex: adjust a futex timeout with a per-timens offset
2020-10-15 14:13 ` Thomas Gleixner
@ 2020-10-16 8:18 ` Andrei Vagin
0 siblings, 0 replies; 8+ messages in thread
From: Andrei Vagin @ 2020-10-16 8:18 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Dmitry Safonov, linux-kernel, Ingo Molnar, Peter Zijlstra,
Darren Hart, Shuah Khan, stable
On Thu, Oct 15, 2020 at 04:13:42PM +0200, Thomas Gleixner wrote:
> On Thu, Oct 15 2020 at 14:26, Dmitry Safonov wrote:
>
> > On 10/15/20 8:29 AM, Andrei Vagin wrote:
> >> 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>[..]
> >> @@ -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);
> >
> > Err, it probably should be
> > : else if (!(op & FUTEX_CLOCK_REALTIME))
Dmitry, thank you for catching this.
>
> Duh, you are right. I stared at it for a while and did not spot it.
>
> > And there's also
> > : SYSCALL_DEFINE6(futex_time32, ...)
> > which wants to be patched.
>
> Indeed. I zapped the commits.
I sent a new version. This time, I extended the test to check
FUTEX_CLOCK_REALTIME and I compiled and run the compat version.
Everything works as it should be.
Thanks,
Andrei
^ permalink raw reply [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
* [tip: timers/urgent] selftests/timens: Add a test for futex()
2020-10-15 16:00 [PATCH 2/2 v2] selftests/timens: Add a test for futex() Andrei Vagin
@ 2020-10-20 15:11 ` tip-bot2 for Andrei Vagin
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot2 for Andrei Vagin @ 2020-10-20 15:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Andrei Vagin, Thomas Gleixner, x86, LKML
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: a4fd8414659bf470e2146b352574bbd274e54b7a
Gitweb: https://git.kernel.org/tip/a4fd8414659bf470e2146b352574bbd274e54b7a
Author: Andrei Vagin <avagin@gmail.com>
AuthorDate: Thu, 15 Oct 2020 09:00:20 -07:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Tue, 20 Oct 2020 17:02:57 +02:00
selftests/timens: Add a test for futex()
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>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201015160020.293748-2-avagin@gmail.com
---
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 b4fd9a9..3a5936c 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 0000000..6b2b926
--- /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;
+}
^ 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.