netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI
@ 2022-08-09  6:08 Kurt Kanzenbach
  2022-08-09  6:08 ` [PATCH bpf-next v2 1/2] bpf: " Kurt Kanzenbach
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kurt Kanzenbach @ 2022-08-09  6:08 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Joanne Koong, Jiri Olsa, Dave Marchevsky,
	Lorenzo Bianconi, Geliang Tang, Jakub Sitnicki, netdev, bpf,
	Thomas Gleixner, Maciej Fijalkowski, Jesper Dangaard Brouer,
	Kurt Kanzenbach

Hi,

add a BPF-helper for accessing CLOCK_TAI. Use cases for such a BPF helper
include functionalities such as Tx launch time (e.g. ETF and TAPRIO Qdiscs),
timestamping and policing.

Patch #1 - Introduce BPF helper
Patch #2 - Add test case (skb based)

Changes since v1:

 * Update changelog (Alexei Starovoitov)
 * Add test case (Alexei Starovoitov, Andrii Nakryiko)
 * Add missing function prototype (netdev ci)

Previous versions:

 * v1: https://lore.kernel.org/r/20220606103734.92423-1-kurt@linutronix.de/

Jesper Dangaard Brouer (1):
  bpf: Add BPF-helper for accessing CLOCK_TAI

Kurt Kanzenbach (1):
  selftests/bpf: Add BPF-helper test for CLOCK_TAI access

 include/linux/bpf.h                           |  1 +
 include/uapi/linux/bpf.h                      | 13 ++++
 kernel/bpf/core.c                             |  1 +
 kernel/bpf/helpers.c                          | 14 ++++
 tools/include/uapi/linux/bpf.h                | 13 ++++
 .../selftests/bpf/prog_tests/time_tai.c       | 74 +++++++++++++++++++
 .../selftests/bpf/progs/test_time_tai.c       | 24 ++++++
 7 files changed, 140 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/time_tai.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_time_tai.c

-- 
2.30.2


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

* [PATCH bpf-next v2 1/2] bpf: Add BPF-helper for accessing CLOCK_TAI
  2022-08-09  6:08 [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI Kurt Kanzenbach
@ 2022-08-09  6:08 ` Kurt Kanzenbach
  2022-08-09  6:08 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add BPF-helper test for CLOCK_TAI access Kurt Kanzenbach
  2022-08-09 17:00 ` [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Kurt Kanzenbach @ 2022-08-09  6:08 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Joanne Koong, Jiri Olsa, Dave Marchevsky,
	Lorenzo Bianconi, Geliang Tang, Jakub Sitnicki, netdev, bpf,
	Thomas Gleixner, Maciej Fijalkowski, Jesper Dangaard Brouer,
	Kurt Kanzenbach

From: Jesper Dangaard Brouer <brouer@redhat.com>

Commit 3dc6ffae2da2 ("timekeeping: Introduce fast accessor to clock tai")
introduced a fast and NMI-safe accessor for CLOCK_TAI. Especially in time
sensitive networks (TSN), where all nodes are synchronized by Precision Time
Protocol (PTP), it's helpful to have the possibility to generate timestamps
based on CLOCK_TAI instead of CLOCK_MONOTONIC. With a BPF helper for TAI in
place, it becomes very convenient to correlate activity across different
machines in the network.

Use cases for such a BPF helper include functionalities such as Tx launch
time (e.g. ETF and TAPRIO Qdiscs) and timestamping.

Note: CLOCK_TAI is nothing new per se, only the NMI-safe variant of it is.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
[Kurt: Wrote changelog and renamed helper]
Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
---
 include/linux/bpf.h            |  1 +
 include/uapi/linux/bpf.h       | 13 +++++++++++++
 kernel/bpf/core.c              |  1 +
 kernel/bpf/helpers.c           | 14 ++++++++++++++
 tools/include/uapi/linux/bpf.h | 13 +++++++++++++
 5 files changed, 42 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 20c26aed7896..a627a02cf8ab 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2349,6 +2349,7 @@ extern const struct bpf_func_proto bpf_get_numa_node_id_proto;
 extern const struct bpf_func_proto bpf_tail_call_proto;
 extern const struct bpf_func_proto bpf_ktime_get_ns_proto;
 extern const struct bpf_func_proto bpf_ktime_get_boot_ns_proto;
+extern const struct bpf_func_proto bpf_ktime_get_tai_ns_proto;
 extern const struct bpf_func_proto bpf_get_current_pid_tgid_proto;
 extern const struct bpf_func_proto bpf_get_current_uid_gid_proto;
 extern const struct bpf_func_proto bpf_get_current_comm_proto;
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 534e33fb1029..7d1e2794d83e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5341,6 +5341,18 @@ union bpf_attr {
  *		**-EACCES** if the SYN cookie is not valid.
  *
  *		**-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin.
+ *
+ * u64 bpf_ktime_get_tai_ns(void)
+ *	Description
+ *		A nonsettable system-wide clock derived from wall-clock time but
+ *		ignoring leap seconds.  This clock does not experience
+ *		discontinuities and backwards jumps caused by NTP inserting leap
+ *		seconds as CLOCK_REALTIME does.
+ *
+ *		See: **clock_gettime**\ (**CLOCK_TAI**)
+ *	Return
+ *		Current *ktime*.
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -5551,6 +5563,7 @@ union bpf_attr {
 	FN(tcp_raw_gen_syncookie_ipv6),	\
 	FN(tcp_raw_check_syncookie_ipv4),	\
 	FN(tcp_raw_check_syncookie_ipv6),	\
+	FN(ktime_get_tai_ns),		\
 	/* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index c1e10d088dbb..639437f36928 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2623,6 +2623,7 @@ const struct bpf_func_proto bpf_get_numa_node_id_proto __weak;
 const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
 const struct bpf_func_proto bpf_ktime_get_boot_ns_proto __weak;
 const struct bpf_func_proto bpf_ktime_get_coarse_ns_proto __weak;
+const struct bpf_func_proto bpf_ktime_get_tai_ns_proto __weak;
 
 const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
 const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 1f961f9982d2..a95eb9fb01ff 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -198,6 +198,18 @@ const struct bpf_func_proto bpf_ktime_get_coarse_ns_proto = {
 	.ret_type	= RET_INTEGER,
 };
 
+BPF_CALL_0(bpf_ktime_get_tai_ns)
+{
+	/* NMI safe access to clock tai */
+	return ktime_get_tai_fast_ns();
+}
+
+const struct bpf_func_proto bpf_ktime_get_tai_ns_proto = {
+	.func		= bpf_ktime_get_tai_ns,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+};
+
 BPF_CALL_0(bpf_get_current_pid_tgid)
 {
 	struct task_struct *task = current;
@@ -1617,6 +1629,8 @@ bpf_base_func_proto(enum bpf_func_id func_id)
 		return &bpf_ktime_get_ns_proto;
 	case BPF_FUNC_ktime_get_boot_ns:
 		return &bpf_ktime_get_boot_ns_proto;
+	case BPF_FUNC_ktime_get_tai_ns:
+		return &bpf_ktime_get_tai_ns_proto;
 	case BPF_FUNC_ringbuf_output:
 		return &bpf_ringbuf_output_proto;
 	case BPF_FUNC_ringbuf_reserve:
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index f58d58e1d547..e174ad28aeb7 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5341,6 +5341,18 @@ union bpf_attr {
  *		**-EACCES** if the SYN cookie is not valid.
  *
  *		**-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin.
+ *
+ * u64 bpf_ktime_get_tai_ns(void)
+ *	Description
+ *		A nonsettable system-wide clock derived from wall-clock time but
+ *		ignoring leap seconds.  This clock does not experience
+ *		discontinuities and backwards jumps caused by NTP inserting leap
+ *		seconds as CLOCK_REALTIME does.
+ *
+ *		See: **clock_gettime**\ (**CLOCK_TAI**)
+ *	Return
+ *		Current *ktime*.
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -5551,6 +5563,7 @@ union bpf_attr {
 	FN(tcp_raw_gen_syncookie_ipv6),	\
 	FN(tcp_raw_check_syncookie_ipv4),	\
 	FN(tcp_raw_check_syncookie_ipv6),	\
+	FN(ktime_get_tai_ns),		\
 	/* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
-- 
2.30.2


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

* [PATCH bpf-next v2 2/2] selftests/bpf: Add BPF-helper test for CLOCK_TAI access
  2022-08-09  6:08 [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI Kurt Kanzenbach
  2022-08-09  6:08 ` [PATCH bpf-next v2 1/2] bpf: " Kurt Kanzenbach
@ 2022-08-09  6:08 ` Kurt Kanzenbach
  2022-08-09 17:00 ` [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Kurt Kanzenbach @ 2022-08-09  6:08 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Joanne Koong, Jiri Olsa, Dave Marchevsky,
	Lorenzo Bianconi, Geliang Tang, Jakub Sitnicki, netdev, bpf,
	Thomas Gleixner, Maciej Fijalkowski, Jesper Dangaard Brouer,
	Kurt Kanzenbach

Add BPF-helper test case for CLOCK_TAI access. The added test verifies that:

 * Timestamps are generated
 * Timestamps are moving forward
 * Timestamps are reasonable

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
---
 .../selftests/bpf/prog_tests/time_tai.c       | 74 +++++++++++++++++++
 .../selftests/bpf/progs/test_time_tai.c       | 24 ++++++
 2 files changed, 98 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/time_tai.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_time_tai.c

diff --git a/tools/testing/selftests/bpf/prog_tests/time_tai.c b/tools/testing/selftests/bpf/prog_tests/time_tai.c
new file mode 100644
index 000000000000..a31119823666
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/time_tai.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2022 Linutronix GmbH */
+
+#include <test_progs.h>
+#include <network_helpers.h>
+
+#include "test_time_tai.skel.h"
+
+#include <time.h>
+#include <stdint.h>
+
+#define TAI_THRESHOLD	1000000000ULL /* 1s */
+#define NSEC_PER_SEC	1000000000ULL
+
+static __u64 ts_to_ns(const struct timespec *ts)
+{
+	return ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec;
+}
+
+void test_time_tai(void)
+{
+	struct __sk_buff skb = {
+		.cb[0] = 0,
+		.cb[1] = 0,
+		.tstamp = 0,
+	};
+	LIBBPF_OPTS(bpf_test_run_opts, topts,
+		.data_in = &pkt_v4,
+		.data_size_in = sizeof(pkt_v4),
+		.ctx_in = &skb,
+		.ctx_size_in = sizeof(skb),
+		.ctx_out = &skb,
+		.ctx_size_out = sizeof(skb),
+	);
+	struct test_time_tai *skel;
+	struct timespec now_tai;
+	__u64 ts1, ts2, now;
+	int ret, prog_fd;
+
+	/* Open and load */
+	skel = test_time_tai__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "tai_open"))
+		return;
+
+	/* Run test program */
+	prog_fd = bpf_program__fd(skel->progs.time_tai);
+	ret = bpf_prog_test_run_opts(prog_fd, &topts);
+	ASSERT_OK(ret, "test_run");
+
+	/* Retrieve generated TAI timestamps */
+	ts1 = skb.tstamp;
+	ts2 = skb.cb[0] | ((__u64)skb.cb[1] << 32);
+
+	/* TAI != 0 */
+	ASSERT_NEQ(ts1, 0, "tai_ts1");
+	ASSERT_NEQ(ts2, 0, "tai_ts2");
+
+	/* TAI is moving forward only */
+	ASSERT_GT(ts2, ts1, "tai_forward");
+
+	/* Check for future */
+	ret = clock_gettime(CLOCK_TAI, &now_tai);
+	ASSERT_EQ(ret, 0, "tai_gettime");
+	now = ts_to_ns(&now_tai);
+
+	ASSERT_TRUE(now > ts1, "tai_future_ts1");
+	ASSERT_TRUE(now > ts2, "tai_future_ts2");
+
+	/* Check for reasonable range */
+	ASSERT_TRUE(now - ts1 < TAI_THRESHOLD, "tai_range_ts1");
+	ASSERT_TRUE(now - ts2 < TAI_THRESHOLD, "tai_range_ts2");
+
+	test_time_tai__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_time_tai.c b/tools/testing/selftests/bpf/progs/test_time_tai.c
new file mode 100644
index 000000000000..7ea0863f3ddb
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_time_tai.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2022 Linutronix GmbH */
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+char _license[] SEC("license") = "GPL";
+
+SEC("tc")
+int time_tai(struct __sk_buff *skb)
+{
+	__u64 ts1, ts2;
+
+	/* Get TAI timestamps */
+	ts1 = bpf_ktime_get_tai_ns();
+	ts2 = bpf_ktime_get_tai_ns();
+
+	/* Save TAI timestamps (Note: skb->hwtstamp is read-only) */
+	skb->tstamp = ts1;
+	skb->cb[0] = ts2 & 0xffffffff;
+	skb->cb[1] = ts2 >> 32;
+
+	return 0;
+}
-- 
2.30.2


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

* Re: [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI
  2022-08-09  6:08 [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI Kurt Kanzenbach
  2022-08-09  6:08 ` [PATCH bpf-next v2 1/2] bpf: " Kurt Kanzenbach
  2022-08-09  6:08 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add BPF-helper test for CLOCK_TAI access Kurt Kanzenbach
@ 2022-08-09 17:00 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-08-09 17:00 UTC (permalink / raw)
  To: Kurt Kanzenbach
  Cc: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, joannelkoong, jolsa, davemarchevsky, lorenzo,
	geliang.tang, jakub, netdev, bpf, tglx, maciej.fijalkowski,
	brouer

Hello:

This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Tue,  9 Aug 2022 08:08:01 +0200 you wrote:
> Hi,
> 
> add a BPF-helper for accessing CLOCK_TAI. Use cases for such a BPF helper
> include functionalities such as Tx launch time (e.g. ETF and TAPRIO Qdiscs),
> timestamping and policing.
> 
> Patch #1 - Introduce BPF helper
> Patch #2 - Add test case (skb based)
> 
> [...]

Here is the summary with links:
  - [bpf-next,v2,1/2] bpf: Add BPF-helper for accessing CLOCK_TAI
    https://git.kernel.org/bpf/bpf-next/c/c8996c98f703
  - [bpf-next,v2,2/2] selftests/bpf: Add BPF-helper test for CLOCK_TAI access
    https://git.kernel.org/bpf/bpf-next/c/64e15820b987

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2022-08-09 17:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-09  6:08 [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI Kurt Kanzenbach
2022-08-09  6:08 ` [PATCH bpf-next v2 1/2] bpf: " Kurt Kanzenbach
2022-08-09  6:08 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add BPF-helper test for CLOCK_TAI access Kurt Kanzenbach
2022-08-09 17:00 ` [PATCH bpf-next v2 0/2] Add BPF-helper for accessing CLOCK_TAI patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).