[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CACAyw9-7dPx1vLNQeYP9Zqx=OwNcd2t1VK3XGD_aUZZG-twrOg@mail.gmail.com>
Date: Mon, 24 May 2021 12:49:52 +0100
From: Lorenz Bauer <lmb@...udflare.com>
To: Alexei Starovoitov <alexei.starovoitov@...il.com>
Cc: "David S . Miller" <davem@...emloft.net>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>,
John Fastabend <john.fastabend@...il.com>,
Networking <netdev@...r.kernel.org>, bpf <bpf@...r.kernel.org>,
Kernel Team <kernel-team@...com>
Subject: Re: [RFC PATCH bpf-next] bpf: Introduce bpf_timer
On Thu, 20 May 2021 at 19:55, Alexei Starovoitov
<alexei.starovoitov@...il.com> wrote:
>
> From: Alexei Starovoitov <ast@...nel.org>
>
> Introduce 'struct bpf_timer' that can be embedded in most BPF map types
> and helpers to operate on it:
> long bpf_timer_init(struct bpf_timer *timer, void *callback, int flags)
> long bpf_timer_mod(struct bpf_timer *timer, u64 msecs)
> long bpf_timer_del(struct bpf_timer *timer)
I like invoking the callback with a pointer to the map element it was
defined in, since it solves lifetime of the context and user space
introspection of the same. I'm not so sure about being able to put it
into all different kinds of maps, is that really going to be used?
It would be useful if Cong Wang could describe their use case, it's
kind of hard to tell what the end goal is. Should user space be able
to create and arm timers? Or just BPF? In the other thread it seems
like a primitive for waiting on a timer is proposed. Why? It also begs
the question how we would wait on multiple timers.
>
> Signed-off-by: Alexei Starovoitov <ast@...nel.org>
> ---
> This is work in progress, but gives an idea on how API will look.
> ---
> include/linux/bpf.h | 1 +
> include/uapi/linux/bpf.h | 25 ++++
> kernel/bpf/helpers.c | 106 +++++++++++++++++
> kernel/bpf/verifier.c | 110 ++++++++++++++++++
> kernel/trace/bpf_trace.c | 2 +-
> scripts/bpf_doc.py | 2 +
> tools/include/uapi/linux/bpf.h | 25 ++++
> .../testing/selftests/bpf/prog_tests/timer.c | 42 +++++++
> tools/testing/selftests/bpf/progs/timer.c | 53 +++++++++
> 9 files changed, 365 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/bpf/prog_tests/timer.c
> create mode 100644 tools/testing/selftests/bpf/progs/timer.c
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 9dc44ba97584..18e09cc0c410 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -312,6 +312,7 @@ enum bpf_arg_type {
> ARG_PTR_TO_FUNC, /* pointer to a bpf program function */
> ARG_PTR_TO_STACK_OR_NULL, /* pointer to stack or NULL */
> ARG_PTR_TO_CONST_STR, /* pointer to a null terminated read-only string */
> + ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
> __BPF_ARG_TYPE_MAX,
> };
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 418b9b813d65..c95d7854d9fb 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -4761,6 +4761,24 @@ union bpf_attr {
> * Execute close syscall for given FD.
> * Return
> * A syscall result.
> + *
> + * long bpf_timer_init(struct bpf_timer *timer, void *callback, int flags)
In your selftest the callback has a type (int)(*callback)(struct
bpf_map *map, int *key, struct map_elem *val).
> + * Description
> + * Initialize the timer to call given static function.
> + * Return
> + * zero
> + *
> + * long bpf_timer_mod(struct bpf_timer *timer, u64 msecs)
> + * Description
> + * Set the timer expiration N msecs from the current time.
> + * Return
> + * zero
> + *
> + * long bpf_timer_del(struct bpf_timer *timer)
> + * Description
> + * Deactivate the timer.
> + * Return
> + * zero
> */
> #define __BPF_FUNC_MAPPER(FN) \
> FN(unspec), \
> @@ -4932,6 +4950,9 @@ union bpf_attr {
> FN(sys_bpf), \
> FN(btf_find_by_name_kind), \
> FN(sys_close), \
> + FN(timer_init), \
> + FN(timer_mod), \
> + FN(timer_del), \
> /* */
How can user space force stopping of timers (required IMO)?
>
> /* integer value in 'imm' field of BPF_CALL instruction selects which helper
> @@ -6038,6 +6059,10 @@ struct bpf_spin_lock {
> __u32 val;
> };
>
> +struct bpf_timer {
> + __u64 opaque;
> +};
> +
This might be clear already, but we won't be able to modify the size
of bpf_timer later since it would break uapi, right?
--
Lorenz Bauer | Systems Engineer
6th Floor, County Hall/The Riverside Building, SE1 7PB, UK
www.cloudflare.com
Powered by blists - more mailing lists