Message ID | 20240429213609.487820-6-thinker.li@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | Notify user space when a struct_ops object is detached/unregisterd | expand |
Context | Check | Description |
---|---|---|
bpf/vmtest-bpf-next-PR | fail | merge-conflict |
netdev/tree_selection | success | Clearly marked for bpf-next, async |
netdev/apply | fail | Patch does not apply to bpf-next-0 |
On Mon, Apr 29, 2024 at 2:36 PM Kui-Feng Lee <thinker.li@gmail.com> wrote: > > Add epoll support to bpf struct_ops links to trigger EPOLLHUP event upon > detachment. > > Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com> > --- > include/linux/bpf.h | 2 ++ > kernel/bpf/bpf_struct_ops.c | 14 ++++++++++++++ > kernel/bpf/syscall.c | 15 +++++++++++++++ > 3 files changed, 31 insertions(+) > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > index eeeed4b1bd32..a4550b927352 100644 > --- a/include/linux/bpf.h > +++ b/include/linux/bpf.h > @@ -1574,6 +1574,7 @@ struct bpf_link { > const struct bpf_link_ops *ops; > struct bpf_prog *prog; > struct work_struct work; > + wait_queue_head_t wait_hup; let's keep it struct_ops-specific, there is no need to pay for this for all existing BPF link types. We can always generalize later, if necessary. pw-bot: cr > }; > > struct bpf_link_ops { > @@ -1587,6 +1588,7 @@ struct bpf_link_ops { > struct bpf_link_info *info); > int (*update_map)(struct bpf_link *link, struct bpf_map *new_map, > struct bpf_map *old_map); > + __poll_t (*poll)(struct file *file, struct poll_table_struct *pts); > }; > > struct bpf_tramp_link { [...]
On 5/1/24 10:03, Andrii Nakryiko wrote: > On Mon, Apr 29, 2024 at 2:36 PM Kui-Feng Lee <thinker.li@gmail.com> wrote: >> >> Add epoll support to bpf struct_ops links to trigger EPOLLHUP event upon >> detachment. >> >> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com> >> --- >> include/linux/bpf.h | 2 ++ >> kernel/bpf/bpf_struct_ops.c | 14 ++++++++++++++ >> kernel/bpf/syscall.c | 15 +++++++++++++++ >> 3 files changed, 31 insertions(+) >> >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h >> index eeeed4b1bd32..a4550b927352 100644 >> --- a/include/linux/bpf.h >> +++ b/include/linux/bpf.h >> @@ -1574,6 +1574,7 @@ struct bpf_link { >> const struct bpf_link_ops *ops; >> struct bpf_prog *prog; >> struct work_struct work; >> + wait_queue_head_t wait_hup; > > let's keep it struct_ops-specific, there is no need to pay for this > for all existing BPF link types. We can always generalize later, if > necessary. > sure! > pw-bot: cr > > >> }; >> >> struct bpf_link_ops { >> @@ -1587,6 +1588,7 @@ struct bpf_link_ops { >> struct bpf_link_info *info); >> int (*update_map)(struct bpf_link *link, struct bpf_map *new_map, >> struct bpf_map *old_map); >> + __poll_t (*poll)(struct file *file, struct poll_table_struct *pts); >> }; >> >> struct bpf_tramp_link { > > [...]
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index eeeed4b1bd32..a4550b927352 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1574,6 +1574,7 @@ struct bpf_link { const struct bpf_link_ops *ops; struct bpf_prog *prog; struct work_struct work; + wait_queue_head_t wait_hup; }; struct bpf_link_ops { @@ -1587,6 +1588,7 @@ struct bpf_link_ops { struct bpf_link_info *info); int (*update_map)(struct bpf_link *link, struct bpf_map *new_map, struct bpf_map *old_map); + __poll_t (*poll)(struct file *file, struct poll_table_struct *pts); }; struct bpf_tramp_link { diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index 4a8a7e5ffc56..f19b6a76591a 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -12,6 +12,7 @@ #include <linux/mutex.h> #include <linux/btf_ids.h> #include <linux/rcupdate_wait.h> +#include <linux/poll.h> struct bpf_struct_ops_value { struct bpf_struct_ops_common_value common; @@ -1149,6 +1150,8 @@ bool bpf_struct_ops_kvalue_unreg(void *data) */ bpf_map_put(&st_map->map); + wake_up_interruptible_poll(&st_link->link.wait_hup, EPOLLHUP); + ret = true; fail_unlock: @@ -1276,15 +1279,26 @@ static int bpf_struct_ops_map_link_detach(struct bpf_link *link) mutex_unlock(&update_mutex); + wake_up_interruptible_poll(&st_link->link.wait_hup, EPOLLHUP); + return 0; } +static __poll_t bpf_struct_ops_map_link_poll(struct file *file, + struct poll_table_struct *ptrs) +{ + struct bpf_struct_ops_link *st_link = file->private_data; + + return (st_link->map) ? 0 : EPOLLHUP | EPOLLERR; +} + static const struct bpf_link_ops bpf_struct_ops_map_lops = { .dealloc = bpf_struct_ops_map_link_dealloc, .detach = bpf_struct_ops_map_link_detach, .show_fdinfo = bpf_struct_ops_map_link_show_fdinfo, .fill_link_info = bpf_struct_ops_map_link_fill_link_info, .update_map = bpf_struct_ops_map_link_update, + .poll = bpf_struct_ops_map_link_poll, }; int bpf_struct_ops_link_create(union bpf_attr *attr) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 4a2f95c4b2ac..b4dbca04d4f5 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2990,6 +2990,7 @@ void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, link->id = 0; link->ops = ops; link->prog = prog; + init_waitqueue_head(&link->wait_hup); } static void bpf_link_free_id(int id) @@ -3108,6 +3109,19 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp) } #endif +static __poll_t bpf_link_poll(struct file *file, struct poll_table_struct *pts) +{ + struct bpf_link *link = file->private_data; + + if (link->ops->poll) { + poll_wait(file, &link->wait_hup, pts); + + return link->ops->poll(file, pts); + } + + return 0; +} + static const struct file_operations bpf_link_fops = { #ifdef CONFIG_PROC_FS .show_fdinfo = bpf_link_show_fdinfo, @@ -3115,6 +3129,7 @@ static const struct file_operations bpf_link_fops = { .release = bpf_link_release, .read = bpf_dummy_read, .write = bpf_dummy_write, + .poll = bpf_link_poll, }; static int bpf_link_alloc_id(struct bpf_link *link)
Add epoll support to bpf struct_ops links to trigger EPOLLHUP event upon detachment. Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com> --- include/linux/bpf.h | 2 ++ kernel/bpf/bpf_struct_ops.c | 14 ++++++++++++++ kernel/bpf/syscall.c | 15 +++++++++++++++ 3 files changed, 31 insertions(+)