From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: "luwei (O)" <luwei32@huawei.com>,
Alexei Starovoitov <alexei.starovoitov@gmail.com>,
davem@davemloft.net
Cc: daniel@iogearbox.net, andrii@kernel.org, netdev@vger.kernel.org,
bpf@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH v4 bpf-next 1/9] bpf: Introduce bpf timers.
Date: Tue, 06 Jul 2021 17:44:22 +0200 [thread overview]
Message-ID: <87eecbxx9l.fsf@toke.dk> (raw)
In-Reply-To: <bcdccd37-6372-859f-824e-c96250361904@huawei.com>
"luwei (O)" <luwei32@huawei.com> writes:
> 在 2021/7/2 3:20 AM, Alexei Starovoitov 写道:
>> From: Alexei Starovoitov <ast@kernel.org>
>>
>> Introduce 'struct bpf_timer { __u64 :64; __u64 :64; };' that can be embedded
>> in hash/array/lru maps as a regular field and helpers to operate on it:
>>
>> // Initialize the timer.
>> // First 4 bits of 'flags' specify clockid.
>> // Only CLOCK_MONOTONIC, CLOCK_REALTIME, CLOCK_BOOTTIME are allowed.
>> long bpf_timer_init(struct bpf_timer *timer, struct bpf_map *map, int flags);
>>
>> // Configure the timer to call 'callback_fn' static function.
>> long bpf_timer_set_callback(struct bpf_timer *timer, void *callback_fn);
>>
>> // Arm the timer to expire 'nsec' nanoseconds from the current time.
>> long bpf_timer_start(struct bpf_timer *timer, u64 nsec, u64 flags);
>>
>> // Cancel the timer and wait for callback_fn to finish if it was running.
>> long bpf_timer_cancel(struct bpf_timer *timer);
>>
> [...]
>> +static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
>> +{
>> + struct bpf_hrtimer *t = container_of(hrtimer, struct bpf_hrtimer, timer);
>> + struct bpf_map *map = t->map;
>> + void *value = t->value;
>> + struct bpf_timer_kern *timer = value + map->timer_off;
>> + struct bpf_prog *prog;
>> + void *callback_fn;
>> + void *key;
>> + u32 idx;
>> + int ret;
>> +
>> + /* The triple underscore bpf_spin_lock is a direct call
>> + * to BPF_CALL_1(bpf_spin_lock) which does irqsave.
>> + */
>> + ____bpf_spin_lock(&timer->lock);
>> + /* callback_fn and prog need to match. They're updated together
>> + * and have to be read under lock.
>> + */
>> + prog = t->prog;
>> + callback_fn = t->callback_fn;
>> +
>> + /* wrap bpf subprog invocation with prog->refcnt++ and -- to make
>> + * sure that refcnt doesn't become zero when subprog is executing.
>> + * Do it under lock to make sure that bpf_timer_start doesn't drop
>> + * prev prog refcnt to zero before timer_cb has a chance to bump it.
>> + */
>> + bpf_prog_inc(prog);
>> + ____bpf_spin_unlock(&timer->lock);
>> +
>> + /* bpf_timer_cb() runs in hrtimer_run_softirq. It doesn't migrate and
>> + * cannot be preempted by another bpf_timer_cb() on the same cpu.
>> + * Remember the timer this callback is servicing to prevent
>> + * deadlock if callback_fn() calls bpf_timer_cancel() on the same timer.
>> + */
>> + this_cpu_write(hrtimer_running, t);
>> + if (map->map_type == BPF_MAP_TYPE_ARRAY) {
>> + struct bpf_array *array = container_of(map, struct bpf_array, map);
>> +
>> + /* compute the key */
>> + idx = ((char *)value - array->value) / array->elem_size;
>> + key = &idx;
>> + } else { /* hash or lru */
>> + key = value - round_up(map->key_size, 8);
>> + }
>> +
>> + ret = BPF_CAST_CALL(callback_fn)((u64)(long)map,
>> + (u64)(long)key,
>> + (u64)(long)value, 0, 0);
>> + WARN_ON(ret != 0); /* Next patch moves this check into the verifier */
>> + bpf_prog_put(prog);
>> +
>> + this_cpu_write(hrtimer_running, NULL);
>> + return HRTIMER_NORESTART;
>> +}
>> +
> Your patch is awesome, and I tried your example and it works, my
> call_back() is called after a certained time. But I am confued that
> the bpf_timer_cb() function only returns HRTIMER_NORESTART,
>
> how to trigger a periodic task, that means I want to call my call_back()
> periodically, not just for one time ?
The callback just needs to reschedule itself by calling
bpf_timer_start() again before exiting... :)
-Toke
next prev parent reply other threads:[~2021-07-06 15:44 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-01 19:20 [PATCH v4 bpf-next 0/9] bpf: Introduce BPF timers Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 1/9] bpf: Introduce bpf timers Alexei Starovoitov
2021-07-02 1:04 ` Martin KaFai Lau
2021-07-04 14:19 ` Alexei Starovoitov
2021-07-07 1:38 ` Alexei Starovoitov
2021-07-06 13:57 ` luwei (O)
2021-07-06 15:44 ` Toke Høiland-Jørgensen [this message]
2021-07-01 19:20 ` [PATCH v4 bpf-next 2/9] bpf: Add map side support for " Alexei Starovoitov
2021-07-02 6:23 ` Martin KaFai Lau
2021-07-04 14:23 ` Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 3/9] bpf: Prevent pointer mismatch in bpf_timer_init Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 4/9] bpf: Remember BTF of inner maps Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 5/9] bpf: Relax verifier recursion check Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 6/9] bpf: Implement verifier support for validation of async callbacks Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 7/9] bpf: Teach stack depth check about " Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 8/9] selftests/bpf: Add bpf_timer test Alexei Starovoitov
2021-07-01 19:20 ` [PATCH v4 bpf-next 9/9] selftests/bpf: Add a test with bpf_timer in inner map Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87eecbxx9l.fsf@toke.dk \
--to=toke@redhat.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=kernel-team@fb.com \
--cc=luwei32@huawei.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.