Benjamin Tissoires bentiss@kernel.org writes:
@@ -1245,6 +1294,7 @@ BPF_CALL_3(bpf_timer_set_callback, struct bpf_timer_kern *, timer, void *, callb ret = -EPERM; goto out; }
- down(&t->sleepable_lock); prev = t->prog; if (prev != prog) { /* Bump prog refcnt once. Every bpf_timer_set_callback()
@@ -1261,6 +1311,7 @@ BPF_CALL_3(bpf_timer_set_callback, struct bpf_timer_kern *, timer, void *, callb t->prog = prog; } rcu_assign_pointer(t->callback_fn, callback_fn);
- up(&t->sleepable_lock);
out: __bpf_spin_unlock_irqrestore(&timer->lock); return ret; @@ -1282,7 +1333,7 @@ BPF_CALL_3(bpf_timer_start, struct bpf_timer_kern *, timer, u64, nsecs, u64, fla if (in_nmi()) return -EOPNOTSUPP;
- if (flags & ~(BPF_F_TIMER_ABS | BPF_F_TIMER_CPU_PIN))
- if (flags & ~(BPF_F_TIMER_ABS | BPF_F_TIMER_CPU_PIN | BPF_F_TIMER_SLEEPABLE)) return -EINVAL; __bpf_spin_lock_irqsave(&timer->lock); t = timer->timer;
@@ -1299,7 +1350,10 @@ BPF_CALL_3(bpf_timer_start, struct bpf_timer_kern *, timer, u64, nsecs, u64, fla if (flags & BPF_F_TIMER_CPU_PIN) mode |= HRTIMER_MODE_PINNED;
- hrtimer_start(&t->timer, ns_to_ktime(nsecs), mode);
- if (flags & BPF_F_TIMER_SLEEPABLE)
schedule_work(&t->work);
- else
hrtimer_start(&t->timer, ns_to_ktime(nsecs), mode);
out: __bpf_spin_unlock_irqrestore(&timer->lock); return ret;
I think it's a little weird to just ignore the timeout parameter when called with the sleepable flag. But I guess it can work at least as a first pass; however, in that case we should enforce that the caller passes in a timeout of 0, so that if we do add support for a timeout for sleepable timers in the future, callers will be able to detect this.
-Toke