public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/2] bpf: Absolute timer support
@ 2023-03-02 11:46 Tero Kristo
  2023-03-02 11:46 ` [PATCHv2 1/2] bpf: Add support for absolute value BPF timers Tero Kristo
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Tero Kristo @ 2023-03-02 11:46 UTC (permalink / raw)
  To: ast, daniel, andrii, bpf; +Cc: linux-kernel

Hi,

v2 of this series just adds the selftest support. Patch #1 is modified
slightly (bpf.h modified under tools/include) so that the new selftest
compiles properly. I also added suggested-by tag from Artem whom I
forgot to add in the initial upstream post.

-Tero



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

* [PATCHv2 1/2] bpf: Add support for absolute value BPF timers
  2023-03-02 11:46 [PATCHv2 0/2] bpf: Absolute timer support Tero Kristo
@ 2023-03-02 11:46 ` Tero Kristo
  2023-03-02 11:46 ` [PATCHv2 2/2] selftests/bpf: Add absolute timer test Tero Kristo
  2023-03-03  7:10 ` [PATCHv2 0/2] bpf: Absolute timer support patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Tero Kristo @ 2023-03-02 11:46 UTC (permalink / raw)
  To: ast, daniel, andrii, bpf; +Cc: linux-kernel, Artem Bityutskiy

Add a new flag BPF_F_TIMER_ABS that can be passed to bpf_timer_start()
to start an absolute value timer instead of the default relative value.
This makes the timer expire at an exact point in time, instead of a time
with latencies induced by both the BPF and timer subsystems.

Suggested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Tero Kristo <tero.kristo@linux.intel.com>
---
v2:
 - added suggested by from Artem
 - copied the change from include/uapi/linux/bpf.h to tools/include also
   
 include/uapi/linux/bpf.h       | 15 +++++++++++++++
 kernel/bpf/helpers.c           | 11 +++++++++--
 tools/include/uapi/linux/bpf.h | 15 +++++++++++++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 464ca3f01fe7..7f5b71847984 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -4951,6 +4951,12 @@ union bpf_attr {
  *		different maps if key/value layout matches across maps.
  *		Every bpf_timer_set_callback() can have different callback_fn.
  *
+ *		*flags* can be one of:
+ *
+ *		**BPF_F_TIMER_ABS**
+ *			Start the timer in absolute expire value instead of the
+ *			default relative one.
+ *
  *	Return
  *		0 on success.
  *		**-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier
@@ -7050,4 +7056,13 @@ struct bpf_core_relo {
 	enum bpf_core_relo_kind kind;
 };
 
+/*
+ * Flags to control bpf_timer_start() behaviour.
+ *     - BPF_F_TIMER_ABS: Timeout passed is absolute time, by default it is
+ *       relative to current time.
+ */
+enum {
+	BPF_F_TIMER_ABS = (1ULL << 0),
+};
+
 #endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index af30c6cbd65d..924849d89828 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1253,10 +1253,11 @@ BPF_CALL_3(bpf_timer_start, struct bpf_timer_kern *, timer, u64, nsecs, u64, fla
 {
 	struct bpf_hrtimer *t;
 	int ret = 0;
+	enum hrtimer_mode mode;
 
 	if (in_nmi())
 		return -EOPNOTSUPP;
-	if (flags)
+	if (flags > BPF_F_TIMER_ABS)
 		return -EINVAL;
 	__bpf_spin_lock_irqsave(&timer->lock);
 	t = timer->timer;
@@ -1264,7 +1265,13 @@ BPF_CALL_3(bpf_timer_start, struct bpf_timer_kern *, timer, u64, nsecs, u64, fla
 		ret = -EINVAL;
 		goto out;
 	}
-	hrtimer_start(&t->timer, ns_to_ktime(nsecs), HRTIMER_MODE_REL_SOFT);
+
+	if (flags & BPF_F_TIMER_ABS)
+		mode = HRTIMER_MODE_ABS_SOFT;
+	else
+		mode = HRTIMER_MODE_REL_SOFT;
+
+	hrtimer_start(&t->timer, ns_to_ktime(nsecs), mode);
 out:
 	__bpf_spin_unlock_irqrestore(&timer->lock);
 	return ret;
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 464ca3f01fe7..7f5b71847984 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -4951,6 +4951,12 @@ union bpf_attr {
  *		different maps if key/value layout matches across maps.
  *		Every bpf_timer_set_callback() can have different callback_fn.
  *
+ *		*flags* can be one of:
+ *
+ *		**BPF_F_TIMER_ABS**
+ *			Start the timer in absolute expire value instead of the
+ *			default relative one.
+ *
  *	Return
  *		0 on success.
  *		**-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier
@@ -7050,4 +7056,13 @@ struct bpf_core_relo {
 	enum bpf_core_relo_kind kind;
 };
 
+/*
+ * Flags to control bpf_timer_start() behaviour.
+ *     - BPF_F_TIMER_ABS: Timeout passed is absolute time, by default it is
+ *       relative to current time.
+ */
+enum {
+	BPF_F_TIMER_ABS = (1ULL << 0),
+};
+
 #endif /* _UAPI__LINUX_BPF_H__ */
-- 
2.25.1


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

* [PATCHv2 2/2] selftests/bpf: Add absolute timer test
  2023-03-02 11:46 [PATCHv2 0/2] bpf: Absolute timer support Tero Kristo
  2023-03-02 11:46 ` [PATCHv2 1/2] bpf: Add support for absolute value BPF timers Tero Kristo
@ 2023-03-02 11:46 ` Tero Kristo
  2023-03-03  7:10 ` [PATCHv2 0/2] bpf: Absolute timer support patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Tero Kristo @ 2023-03-02 11:46 UTC (permalink / raw)
  To: ast, daniel, andrii, bpf; +Cc: linux-kernel

Add test for the absolute BPF timer under the existing timer tests. This
will run the timer two times with 1us expiration time, and then re-arm
the timer at ~35s in the future. At the end, it is verified that the
absolute timer expired exactly two times.

Signed-off-by: Tero Kristo <tero.kristo@linux.intel.com>
---
v2: new patch added

 .../testing/selftests/bpf/prog_tests/timer.c  |  3 ++
 tools/testing/selftests/bpf/progs/timer.c     | 45 +++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/timer.c b/tools/testing/selftests/bpf/prog_tests/timer.c
index 7eb049214859..290c21dbe65a 100644
--- a/tools/testing/selftests/bpf/prog_tests/timer.c
+++ b/tools/testing/selftests/bpf/prog_tests/timer.c
@@ -29,6 +29,9 @@ static int timer(struct timer *timer_skel)
 	/* check that timer_cb2() was executed twice */
 	ASSERT_EQ(timer_skel->bss->bss_data, 10, "bss_data");
 
+	/* check that timer_cb3() was executed twice */
+	ASSERT_EQ(timer_skel->bss->abs_data, 12, "abs_data");
+
 	/* check that there were no errors in timer execution */
 	ASSERT_EQ(timer_skel->bss->err, 0, "err");
 
diff --git a/tools/testing/selftests/bpf/progs/timer.c b/tools/testing/selftests/bpf/progs/timer.c
index acda5c9cea93..9a16d95213e1 100644
--- a/tools/testing/selftests/bpf/progs/timer.c
+++ b/tools/testing/selftests/bpf/progs/timer.c
@@ -46,7 +46,15 @@ struct {
 	__type(value, struct elem);
 } lru SEC(".maps");
 
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__uint(max_entries, 1);
+	__type(key, int);
+	__type(value, struct elem);
+} abs_timer SEC(".maps");
+
 __u64 bss_data;
+__u64 abs_data;
 __u64 err;
 __u64 ok;
 __u64 callback_check = 52;
@@ -284,3 +292,40 @@ int BPF_PROG2(test2, int, a, int, b)
 
 	return bpf_timer_test();
 }
+
+/* callback for absolute timer */
+static int timer_cb3(void *map, int *key, struct bpf_timer *timer)
+{
+	abs_data += 6;
+
+	if (abs_data < 12) {
+		bpf_timer_start(timer, bpf_ktime_get_boot_ns() + 1000,
+				BPF_F_TIMER_ABS);
+	} else {
+		/* Re-arm timer ~35 seconds in future */
+		bpf_timer_start(timer, bpf_ktime_get_boot_ns() + (1ull << 35),
+				BPF_F_TIMER_ABS);
+	}
+
+	return 0;
+}
+
+SEC("fentry/bpf_fentry_test3")
+int BPF_PROG2(test3, int, a)
+{
+	int key = 0;
+	struct bpf_timer *timer;
+
+	bpf_printk("test3");
+
+	timer = bpf_map_lookup_elem(&abs_timer, &key);
+	if (timer) {
+		if (bpf_timer_init(timer, &abs_timer, CLOCK_BOOTTIME) != 0)
+			err |= 2048;
+		bpf_timer_set_callback(timer, timer_cb3);
+		bpf_timer_start(timer, bpf_ktime_get_boot_ns() + 1000,
+				BPF_F_TIMER_ABS);
+	}
+
+	return 0;
+}
-- 
2.25.1


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

* Re: [PATCHv2 0/2] bpf: Absolute timer support
  2023-03-02 11:46 [PATCHv2 0/2] bpf: Absolute timer support Tero Kristo
  2023-03-02 11:46 ` [PATCHv2 1/2] bpf: Add support for absolute value BPF timers Tero Kristo
  2023-03-02 11:46 ` [PATCHv2 2/2] selftests/bpf: Add absolute timer test Tero Kristo
@ 2023-03-03  7:10 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-03-03  7:10 UTC (permalink / raw)
  To: Tero Kristo; +Cc: ast, daniel, andrii, bpf, linux-kernel

Hello:

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

On Thu,  2 Mar 2023 13:46:12 +0200 you wrote:
> Hi,
> 
> v2 of this series just adds the selftest support. Patch #1 is modified
> slightly (bpf.h modified under tools/include) so that the new selftest
> compiles properly. I also added suggested-by tag from Artem whom I
> forgot to add in the initial upstream post.
> 
> [...]

Here is the summary with links:
  - [PATCHv2,1/2] bpf: Add support for absolute value BPF timers
    https://git.kernel.org/bpf/bpf-next/c/f71f8530494b
  - [PATCHv2,2/2] selftests/bpf: Add absolute timer test
    https://git.kernel.org/bpf/bpf-next/c/944459e88b4f

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:[~2023-03-03  7:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-02 11:46 [PATCHv2 0/2] bpf: Absolute timer support Tero Kristo
2023-03-02 11:46 ` [PATCHv2 1/2] bpf: Add support for absolute value BPF timers Tero Kristo
2023-03-02 11:46 ` [PATCHv2 2/2] selftests/bpf: Add absolute timer test Tero Kristo
2023-03-03  7:10 ` [PATCHv2 0/2] bpf: Absolute timer support 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