bpf: offload: allow netdev to disappear while verifier is running
To allow verifier instruction callbacks without any extra locking NETDEV_UNREGISTER notification would wait on a waitqueue for verifier to finish. This design decision was made when rtnl lock was providing all the locking. Use the read/write lock instead and remove the workqueue. Verifier will now call into the offload code, so dev_ops are moved to offload structure. Since verifier calls are all under bpf_prog_is_dev_bound() we no longer need static inline implementations to please builds with CONFIG_NET=n. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:

committed by
Daniel Borkmann

parent
9a18eedb14
commit
cae1927c0b
@@ -17,6 +17,7 @@
|
||||
#include <linux/numa.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
struct bpf_verifier_env;
|
||||
struct perf_event;
|
||||
struct bpf_prog;
|
||||
struct bpf_map;
|
||||
@@ -184,14 +185,18 @@ struct bpf_verifier_ops {
|
||||
struct bpf_prog *prog, u32 *target_size);
|
||||
};
|
||||
|
||||
struct bpf_prog_offload_ops {
|
||||
int (*insn_hook)(struct bpf_verifier_env *env,
|
||||
int insn_idx, int prev_insn_idx);
|
||||
};
|
||||
|
||||
struct bpf_dev_offload {
|
||||
struct bpf_prog *prog;
|
||||
struct net_device *netdev;
|
||||
void *dev_priv;
|
||||
struct list_head offloads;
|
||||
bool dev_state;
|
||||
bool verifier_running;
|
||||
wait_queue_head_t verifier_done;
|
||||
const struct bpf_prog_offload_ops *dev_ops;
|
||||
};
|
||||
|
||||
struct bpf_prog_aux {
|
||||
|
@@ -166,12 +166,6 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifer_log *log)
|
||||
return log->len_used >= log->len_total - 1;
|
||||
}
|
||||
|
||||
struct bpf_verifier_env;
|
||||
struct bpf_ext_analyzer_ops {
|
||||
int (*insn_hook)(struct bpf_verifier_env *env,
|
||||
int insn_idx, int prev_insn_idx);
|
||||
};
|
||||
|
||||
#define BPF_MAX_SUBPROGS 256
|
||||
|
||||
/* single container for all structs
|
||||
@@ -185,7 +179,6 @@ struct bpf_verifier_env {
|
||||
bool strict_alignment; /* perform strict pointer alignment checks */
|
||||
struct bpf_verifier_state *cur_state; /* current verifier state */
|
||||
struct bpf_verifier_state_list **explored_states; /* search pruning optimization */
|
||||
const struct bpf_ext_analyzer_ops *dev_ops; /* device analyzer ops */
|
||||
struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by eBPF program */
|
||||
u32 used_map_cnt; /* number of used maps */
|
||||
u32 id_gen; /* used to generate unique reg IDs */
|
||||
@@ -206,13 +199,8 @@ static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env)
|
||||
return cur->frame[cur->curframe]->regs;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
|
||||
int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env);
|
||||
#else
|
||||
static inline int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env,
|
||||
int insn_idx, int prev_insn_idx);
|
||||
|
||||
#endif /* _LINUX_BPF_VERIFIER_H */
|
||||
|
@@ -804,7 +804,7 @@ enum bpf_netdev_command {
|
||||
BPF_OFFLOAD_DESTROY,
|
||||
};
|
||||
|
||||
struct bpf_ext_analyzer_ops;
|
||||
struct bpf_prog_offload_ops;
|
||||
struct netlink_ext_ack;
|
||||
|
||||
struct netdev_bpf {
|
||||
@@ -826,7 +826,7 @@ struct netdev_bpf {
|
||||
/* BPF_OFFLOAD_VERIFIER_PREP */
|
||||
struct {
|
||||
struct bpf_prog *prog;
|
||||
const struct bpf_ext_analyzer_ops *ops; /* callee set */
|
||||
const struct bpf_prog_offload_ops *ops; /* callee set */
|
||||
} verifier;
|
||||
/* BPF_OFFLOAD_TRANSLATE, BPF_OFFLOAD_DESTROY */
|
||||
struct {
|
||||
|
Reference in New Issue
Block a user