IR decoding using BPF
Subsystems (13)
Sean Young
maintainerv5 cover IR decoding using BPF
The kernel IR decoders (drivers/media/rc/ir-*-decoder.c) support the most widely used IR protocols, but there are many protocols which are not supported[1]. For example, the lirc-remotes[2] repo has over 2700 remotes, many of which are not supported by rc-core. There is a "long tail" of unsupported IR protocols, for which lircd is need to decode the IR .
IR encoding is done in such a way that some simple circuit can decode it; therefore, bpf is ideal.
In order to support all these protocols, here we have bpf based IR decoding. The idea is that user-space can define a decoder in bpf, attach it to the rc device through the lirc chardev.
Separate work is underway to extend ir-keytable to have an extensive library of bpf-based decoders, and a much expanded library of rc keymaps.
Another future application would be to compile IRP[3] to a IR BPF program, and so support virtually every remote without having to write a decoder for each. It might also be possible to support non-button devices such as analog directional pads or air conditioning remote controls and decode the target temperature in bpf, and pass that to an input device.
Thanks,
Sean Young
[1] http://www.hifi-remote.com/wiki/index.php?title=DecodeIR
[2] https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/remotes/
[3] http://www.hifi-remote.com/wiki/index.php?title=IRP_Notation
Changes since v4:
- Renamed rc_dev_bpf_{attach,detach,query} to lirc_bpf_{attach,detach,query}
- Fixed error path in lirc_bpf_query
- Rebased on bpf-next
Changes since v3:
- Implemented review comments from Quentin Monnet and Y Song (thanks!)
- More helpful and better formatted bpf helper documentation
- Changed back to bpf_prog_array rather than open-coded implementation
- scancodes can be 64 bit
- bpf gets passed values in microseconds, not nanoseconds. microseconds is more than than enough (IR receivers support carriers upto 70kHz, at which point a single period is already 14 microseconds). Also, this makes it much more consistent with lirc mode2.
- Since it looks much more like lirc mode2, rename the program type to BPF_PROG_TYPE_LIRC_MODE2.
- Rebased on bpf-next
Changes since v2:
- Fixed locking issues
- Improved self-test to cover more cases
- Rebased on bpf-next again
Changes since v1:
- Code review comments from Y Song <[email protected]> and Randy Dunlap <[email protected]>
- Re-wrote sample bpf to be selftest
- Renamed RAWIR_DECODER -> RAWIR_EVENT (Kconfig, context, bpf prog type)
- Rebase on bpf-next
- Introduced bpf_rawir_event context structure with simpler access checking
Sean Young (3):
bpf: bpf_prog_array_copy() should return -ENOENT if exclude_prog not
found
media: rc: introduce BPF_PROG_LIRC_MODE2
bpf: add selftest for lirc_mode2 type program
drivers/media/rc/Kconfig | 13 + drivers/media/rc/Makefile | 1 + drivers/media/rc/bpf-lirc.c | 313 ++++++++++++++++++ drivers/media/rc/lirc_dev.c | 30 ++ drivers/media/rc/rc-core-priv.h | 21 ++ drivers/media/rc/rc-ir-raw.c | 12 +- include/linux/bpf_lirc.h | 29 ++ include/linux/bpf_types.h | 3 + include/uapi/linux/bpf.h | 53 ++- kernel/bpf/core.c | 11 +- kernel/bpf/syscall.c | 7 + kernel/trace/bpf_trace.c | 2 + tools/bpf/bpftool/prog.c | 1 + tools/include/uapi/linux/bpf.h | 53 ++- tools/include/uapi/linux/lirc.h | 217 ++++++++++++ tools/lib/bpf/libbpf.c | 1 + tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 7 +- tools/testing/selftests/bpf/bpf_helpers.h | 5 + .../testing/selftests/bpf/test_lirc_mode2.sh | 28 ++ .../selftests/bpf/test_lirc_mode2_kern.c | 23 ++ .../selftests/bpf/test_lirc_mode2_user.c | 149 +++++++++ 22 files changed, 971 insertions(+), 9 deletions(-) create mode 100644 drivers/media/rc/bpf-lirc.c create mode 100644 include/linux/bpf_lirc.h create mode 100644 tools/include/uapi/linux/lirc.h create mode 100755 tools/testing/selftests/bpf/test_lirc_mode2.sh create mode 100644 tools/testing/selftests/bpf/test_lirc_mode2_kern.c create mode 100644 tools/testing/selftests/bpf/test_lirc_mode2_user.c
Signature · 1 line
2.17.0
Sean Young
maintainerPATCH v5 1/3 bpf: bpf_prog_array_copy() should return -ENOENT if exclude_prog not found
This makes is it possible for bpf prog detach to return -ENOENT.
--- kernel/bpf/core.c | 11 +++++++++-- kernel/trace/bpf_trace.c | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-)
kernel/bpf/core.c +9 -2
@@ -1616,6 +1616,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,int new_prog_cnt, carry_prog_cnt =0 ;struct bpf_prog **existing_prog;struct bpf_prog_array *array; +bool found_exclude = false;int new_prog_idx =0 ;/* Figure out how many existing progs we need to carry over to
@@ -1624,14 +1625,20 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,if (old_array) { existing_prog = old_array->progs;for (; *existing_prog; existing_prog++) { -if (*existing_prog != exclude_prog && - *existing_prog != &dummy_bpf_prog.prog) +if (*existing_prog == exclude_prog) { + found_exclude = true; +continue ; + } +if (*existing_prog != &dummy_bpf_prog.prog) carry_prog_cnt++;if (*existing_prog == include_prog)return -EEXIST ; } } +if (exclude_prog && !found_exclude) +return -ENOENT ; +/* How many progs (not NULL) will be in the new array? */ new_prog_cnt = carry_prog_cnt;if (include_prog)
kernel/trace/bpf_trace.c +2 -0
@@ -1006,6 +1006,8 @@ void perf_event_detach_bpf_prog(struct perf_event *event) old_array = event->tp_event->prog_array; ret =bpf_prog_array_copy (old_array, event->prog,NULL , &new_array); +if (ret == -ENOENT ) + goto unlock;if (ret <0 ) {bpf_prog_array_delete_safe (old_array, event->prog); }else {
Signature · 1 line
2.17.0
Sean Young
maintainerPATCH v5 2/3 media: rc: introduce BPF_PROG_LIRC_MODE2
In reply to Sean YoungAdd support for BPF_PROG_LIRC_MODE2. This type of BPF program can call rc_keydown() to reported decoded IR scancodes, or rc_repeat() to report that the last key should be repeated.
The bpf program can be attached to using the bpf(BPF_PROG_ATTACH) syscall; the target_fd must be the /dev/lircN device.
--- drivers/media/rc/Kconfig | 13 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/bpf-lirc.c | 313 ++++++++++++++++++++++++++++++++ drivers/media/rc/lirc_dev.c | 30 +++ drivers/media/rc/rc-core-priv.h | 21 +++ drivers/media/rc/rc-ir-raw.c | 12 +- include/linux/bpf_lirc.h | 29 +++ include/linux/bpf_types.h | 3 + include/uapi/linux/bpf.h | 53 +++++- kernel/bpf/syscall.c | 7 + 10 files changed, 479 insertions(+), 3 deletions(-) create mode 100644 drivers/media/rc/bpf-lirc.c create mode 100644 include/linux/bpf_lirc.h
drivers/media/rc/Kconfig +13 -0
@@ -25,6 +25,19 @@ config LIRC passes raw IR to and from userspace, which is needed for IR transmitting (aka "blasting") and for the lirc daemon. +config BPF_LIRC_MODE2 + bool "Support for eBPF programs attached to lirc devices" + depends on BPF_SYSCALL + depends on RC_CORE=y + depends on LIRC + help + Allow attaching eBPF programs to a lirc device using the bpf(2) + syscall command BPF_PROG_ATTACH. This is supported for raw IR + receivers. + + These eBPF programs can be used to decode IR into scancodes, for + IR protocols not supported by the kernel decoders. + menuconfig RC_DECODERS bool "Remote controller decoders" depends on RC_CORE
drivers/media/rc/Makefile +1 -0
@@ -5,6 +5,7 @@ obj-y += keymaps/ obj-$(CONFIG_RC_CORE) += rc-core.o rc-core-y := rc-main.o rc-ir-raw.o rc-core-$(CONFIG_LIRC) += lirc_dev.o +rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
drivers/media/rc/bpf-lirc.c new file +313 -0
313 lines not on this page · raw message
drivers/media/rc/lirc_dev.c +30 -0
@@ -20,6 +20,7 @@#include <linux/module.h> #include <linux/mutex.h> #include <linux/device.h> +#include <linux/file.h> #include <linux/idr.h> #include <linux/poll.h> #include <linux/sched.h>
@@ -104,6 +105,12 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) TO_US(ev.duration), TO_STR(ev.pulse)); } +/* +* bpf does not care about the gap generated above; that exists +* for backwards compatibility +*/ +lirc_bpf_run (dev, sample); +spin_lock_irqsave (&dev->lirc_fh_lock, flags);list_for_each_entry (fh, &dev->lirc_fh, list) {if (LIRC_IS_TIMEOUT (sample) && !fh->send_timeout_reports)
@@ -816,4 +823,27 @@ void __exit lirc_dev_exit(void)unregister_chrdev_region (lirc_base_dev,RC_DEV_MAX ); } +struct rc_dev *rc_dev_get_from_fd (int fd) +{ +struct fd f =fdget (fd); +struct lirc_fh *fh; +struct rc_dev *dev; + +if (!f.file) +return ERR_PTR (-EBADF ); + +if (f.file->f_op != &lirc_fops) { +fdput (f); +return ERR_PTR (-EINVAL ); + } + + fh = f.file->private_data; + dev = fh->rc; + +get_device (&dev->dev); +fdput (f); + +return dev; +} +MODULE_ALIAS ("lirc_dev" );
drivers/media/rc/rc-core-priv.h +21 -0
@@ -13,6 +13,7 @@#define MAX_IR_EVENT_SIZE 512#include <linux/slab.h> +#include <uapi/linux/bpf.h> #include <media/rc-core.h> /**
@@ -57,6 +58,11 @@ struct ir_raw_event_ctrl {/* raw decoder state follows */ struct ir_raw_event prev_ev;struct ir_raw_event this_ev; + +#ifdef CONFIG_BPF_LIRC_MODE2 +u32 bpf_sample; +struct bpf_prog_array __rcu *progs; +#endif struct nec_dec {int state;unsigned count;
@@ -126,6 +132,9 @@ struct ir_raw_event_ctrl { } imon; }; +/* Mutex for locking raw IR processing and handler change */ +extern struct mutex ir_raw_handler_lock; +/* macros for IR decoders */ static inline bool geq_margin (unsigned d1,unsigned d2,unsigned margin) {
@@ -288,6 +297,7 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);void ir_lirc_scancode_event (struct rc_dev *dev,struct lirc_scancode *lsc);int ir_lirc_register (struct rc_dev *dev);void ir_lirc_unregister (struct rc_dev *dev); +struct rc_dev *rc_dev_get_from_fd (int fd);#else static inline int lirc_dev_init (void ) {return 0 ; }static inline void lirc_dev_exit (void ) {}
@@ -299,4 +309,15 @@ static inline int ir_lirc_register(struct rc_dev *dev) { return 0; }static inline void ir_lirc_unregister (struct rc_dev *dev) { }#endif +/* +* bpf interface +*/ +#ifdef CONFIG_BPF_LIRC_MODE2 +void lirc_bpf_free (struct rc_dev *dev); +void lirc_bpf_run (struct rc_dev *dev,u32 sample); +#else +static inline void lirc_bpf_free (struct rc_dev *dev) { } +static inline void lirc_bpf_run (struct rc_dev *dev,u32 sample) { } +#endif +#endif /* _RC_CORE_PRIV */
drivers/media/rc/rc-ir-raw.c +10 -2
@@ -14,7 +14,7 @@static LIST_HEAD (ir_raw_client_list);/* Used to handle IR raw handler extensions */ -static DEFINE_MUTEX (ir_raw_handler_lock); +DEFINE_MUTEX (ir_raw_handler_lock);static LIST_HEAD (ir_raw_handler_list);static atomic64_t available_protocols =ATOMIC64_INIT (0 );
@@ -621,9 +621,17 @@ void ir_raw_event_unregister(struct rc_dev *dev)list_for_each_entry (handler, &ir_raw_handler_list, list)if (handler->raw_unregister) handler->raw_unregister (dev); -mutex_unlock (&ir_raw_handler_lock); + +lirc_bpf_free (dev);ir_raw_event_free (dev); + +/* +* A user can be calling bpf(BPF_PROG_{QUERY|ATTACH|DETACH}), so +* ensure that the raw member is null on unlock; this is how +* "device gone" is checked. +*/ +mutex_unlock (&ir_raw_handler_lock); }/*
include/linux/bpf_lirc.h new file +29 -0
@@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _BPF_LIRC_H +#define _BPF_LIRC_H + +#include <uapi/linux/bpf.h> + +#ifdef CONFIG_BPF_LIRC_MODE2 +int lirc_prog_attach (const union bpf_attr *attr); +int lirc_prog_detach (const union bpf_attr *attr); +int lirc_prog_query (const union bpf_attr *attr,union bpf_attr __user *uattr); +#else +static inline int lirc_prog_attach (const union bpf_attr *attr) +{ +return -EINVAL ; +} + +static inline int lirc_prog_detach (const union bpf_attr *attr) +{ +return -EINVAL ; +} + +static inline int lirc_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#endif + +#endif /* _BPF_LIRC_H */
include/linux/bpf_types.h +3 -0
@@ -26,6 +26,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_RAW_TRACEPOINT, raw_tracepoint)#ifdef CONFIG_CGROUP_BPF BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_DEVICE, cg_dev)#endif +#ifdef CONFIG_BPF_LIRC_MODE2 +BPF_PROG_TYPE(BPF_PROG_TYPE_LIRC_MODE2, lirc_mode2) +#endif BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)BPF_MAP_TYPE (BPF_MAP_TYPE_PERCPU_ARRAY , percpu_array_map_ops)
include/uapi/linux/bpf.h +52 -1
77 lines not on this page · raw message
kernel/bpf/syscall.c +7 -0
@@ -11,6 +11,7 @@*/ #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <linux/bpf_lirc.h> #include <linux/btf.h> #include <linux/syscalls.h> #include <linux/slab.h>
@@ -1578,6 +1579,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , true); +case BPF_LIRC_MODE2 : +return lirc_prog_attach (attr);default :return -EINVAL ; }
@@ -1648,6 +1651,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , false); +case BPF_LIRC_MODE2 : +return lirc_prog_detach (attr);default :return -EINVAL ; }
@@ -1695,6 +1700,8 @@ static int bpf_prog_query(const union bpf_attr *attr,case BPF_CGROUP_SOCK_OPS :case BPF_CGROUP_DEVICE :break ; +case BPF_LIRC_MODE2 : +return lirc_prog_query (attr, uattr);default :return -EINVAL ; }
Signature · 1 line
2.17.0
Sean Young
maintainerPATCH v5 3/3 bpf: add selftest for lirc_mode2 type program
In reply to Sean YoungThis is simple test over rc-loopback.
--- tools/bpf/bpftool/prog.c | 1 + tools/include/uapi/linux/bpf.h | 53 ++++- tools/include/uapi/linux/lirc.h | 217 ++++++++++++++++++ tools/lib/bpf/libbpf.c | 1 + tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 7 +- tools/testing/selftests/bpf/bpf_helpers.h | 5 + .../testing/selftests/bpf/test_lirc_mode2.sh | 28 +++ .../selftests/bpf/test_lirc_mode2_kern.c | 23 ++ .../selftests/bpf/test_lirc_mode2_user.c | 149 ++++++++++++ 10 files changed, 481 insertions(+), 4 deletions(-) create mode 100644 tools/include/uapi/linux/lirc.h create mode 100755 tools/testing/selftests/bpf/test_lirc_mode2.sh create mode 100644 tools/testing/selftests/bpf/test_lirc_mode2_kern.c create mode 100644 tools/testing/selftests/bpf/test_lirc_mode2_user.c
tools/bpf/bpftool/prog.c +1 -0
@@ -71,6 +71,7 @@ static const char * const prog_type_name[] = { [BPF_PROG_TYPE_SK_MSG] = "sk_msg", [BPF_PROG_TYPE_RAW_TRACEPOINT] = "raw_tracepoint", [BPF_PROG_TYPE_CGROUP_SOCK_ADDR] = "cgroup_sock_addr", + [BPF_PROG_TYPE_LIRC_MODE2] = "lirc_mode2", };static void print_boot_time (__u64 nsecs,char *buf,unsigned int size)
tools/include/uapi/linux/bpf.h +52 -1
77 lines not on this page · raw message
tools/include/uapi/linux/lirc.h new file +217 -0
217 lines not on this page · raw message
tools/lib/bpf/libbpf.c +1 -0
@@ -1462,6 +1462,7 @@ static bool bpf_prog_type__needs_kver(enum bpf_prog_type type)case BPF_PROG_TYPE_CGROUP_DEVICE :case BPF_PROG_TYPE_SK_MSG :case BPF_PROG_TYPE_CGROUP_SOCK_ADDR : +case BPF_PROG_TYPE_LIRC_MODE2 :return false;case BPF_PROG_TYPE_UNSPEC :case BPF_PROG_TYPE_KPROBE :
tools/testing/selftests/bpf/.gitignore +1 -0
@@ -17,3 +17,4 @@ test_sock_addr urandom_read test_btf test_sockmap +test_lirc_mode2_user
tools/testing/selftests/bpf/Makefile +4 -3
@@ -24,7 +24,7 @@ urandom_read: urandom_read.c # Order correspond to 'make run_tests' order TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ - test_sock test_btf test_sockmap + test_sock test_btf test_sockmap test_lirc_mode2_user TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
@@ -34,7 +34,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \ test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \ test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \ - test_lwt_seg6local.o + test_lwt_seg6local.o test_lirc_mode2_kern.o # Order correspond to 'make run_tests' order TEST_PROGS := test_kmod.sh \
@@ -44,7 +44,8 @@ TEST_PROGS := test_kmod.sh \ test_offload.py \ test_sock_addr.sh \ test_tunnel.sh \ - test_lwt_seg6local.sh + test_lwt_seg6local.sh \ + test_lirc_mode2.sh # Compile but not part of 'make run_tests' TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
tools/testing/selftests/bpf/bpf_helpers.h +5 -0
@@ -126,6 +126,11 @@ static int (*bpf_lwt_seg6_action)(void *ctx, unsigned int action, void *param,static int (*bpf_lwt_seg6_adjust_srh)(void *ctx,unsigned int offset,unsigned int len) = (void *) BPF_FUNC_lwt_seg6_adjust_srh; +static int (*bpf_rc_repeat)(void *ctx) = + (void *) BPF_FUNC_rc_repeat; +static int (*bpf_rc_keydown)(void *ctx,unsigned int protocol, +unsigned long long scancode,unsigned int toggle) = + (void *) BPF_FUNC_rc_keydown;/* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions
tools/testing/selftests/bpf/test_lirc_mode2.sh new file +28 -0
@@ -0,0 +1,28 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +GREEN='\033[0;92m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +modprobe rc-loopback + +for i in /sys/class/rc/rc* +do + if grep -q DRV_NAME=rc-loopback $i/uevent + then + LIRCDEV=$(grep DEVNAME= $i/lirc*/uevent | sed sQDEVNAME=Q/dev/Q) + fi +done + +if [ -n $LIRCDEV ]; +then + TYPE=lirc_mode2 + ./test_lirc_mode2_user $LIRCDEV + ret=$? + if [ $ret -ne 0 ]; then + echo -e ${RED}"FAIL: $TYPE"${NC} + else + echo -e ${GREEN}"PASS: $TYPE"${NC} + fi +fi
tools/testing/selftests/bpf/test_lirc_mode2_kern.c new file +23 -0
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +// test ir decoder +// +// Copyright (C) 2018 Sean Young <[email protected]> + +#include <linux/bpf.h> +#include <linux/lirc.h> +#include "bpf_helpers.h" + +SEC("lirc_mode2") +int bpf_decoder (unsigned int *sample) +{ +if (LIRC_IS_PULSE (*sample)) { +unsigned int duration =LIRC_VALUE (*sample); + +if (duration &0x10000 ) +bpf_rc_keydown (sample,0x40 , duration &0xffff ,0 ); + } + +return 0 ; +} + +char _license[] SEC("license") = "GPL";
tools/testing/selftests/bpf/test_lirc_mode2_user.c new file +149 -0
149 lines not on this page · raw message
Signature · 1 line
2.17.0
Quoted 53 lines · Sean Young
The kernel IR decoders (
drivers/media/rc/ir-*-decoder.c) support the most widely used IR protocols, but there are many protocols which are not supported[1]. For example, the lirc-remotes[2] repo has over 2700 remotes, many of which are not supported by rc-core. There is a "long tail" of unsupported IR protocols, for which lircd is need to decode the IR .IR encoding is done in such a way that some simple circuit can decode it; therefore, bpf is ideal.
In order to support all these protocols, here we have bpf based IR decoding. The idea is that user-space can define a decoder in bpf, attach it to the rc device through the lirc chardev.
Separate work is underway to extend ir-keytable to have an extensive library of bpf-based decoders, and a much expanded library of rc keymaps.
Another future application would be to compile IRP[3] to a IR BPF program, and so support virtually every remote without having to write a decoder for each. It might also be possible to support non-button devices such as analog directional pads or air conditioning remote controls and decode the target temperature in bpf, and pass that to an input device.
Thanks,
Sean Young
[1] http://www.hifi-remote.com/wiki/index.php?title=DecodeIR
[2] https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/remotes/
[3] http://www.hifi-remote.com/wiki/index.php?title=IRP_NotationChanges since v4:
- Renamed rc_dev_bpf_{attach,detach,query} to lirc_bpf_{attach,detach,query}
- Fixed error path inlirc_bpf_query
- Rebased on bpf-nextChanges since v3:
- Implemented review comments from Quentin Monnet and Y Song (thanks!)
- More helpful and better formatted bpf helper documentation
- Changed back tobpf_prog_arrayrather than open-coded implementation
- scancodes can be 64 bit
- bpf gets passed values in microseconds, not nanoseconds. microseconds is more than than enough (IR receivers support carriers upto 70kHz, at which point a single period is already 14 microseconds). Also, this makes it much more consistent with lirc mode2.
- Since it looks much more like lirc mode2, rename the program type toBPF_PROG_TYPE_LIRC_MODE2.
- Rebased on bpf-nextChanges since v2:
- Fixed locking issues
- Improved self-test to cover more cases
- Rebased on bpf-next again
Quoted 7 lines
Changes since v1:
- Code review comments from Y Song <[email protected]> and Randy Dunlap <[email protected]>
- Re-wrote sample bpf to be selftest
- RenamedRAWIR_DECODER->RAWIR_EVENT(Kconfig, context, bpf prog type)
- Rebase on bpf-next
- Introducedbpf_rawir_eventcontext structure with simpler access checking
Applied to bpf-next, thanks Sean!
Re: [PATCH v5 2/3] media: rc: introduce BPF_PROG_LIRC_MODE2
In reply to Sean YoungHi Sean,
I finally found the time to test your patch series and noticed 2 issues - comments are inline
drivers/media/rc/Kconfig config LIRC · line 31
Quoted 12 lines · Sean Young
drivers/media/rc/Kconfig +4
-0@@ -25,6 +25,19 @@ config LIRC passes raw IR to and from userspace, which is needed for IR transmitting (aka "blasting") and for the lirc daemon. +config BPF_LIRC_MODE2 + bool "Support for eBPF programs attached to lirc devices" + depends on BPF_SYSCALL + depends on RC_CORE=y
Requiring rc-core to be built into the kernel could become problematic in the future for people using media_build.
Currently the whole media tree (including rc-core) can be built as modules so DVB and IR drivers can be replaced by newer versions. But with rc-core in the kernel things could easily break if internal data structures are changed.
Maybe we should add a small layer with a stable API/ABI between bpf-lirc and rc-core to decouple them? Or would it be possible to build rc-core with bpf support as a module?
Quoted 44 lines
drivers/media/rc/Kconfig +9
-0+ depends on LIRC + help + Allow attaching eBPF programs to a lirc device using the bpf(2) + syscall command BPF_PROG_ATTACH. This is supported for raw IR + receivers. + + These eBPF programs can be used to decode IR into scancodes, for + IR protocols not supported by the kernel decoders. + menuconfig RC_DECODERS bool "Remote controller decoders" depends on RC_COREkernel/bpf/syscall.c +5
-0@@ -11,6 +11,7 @@*/ #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <linux/bpf_lirc.h> #include <linux/btf.h> #include <linux/syscalls.h> #include <linux/slab.h> @@ -1578,6 +1579,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , true); +case BPF_LIRC_MODE2 : +return lirc_prog_attach (attr);default :return -EINVAL ; }@@ -1648,6 +1651,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , false); +case BPF_LIRC_MODE2 : +return lirc_prog_detach (attr);default :return -EINVAL ; }
kernel/bpf/syscall.c static int bpf_prog_query(const union bpf_attr *attr, · line 1704
Quoted 5 lines
kernel/bpf/syscall.c +2
-0@@ -1695,6 +1700,8 @@ static int bpf_prog_query(const union bpf_attr *attr,case BPF_CGROUP_SOCK_OPS :case BPF_CGROUP_DEVICE :break ; +case BPF_LIRC_MODE2 : +return lirc_prog_query (attr, uattr);
When testing this patch series I was wondering why I always got -EINVAL when trying to query the registered programs.
Closer inspection revealed that bpf_prog_attach/detach/query and calls to them in the bpf syscall are in "#ifdef CONFIG_CGROUP_BPF" blocks - and as I built the kernel without CONFIG_CGROUP_BPF BPF_PROG_ATTACH/DETACH/QUERY weren't handled in the syscall switch and I got -EINVAL from the bpf syscall function.
I haven't checked in detail yet, but it looks to me like bpf_prog_attach/detach/query could always be built (or when either cgroup bpf or lirc bpf are enabled) and the #ifdefs moved inside the switch(). So lirc bpf could be used without cgroup bpf. Or am I missing something?
so long,
Hias
Quoted 6 lines
kernel/bpf/syscall.c +0
-0default :return -EINVAL ; }Signature · 1 line
2.17.0
Sean Young
maintainerRe: [PATCH v5 2/3] media: rc: introduce BPF_PROG_LIRC_MODE2
Quoted 22 lines · Matthias Reichl
Hi Sean,
I finally found the time to test your patch series and noticed 2 issues - comments are inline
drivers/media/rc/Kconfig config LIRC · line 31
Quoted 12 lines · Sean Young
drivers/media/rc/Kconfig +4
-0@@ -25,6 +25,19 @@ config LIRC passes raw IR to and from userspace, which is needed for IR transmitting (aka "blasting") and for the lirc daemon. +config BPF_LIRC_MODE2 + bool "Support for eBPF programs attached to lirc devices" + depends on BPF_SYSCALL + depends on RC_CORE=yRequiring rc-core to be built into the kernel could become problematic in the future for people using
media_build.
Quoted 8 lines
Currently the whole media tree (including rc-core) can be built as modules so DVB and IR drivers can be replaced by newer versions. But with rc-core in the kernel things could easily break if internal data structures are changed.
Maybe we should add a small layer with a stable API/ABI between bpf-lirc and rc-core to decouple them? Or would it be possible to build rc-core with bpf support as a module?
Unfortunately bpf cannot be built as a module.
Quoted 59 lines
Quoted 44 lines
drivers/media/rc/Kconfig +9
-0+ depends on LIRC + help + Allow attaching eBPF programs to a lirc device using the bpf(2) + syscall command BPF_PROG_ATTACH. This is supported for raw IR + receivers. + + These eBPF programs can be used to decode IR into scancodes, for + IR protocols not supported by the kernel decoders. + menuconfig RC_DECODERS bool "Remote controller decoders" depends on RC_COREkernel/bpf/syscall.c +5
-0@@ -11,6 +11,7 @@*/ #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <linux/bpf_lirc.h> #include <linux/btf.h> #include <linux/syscalls.h> #include <linux/slab.h> @@ -1578,6 +1579,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , true); +case BPF_LIRC_MODE2 : +return lirc_prog_attach (attr);default :return -EINVAL ; }@@ -1648,6 +1651,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)case BPF_SK_SKB_STREAM_PARSER :case BPF_SK_SKB_STREAM_VERDICT :return sockmap_get_from_fd (attr,BPF_PROG_TYPE_SK_SKB , false); +case BPF_LIRC_MODE2 : +return lirc_prog_detach (attr);default :return -EINVAL ; }kernel/bpf/syscall.c static int bpf_prog_query(const union bpf_attr *attr, · line 1704
Quoted 5 lines
kernel/bpf/syscall.c +2
-0@@ -1695,6 +1700,8 @@ static int bpf_prog_query(const union bpf_attr *attr,case BPF_CGROUP_SOCK_OPS :case BPF_CGROUP_DEVICE :break ; +case BPF_LIRC_MODE2 : +return lirc_prog_query (attr, uattr);When testing this patch series I was wondering why I always got
-EINVALwhen trying to query the registered programs.Closer inspection revealed that bpf_prog_attach/detach/query and calls to them in the bpf syscall are in "#ifdef
CONFIG_CGROUP_BPF" blocks - and as I built the kernel withoutCONFIG_CGROUP_BPFBPF_PROG_ATTACH/DETACH/QUERY weren't handled in the syscall switch and I got-EINVALfrom the bpf syscall function.
Quoted 5 lines
I haven't checked in detail yet, but it looks to me like bpf_prog_attach/detach/query could always be built (or when either cgroup bpf or lirc bpf are enabled) and the #ifdefs moved inside the
switch(). So lirc bpf could be used without cgroup bpf. Or am I missing something?
You are right, this features depends on CONFIG_CGROUP_BPF right now. This also affects the BPF_SK_MSG_VERDICT, BPF_SK_SKB_STREAM_VERDICT and BPF_SK_SKB_STREAM_PARSER type bpf attachments, and as far as I know these shouldn't depend on CONFIG_CGROUP_BPF either.
Sean
Daniel Borkmann
maintainerRe: [PATCH v5 2/3] media: rc: introduce BPF_PROG_LIRC_MODE2
Quoted 1 line · Sean Young
On Mon, Jun 04, 2018 at 07:47:30PM +0200, Matthias Reichl wrote:
[...]
Quoted 22 lines
Quoted 16 lines
kernel/bpf/syscall.c static int bpf_prog_query(const union bpf_attr *attr, · line 1704
Quoted 6 lines
kernel/bpf/syscall.c +2
-0@@ -1695,6 +1700,8 @@ static int bpf_prog_query(const union bpf_attr *attr,case BPF_CGROUP_SOCK_OPS :case BPF_CGROUP_DEVICE :break ; +case BPF_LIRC_MODE2 : +return lirc_prog_query (attr, uattr);When testing this patch series I was wondering why I always got
-EINVALwhen trying to query the registered programs.Closer inspection revealed that bpf_prog_attach/detach/query and calls to them in the bpf syscall are in "#ifdef
CONFIG_CGROUP_BPF" blocks - and as I built the kernel withoutCONFIG_CGROUP_BPFBPF_PROG_ATTACH/DETACH/QUERY weren't handled in the syscall switch and I got-EINVALfrom the bpf syscall function.Quoted 5 lines
I haven't checked in detail yet, but it looks to me like bpf_prog_attach/detach/query could always be built (or when either cgroup bpf or lirc bpf are enabled) and the #ifdefs moved inside the
switch(). So lirc bpf could be used without cgroup bpf. Or am I missing something?
Quoted 4 lines
You are right, this features depends on
CONFIG_CGROUP_BPFright now. This also affects theBPF_SK_MSG_VERDICT,BPF_SK_SKB_STREAM_VERDICTandBPF_SK_SKB_STREAM_PARSERtype bpf attachments, and as far as I know these shouldn't depend onCONFIG_CGROUP_BPFeither.
The latter three do depend on it from a bigger picture as sockmap progs are orchestrated via cgroups. But I'd be fine if you decouple lirc from it since there's really no dependency at all, and presumably there are valid cases where you would want to run it on low-end devices with minimal kernel.
Thanks,
Daniel
Sean Young
maintainerPATCH 1/1 bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_BPF_CGROUP
Compile bpf_prog_{attach,detach,query} even if CONFIG_BPF_CGROUP is not set.
--- include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-)
include/linux/bpf-cgroup.h +31 -0
@@ -188,12 +188,43 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach); +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int sockmap_get_from_fd (const union bpf_attr *attr, +int type,bool attach) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })
kernel/bpf/cgroup.c +110 -0
116 lines not on this page · raw message
kernel/bpf/syscall.c +4 -101
162 lines not on this page · raw message
Signature · 1 line
2.17.1
Re: [PATCH] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_BPF_CGROUP
Quoted 4 lines · Sean Young
Compile bpf_prog_{attach,detach,query} even if
CONFIG_BPF_CGROUPis not set.Signed-off-by Sean Young <[email protected]>
Hi Sean,
This patch seems to involve rather extensive refactoring, the details of which are not explained, in order to make a change whose motivation is also not explained. I for one would value a more extensive changelog if not a series of patches which implement discrete changes.
Thanks!
Re: [PATCH] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_BPF_CGROUP
In reply to Sean YoungQuoted 2 lines · Sean Young
Compile bpf_prog_{attach,detach,query} even if
CONFIG_BPF_CGROUPis not set.
It should be CONFIG_CGROUP_BPF here. The same for subject line. Today, if CONFIG_CGROUP_BPF is not defined. Users will get an -EINVAL if they try to attach/detach/query.
I am not sure what is the motivation behind this change. Could you explain more?
Quoted 354 lines
Signed-off-by Sean Young <[email protected]>--- include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-)include/linux/bpf-cgroup.h +31
-0@@ -188,12 +188,43 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach); +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int sockmap_get_from_fd (const union bpf_attr *attr, +int type,bool attach) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })kernel/bpf/cgroup.c +110
-0@@ -428,6 +428,116 @@ int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,return ret; } +int bpf_prog_attach_check_attach_type (const struct bpf_prog *prog, +enum bpf_attach_type attach_type) +{ +switch (prog->type) { +case BPF_PROG_TYPE_CGROUP_SOCK : +case BPF_PROG_TYPE_CGROUP_SOCK_ADDR : +return attach_type == prog->expected_attach_type ?0 : -EINVAL ; +default : +return 0 ; + } +} + +int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach) +{ +struct bpf_prog *prog =NULL ; +int ufd = attr->target_fd; +struct bpf_map *map; +struct fd f; +int err; + + f =fdget (ufd); + map =__bpf_map_get (f); +if (IS_ERR (map)) +return PTR_ERR (map); + +if (attach) { + prog =bpf_prog_get_type (attr->attach_bpf_fd, type); +if (IS_ERR (prog)) { +fdput (f); +return PTR_ERR (prog); + } + } + + err =sock_map_prog (map, prog, attr->attach_type); +if (err) { +fdput (f); +if (prog) +bpf_prog_put (prog); +return err; + } + +fdput (f); +return 0 ; +} + +int cgroup_bpf_prog_attach (const union bpf_attr *attr,enum bpf_prog_type ptype) +{ +struct bpf_prog *prog; +struct cgroup *cgrp; +int ret; + + prog =bpf_prog_get_type (attr->attach_bpf_fd, ptype); +if (IS_ERR (prog)) +return PTR_ERR (prog); + +if (bpf_prog_attach_check_attach_type (prog, attr->attach_type)) { +bpf_prog_put (prog); +return -EINVAL ; + } + + cgrp =cgroup_get_from_fd (attr->target_fd); +if (IS_ERR (cgrp)) { +bpf_prog_put (prog); +return PTR_ERR (cgrp); + } + + ret =cgroup_bpf_attach (cgrp, prog, attr->attach_type, + attr->attach_flags); +if (ret) +bpf_prog_put (prog); +cgroup_put (cgrp); + +return ret; +} + +int cgroup_bpf_prog_detach (const union bpf_attr *attr,enum bpf_prog_type ptype) +{ +struct bpf_prog *prog; +struct cgroup *cgrp; +int ret; + + cgrp =cgroup_get_from_fd (attr->target_fd); +if (IS_ERR (cgrp)) +return PTR_ERR (cgrp); + + prog =bpf_prog_get_type (attr->attach_bpf_fd, ptype); +if (IS_ERR (prog)) + prog =NULL ; + + ret =cgroup_bpf_detach (cgrp, prog, attr->attach_type,0 ); +if (prog) +bpf_prog_put (prog); +cgroup_put (cgrp); +return ret; +} + +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +struct cgroup *cgrp; +int ret; + + cgrp =cgroup_get_from_fd (attr->query.target_fd); +if (IS_ERR (cgrp)) +return PTR_ERR (cgrp); + ret =cgroup_bpf_query (cgrp, attr, uattr); +cgroup_put (cgrp); +return ret; +} +/** * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering * @sk: The socket sending or receiving traffic kernel/bpf/syscall.c +4
-102@@ -1489,65 +1489,14 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)return err; } -#ifdef CONFIG_CGROUP_BPF - -static int bpf_prog_attach_check_attach_type (const struct bpf_prog *prog, -enum bpf_attach_type attach_type) -{ -switch (prog->type) { -case BPF_PROG_TYPE_CGROUP_SOCK : -case BPF_PROG_TYPE_CGROUP_SOCK_ADDR : -return attach_type == prog->expected_attach_type ?0 : -EINVAL ; -default : -return 0 ; - } -} -#define BPF_PROG_ATTACH_LAST_FIELD attach_flags -static int sockmap_get_from_fd (const union bpf_attr *attr, -int type,bool attach) -{ -struct bpf_prog *prog =NULL ; -int ufd = attr->target_fd; -struct bpf_map *map; -struct fd f; -int err; - - f =fdget (ufd); - map =__bpf_map_get (f); -if (IS_ERR (map)) -return PTR_ERR (map); - -if (attach) { - prog =bpf_prog_get_type (attr->attach_bpf_fd, type); -if (IS_ERR (prog)) { -fdput (f); -return PTR_ERR (prog); - } - } - - err =sock_map_prog (map, prog, attr->attach_type); -if (err) { -fdput (f); -if (prog) -bpf_prog_put (prog); -return err; - } - -fdput (f); -return 0 ; -} -#define BPF_F_ATTACH_MASK \ (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)static int bpf_prog_attach (const union bpf_attr *attr) {enum bpf_prog_type ptype; -struct bpf_prog *prog; -struct cgroup *cgrp; -int ret;if (!capable (CAP_NET_ADMIN ))return -EPERM ;@@ -1593,28 +1542,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)return -EINVAL ; } - prog =bpf_prog_get_type (attr->attach_bpf_fd, ptype); -if (IS_ERR (prog)) -return PTR_ERR (prog); - -if (bpf_prog_attach_check_attach_type (prog, attr->attach_type)) { -bpf_prog_put (prog); -return -EINVAL ; - } - - cgrp =cgroup_get_from_fd (attr->target_fd); -if (IS_ERR (cgrp)) { -bpf_prog_put (prog); -return PTR_ERR (cgrp); - } - - ret =cgroup_bpf_attach (cgrp, prog, attr->attach_type, - attr->attach_flags); -if (ret) -bpf_prog_put (prog); -cgroup_put (cgrp); - -return ret; +return cgroup_bpf_prog_attach (attr, ptype); }#define BPF_PROG_DETACH_LAST_FIELD attach_type@@ -1622,9 +1550,6 @@ static int bpf_prog_attach(const union bpf_attr *attr)static int bpf_prog_detach (const union bpf_attr *attr) {enum bpf_prog_type ptype; -struct bpf_prog *prog; -struct cgroup *cgrp; -int ret;if (!capable (CAP_NET_ADMIN ))return -EPERM ;@@ -1667,19 +1592,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)return -EINVAL ; } - cgrp =cgroup_get_from_fd (attr->target_fd); -if (IS_ERR (cgrp)) -return PTR_ERR (cgrp); - - prog =bpf_prog_get_type (attr->attach_bpf_fd, ptype); -if (IS_ERR (prog)) - prog =NULL ; - - ret =cgroup_bpf_detach (cgrp, prog, attr->attach_type,0 ); -if (prog) -bpf_prog_put (prog); -cgroup_put (cgrp); -return ret; +return cgroup_bpf_prog_detach (attr, ptype); }#define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt@@ -1687,9 +1600,6 @@ static int bpf_prog_detach(const union bpf_attr *attr)static int bpf_prog_query (const union bpf_attr *attr,union bpf_attr __user *uattr) { -struct cgroup *cgrp; -int ret; -if (!capable (CAP_NET_ADMIN ))return -EPERM ;if (CHECK_ATTR (BPF_PROG_QUERY ))@@ -1717,14 +1627,9 @@ static int bpf_prog_query(const union bpf_attr *attr,default :return -EINVAL ; } - cgrp =cgroup_get_from_fd (attr->query.target_fd); -if (IS_ERR (cgrp)) -return PTR_ERR (cgrp); - ret =cgroup_bpf_query (cgrp, attr, uattr); -cgroup_put (cgrp); -return ret; + +return cgroup_bpf_prog_query (attr, uattr); } -#endif /* CONFIG_CGROUP_BPF */ #define BPF_PROG_TEST_RUN_LAST_FIELD test.duration@@ -2371,7 +2276,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, sizcase BPF_OBJ_GET : err =bpf_obj_get (&attr);break ; -#ifdef CONFIG_CGROUP_BPF case BPF_PROG_ATTACH : err =bpf_prog_attach (&attr);break ;@@ -2381,7 +2285,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, sizcase BPF_PROG_QUERY : err =bpf_prog_query (&attr, uattr);break ; -#endif case BPF_PROG_TEST_RUN : err =bpf_prog_test_run (&attr, uattr);break ; --2.17.1
Daniel Borkmann
maintainerRe: [PATCH] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_BPF_CGROUP
Quoted 9 lines · Y Song
Quoted 2 lines · Sean Young
Compile bpf_prog_{attach,detach,query} even if
CONFIG_BPF_CGROUPis not set.It should be
CONFIG_CGROUP_BPFhere. The same for subject line. Today, ifCONFIG_CGROUP_BPFis not defined. Users will get an-EINVALif they try to attach/detach/query.I am not sure what is the motivation behind this change. Could you explain more?
Motivation was that lirc2 progs are not related to cgroups at all and there are users that have compiled it out, yet it uses BPF_PROG_ATTACH/DETACH for managing them. This definitely needs to be more clearly explained in the changelog, agree.
Quoted 7 lines
Quoted 7 lines
Signed-off-by Sean Young <[email protected]>--- include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-)[...]
Sean Young
maintainerPATCH 1/1 bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
If the kernel is compiled with CONFIG_CGROUP_BPF not enabled, it is not possible to attach, detach or query IR BPF programs to /dev/lircN devices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups or CONFIG_CGROUP_BPF enabled.
This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef CONFIG_CGROUP_BPF in kernel/bpf/syscall.c, moving them to kernel/bpf/cgroup.c does not require #ifdefs since that file is already conditionally compiled.
--- include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-)
include/linux/bpf-cgroup.h +31 -0
@@ -188,12 +188,43 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach); +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int sockmap_get_from_fd (const union bpf_attr *attr, +int type,bool attach) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })
kernel/bpf/cgroup.c +110 -0
116 lines not on this page · raw message
kernel/bpf/syscall.c +4 -101
162 lines not on this page · raw message
Signature · 1 line
2.17.1
Daniel Borkmann
maintainerRe: [PATCH] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
Hi Sean,
Quoted 5 lines · Sean Young
If the kernel is compiled with
CONFIG_CGROUP_BPFnot enabled, it is not possible to attach, detach or query IR BPF programs to/dev/lircNdevices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups orCONFIG_CGROUP_BPFenabled.
Quoted 7 lines
This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef
CONFIG_CGROUP_BPFinkernel/bpf/syscall.c, moving them tokernel/bpf/cgroup.cdoes not require #ifdefs since that file is already conditionally compiled.Signed-off-by Sean Young <[email protected]>
Just two minor edits below from my side:
Quoted 62 lines
include/linux/bpf-cgroup.h | 31 +++++++++++ kernel/bpf/cgroup.c | 110 +++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 105 ++--------------------------------- 3 files changed, 145 insertions(+), 101 deletions(-)include/linux/bpf-cgroup.h +31
-0@@ -188,12 +188,43 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach); +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int sockmap_get_from_fd (const union bpf_attr *attr, +int type,bool attach) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })kernel/bpf/cgroup.c +1
-0@@ -428,6 +428,116 @@ int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,return ret; } +int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
kernel/bpf/cgroup.c int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, · line 441
Quoted 10 lines
kernel/bpf/cgroup.c +10
-0+ enum bpf_attach_type attach_type) +{ +switch (prog->type) { +case BPF_PROG_TYPE_CGROUP_SOCK : +case BPF_PROG_TYPE_CGROUP_SOCK_ADDR : +return attach_type == prog->expected_attach_type ?0 : -EINVAL ; +default : +return 0 ; + } +}
This one is rather BPF core, cgroup progs only happen to use it. Could you either move it as static inline into include/linux/bpf.h or leave it in kernel/bpf/syscall.c? In any case the #ifdef CONFIG_CGROUP_BPF wrapper could probably be dropped as well from it.
Quoted 22 lines
kernel/bpf/cgroup.c +22
-0+int sockmap_get_from_fd (const union bpf_attr *attr,int type,bool attach) +{ +struct bpf_prog *prog =NULL ; +int ufd = attr->target_fd; +struct bpf_map *map; +struct fd f; +int err; + + f =fdget (ufd); + map =__bpf_map_get (f); +if (IS_ERR (map)) +return PTR_ERR (map); + +if (attach) { + prog =bpf_prog_get_type (attr->attach_bpf_fd, type); +if (IS_ERR (prog)) { +fdput (f); +return PTR_ERR (prog); + } + } + + err =sock_map_prog (map, prog, attr->attach_type);
kernel/bpf/cgroup.c int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, · line 474
Quoted 10 lines
kernel/bpf/cgroup.c +10
-0+if (err) { +fdput (f); +if (prog) +bpf_prog_put (prog); +return err; + } + +fdput (f); +return 0 ; +}
And this one should rather end up in kernel/bpf/sockmap.c to have it with the rest of sockmap code. Moving into cgroup.c would rather be a in the wrong place given what the code does.
Thanks,
Daniel
Sean Young
maintainerPATCH v3 1/1 bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
If the kernel is compiled with CONFIG_CGROUP_BPF not enabled, it is not possible to attach, detach or query IR BPF programs to /dev/lircN devices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups or CONFIG_CGROUP_BPF enabled.
This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef CONFIG_CGROUP_BPF in kernel/bpf/syscall.c, moving them to kernel/bpf/cgroup.c and kernel/bpf/sockmap.c does not require #ifdefs since that is already conditionally compiled.
--- drivers/media/rc/bpf-lirc.c | 14 +----- include/linux/bpf-cgroup.h | 26 ++++++++++ include/linux/bpf.h | 8 +++ include/linux/bpf_lirc.h | 5 +- kernel/bpf/cgroup.c | 52 ++++++++++++++++++++ kernel/bpf/sockmap.c | 18 +++++++ kernel/bpf/syscall.c | 98 ++++++++----------------------------- 7 files changed, 130 insertions(+), 91 deletions(-)
drivers/media/rc/bpf-lirc.c +2 -12
@@ -207,29 +207,19 @@ void lirc_bpf_free(struct rc_dev *rcdev)bpf_prog_array_free (rcdev->raw->progs); } -int lirc_prog_attach (const union bpf_attr *attr) +int lirc_prog_attach (const union bpf_attr *attr,struct bpf_prog *prog) { -struct bpf_prog *prog;struct rc_dev *rcdev;int ret;if (attr->attach_flags)return -EINVAL ; - prog =bpf_prog_get_type (attr->attach_bpf_fd, -BPF_PROG_TYPE_LIRC_MODE2 ); -if (IS_ERR (prog)) -return PTR_ERR (prog); - rcdev =rc_dev_get_from_fd (attr->target_fd); -if (IS_ERR (rcdev)) { -bpf_prog_put (prog); +if (IS_ERR (rcdev))return PTR_ERR (rcdev); - } ret =lirc_bpf_attach (rcdev, prog); -if (ret) -bpf_prog_put (prog);put_device (&rcdev->dev);
include/linux/bpf-cgroup.h +26 -0
@@ -188,12 +188,38 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype,struct bpf_prog *prog); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else +struct bpf_prog ;struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype, +struct bpf_prog *prog) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })
include/linux/bpf.h +8 -0
@@ -684,6 +684,8 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)struct sock *__sock_map_lookup_elem (struct bpf_map *map,u32 key);struct sock *__sock_hash_lookup_elem (struct bpf_map *map,void *key);int sock_map_prog (struct bpf_map *map,struct bpf_prog *prog,u32 type); +int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog);#else static inline struct sock *__sock_map_lookup_elem (struct bpf_map *map,u32 key) {
@@ -702,6 +704,12 @@ static inline int sock_map_prog(struct bpf_map *map, {return -EOPNOTSUPP ; } + +int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog); +{ +return -EINVAL ; +}#endif #if defined(CONFIG_XDP_SOCKETS )
include/linux/bpf_lirc.h +3 -2
@@ -5,11 +5,12 @@#include <uapi/linux/bpf.h> #ifdef CONFIG_BPF_LIRC_MODE2 -int lirc_prog_attach (const union bpf_attr *attr); +int lirc_prog_attach (const union bpf_attr *attr,struct bpf_prog *prog);int lirc_prog_detach (const union bpf_attr *attr);int lirc_prog_query (const union bpf_attr *attr,union bpf_attr __user *uattr);#else -static inline int lirc_prog_attach (const union bpf_attr *attr) +static inline int lirc_prog_attach (const union bpf_attr *attr, +struct bpf_prog *prog) {return -EINVAL ; }
kernel/bpf/cgroup.c +52 -0
58 lines not on this page · raw message
kernel/bpf/sockmap.c +18 -0
@@ -1915,6 +1915,24 @@ int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)return 0 ; } +int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog) +{ +int ufd = attr->target_fd; +struct bpf_map *map; +struct fd f; +int err; + + f =fdget (ufd); + map =__bpf_map_get (f); +if (IS_ERR (map)) +return PTR_ERR (map); + + err =sock_map_prog (map, prog, attr->attach_type); +fdput (f); +return err; +} +static void *sock_map_lookup (struct bpf_map *map,void *key) {return NULL ;
kernel/bpf/syscall.c +21 -77
180 lines not on this page · raw message
Signature · 1 line
2.17.1
kbuild test robot
build botRe: [PATCH v3] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
I love your patch! Yet something to improve:
Hi Sean,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.18-rc1 next-20180618]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Sean-Young/bpf-attach-type-BPF_LIRC_MODE2-should-not-depend-on-CONFIG_CGROUP_BPF/20180619-023056
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce:
# save the attached .config to linux build tree
make ARCH=i386 All errors (new ones prefixed by >>):
In file included from kernel///events/core.c:45:0:
>> include/linux/bpf.h:710:1: error: expected identifier or '(' before '{' token
{
^vim +710 include/linux/bpf.h
707
708 int sockmap_get_from_fd(const union bpf_attr *attr, int type,
709 struct bpf_prog *prog);
> 710 { 711 return -EINVAL;
712 }
713 #endif
714
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Sean Young
maintainerRe: [PATCH v3] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
Quoted 15 lines · kbuild test robot
Hi Sean,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.18-rc1 next-20180618]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]url: https://github.com/0day-ci/linux/commits/Sean-Young/bpf-attach-type-BPF_LIRC_MODE2-should-not-depend-on-CONFIG_CGROUP_BPF/20180619-023056
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce:# save the attached .config to linux build tree make ARCH=i386
Quoted 6 lines
All errors (new ones prefixed by >>):
In file included from kernel///events/core.c:45:0:
Quoted 1 line
Quoted 1 line
include/linux/bpf.h:710:1: error: expected identifier or '(' before '{' token{ ^
Oh dear I never tested that with CONFIG_INET off (no ip? madness!). I'll send out a v4 soon.
Sean
Sean Young
maintainerPATCH v4 1/1 bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
In reply to kbuild test robotIf the kernel is compiled with CONFIG_CGROUP_BPF not enabled, it is not possible to attach, detach or query IR BPF programs to /dev/lircN devices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups or CONFIG_CGROUP_BPF enabled.
This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef CONFIG_CGROUP_BPF in kernel/bpf/syscall.c, moving them to kernel/bpf/cgroup.c and kernel/bpf/sockmap.c does not require #ifdefs since that is already conditionally compiled.
--- drivers/media/rc/bpf-lirc.c | 14 +----- include/linux/bpf-cgroup.h | 26 ++++++++++ include/linux/bpf.h | 8 +++ include/linux/bpf_lirc.h | 5 +- kernel/bpf/cgroup.c | 52 ++++++++++++++++++++ kernel/bpf/sockmap.c | 18 +++++++ kernel/bpf/syscall.c | 98 ++++++++----------------------------- 7 files changed, 130 insertions(+), 91 deletions(-)
drivers/media/rc/bpf-lirc.c +2 -12
@@ -207,29 +207,19 @@ void lirc_bpf_free(struct rc_dev *rcdev)bpf_prog_array_free (rcdev->raw->progs); } -int lirc_prog_attach (const union bpf_attr *attr) +int lirc_prog_attach (const union bpf_attr *attr,struct bpf_prog *prog) { -struct bpf_prog *prog;struct rc_dev *rcdev;int ret;if (attr->attach_flags)return -EINVAL ; - prog =bpf_prog_get_type (attr->attach_bpf_fd, -BPF_PROG_TYPE_LIRC_MODE2 ); -if (IS_ERR (prog)) -return PTR_ERR (prog); - rcdev =rc_dev_get_from_fd (attr->target_fd); -if (IS_ERR (rcdev)) { -bpf_prog_put (prog); +if (IS_ERR (rcdev))return PTR_ERR (rcdev); - } ret =lirc_bpf_attach (rcdev, prog); -if (ret) -bpf_prog_put (prog);put_device (&rcdev->dev);
include/linux/bpf-cgroup.h +26 -0
@@ -188,12 +188,38 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, \ __ret; \ }) +int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype,struct bpf_prog *prog); +int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype); +int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr);#else +struct bpf_prog ;struct cgroup_bpf {};static inline void cgroup_bpf_put (struct cgroup *cgrp) {}static inline int cgroup_bpf_inherit (struct cgroup *cgrp) {return 0 ; } +static inline int cgroup_bpf_prog_attach (const union bpf_attr *attr, +enum bpf_prog_type ptype, +struct bpf_prog *prog) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_detach (const union bpf_attr *attr, +enum bpf_prog_type ptype) +{ +return -EINVAL ; +} + +static inline int cgroup_bpf_prog_query (const union bpf_attr *attr, +union bpf_attr __user *uattr) +{ +return -EINVAL ; +} +#define cgroup_bpf_enabled (0)#define BPF_CGROUP_PRE_CONNECT_ENABLED (sk) (0)#define BPF_CGROUP_RUN_PROG_INET_INGRESS (sk,skb) ({ 0; })
include/linux/bpf.h +8 -0
@@ -684,6 +684,8 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)struct sock *__sock_map_lookup_elem (struct bpf_map *map,u32 key);struct sock *__sock_hash_lookup_elem (struct bpf_map *map,void *key);int sock_map_prog (struct bpf_map *map,struct bpf_prog *prog,u32 type); +int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog);#else static inline struct sock *__sock_map_lookup_elem (struct bpf_map *map,u32 key) {
@@ -702,6 +704,12 @@ static inline int sock_map_prog(struct bpf_map *map, {return -EOPNOTSUPP ; } + +static inline int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog) +{ +return -EINVAL ; +}#endif #if defined(CONFIG_XDP_SOCKETS )
include/linux/bpf_lirc.h +3 -2
@@ -5,11 +5,12 @@#include <uapi/linux/bpf.h> #ifdef CONFIG_BPF_LIRC_MODE2 -int lirc_prog_attach (const union bpf_attr *attr); +int lirc_prog_attach (const union bpf_attr *attr,struct bpf_prog *prog);int lirc_prog_detach (const union bpf_attr *attr);int lirc_prog_query (const union bpf_attr *attr,union bpf_attr __user *uattr);#else -static inline int lirc_prog_attach (const union bpf_attr *attr) +static inline int lirc_prog_attach (const union bpf_attr *attr, +struct bpf_prog *prog) {return -EINVAL ; }
kernel/bpf/cgroup.c +52 -0
58 lines not on this page · raw message
kernel/bpf/sockmap.c +18 -0
@@ -1915,6 +1915,24 @@ int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)return 0 ; } +int sockmap_get_from_fd (const union bpf_attr *attr,int type, +struct bpf_prog *prog) +{ +int ufd = attr->target_fd; +struct bpf_map *map; +struct fd f; +int err; + + f =fdget (ufd); + map =__bpf_map_get (f); +if (IS_ERR (map)) +return PTR_ERR (map); + + err =sock_map_prog (map, prog, attr->attach_type); +fdput (f); +return err; +} +static void *sock_map_lookup (struct bpf_map *map,void *key) {return NULL ;
kernel/bpf/syscall.c +21 -77
180 lines not on this page · raw message
Signature · 1 line
2.17.1
Re: [PATCH v4] bpf: attach type BPF_LIRC_MODE2 should not depend on CONFIG_CGROUP_BPF
Quoted 5 lines · Sean Young
If the kernel is compiled with
CONFIG_CGROUP_BPFnot enabled, it is not possible to attach, detach or query IR BPF programs to/dev/lircNdevices, making them impossible to use. For embedded devices, it should be possible to use IR decoding without cgroups orCONFIG_CGROUP_BPFenabled.
Quoted 7 lines
This change requires some refactoring, since bpf_prog_{attach,detach,query} functions are now always compiled, but their code paths for cgroups need moving out. Rather than a #ifdef
CONFIG_CGROUP_BPFinkernel/bpf/syscall.c, moving them tokernel/bpf/cgroup.candkernel/bpf/sockmap.cdoes not require #ifdefs since that is already conditionally compiled.Signed-off-by Sean Young <[email protected]>
Applied to bpf, thanks Sean!