Skip to content

Commit

Permalink
Merge branch 'bpf-offload-report-dev'
Browse files Browse the repository at this point in the history
Jakub Kicinski says:

====================
This series is a redo of reporting offload device information to
user space after the first attempt did not take into account name
spaces.  As requested by Kirill offloads are now protected by an
r/w sem.  This allows us to remove the workqueue and free the
offload state fully when device is removed (suggested by Alexei).

Net namespace is reported with a device/inode pair.

The accompanying bpftool support is placed in common code because
maps will have very similar info.  Note that the UAPI information
can't be nicely encapsulated into a struct, because in case we
need to grow the device information the new fields will have to
be added at the end of struct bpf_prog_info, we can't grow
structures in the middle of bpf_prog_info.

v3:
 - use dev_get_by_index();
 - redo ns code (new patch 6).
v2:
 - rework the locking in patch 1 (use RCU instead of locking
   dependencies);
 - grab RTNL for a short time in patch 6;
 - minor update to the test in patch 8.
====================

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
  • Loading branch information
Daniel Borkmann committed Dec 31, 2017
2 parents fb98266 + 752d7b4 commit 5620e1a
Show file tree
Hide file tree
Showing 17 changed files with 346 additions and 89 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/bpf/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ struct nfp_bpf_vnic {

int nfp_bpf_jit(struct nfp_prog *prog);

extern const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops;
extern const struct bpf_prog_offload_ops nfp_bpf_analyzer_ops;

struct netdev_bpf;
struct nfp_app;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,6 @@ nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn_idx)
return 0;
}

const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops = {
const struct bpf_prog_offload_ops nfp_bpf_analyzer_ops = {
.insn_hook = nfp_verify_insn,
};
2 changes: 1 addition & 1 deletion drivers/net/netdevsim/bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ nsim_bpf_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn)
return 0;
}

static const struct bpf_ext_analyzer_ops nsim_bpf_analyzer_ops = {
static const struct bpf_prog_offload_ops nsim_bpf_analyzer_ops = {
.insn_hook = nsim_bpf_verify_insn,
};

Expand Down
29 changes: 26 additions & 3 deletions fs/nsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns)
goto got_it;
}

void *ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops)
void *ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
void *private_data)
{
struct ns_common *ns;
void *ret;

again:
ns = ns_ops->get(task);
ns = ns_get_cb(private_data);
if (!ns)
return ERR_PTR(-ENOENT);

Expand All @@ -120,6 +120,29 @@ void *ns_get_path(struct path *path, struct task_struct *task,
return ret;
}

struct ns_get_path_task_args {
const struct proc_ns_operations *ns_ops;
struct task_struct *task;
};

static struct ns_common *ns_get_path_task(void *private_data)
{
struct ns_get_path_task_args *args = private_data;

return args->ns_ops->get(args->task);
}

void *ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops)
{
struct ns_get_path_task_args args = {
.ns_ops = ns_ops,
.task = task,
};

return ns_get_path_cb(path, ns_get_path_task, &args);
}

int open_related_ns(struct ns_common *ns,
struct ns_common *(*get_ns)(struct ns_common *ns))
{
Expand Down
16 changes: 13 additions & 3 deletions include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -201,6 +206,7 @@ struct bpf_prog_aux {
u32 stack_depth;
u32 id;
u32 func_cnt;
bool offload_requested;
struct bpf_prog **func;
void *jit_data; /* JIT specific data. arch dependent */
struct latch_tree_node ksym_tnode;
Expand Down Expand Up @@ -351,6 +357,8 @@ void bpf_prog_put(struct bpf_prog *prog);
int __bpf_prog_charge(struct user_struct *user, u32 pages);
void __bpf_prog_uncharge(struct user_struct *user, u32 pages);

void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock);

struct bpf_map *bpf_map_get_with_uref(u32 ufd);
struct bpf_map *__bpf_map_get(struct fd f);
struct bpf_map * __must_check bpf_map_inc(struct bpf_map *map, bool uref);
Expand Down Expand Up @@ -523,13 +531,15 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd,

int bpf_prog_offload_compile(struct bpf_prog *prog);
void bpf_prog_offload_destroy(struct bpf_prog *prog);
int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
struct bpf_prog *prog);

#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr);

static inline bool bpf_prog_is_dev_bound(struct bpf_prog_aux *aux)
{
return aux->offload;
return aux->offload_requested;
}
#else
static inline int bpf_prog_offload_init(struct bpf_prog *prog,
Expand Down
16 changes: 2 additions & 14 deletions include/linux/bpf_verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand All @@ -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 */
4 changes: 2 additions & 2 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions include/linux/proc_ns.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ extern struct file *proc_ns_fget(int fd);
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
extern void *ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
typedef struct ns_common *ns_get_path_helper_t(void *);
extern void *ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_cb,
void *private_data);

extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
Expand Down
3 changes: 3 additions & 0 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,9 @@ struct bpf_prog_info {
__u32 nr_map_ids;
__aligned_u64 map_ids;
char name[BPF_OBJ_NAME_LEN];
__u32 ifindex;
__u64 netns_dev;
__u64 netns_ino;
} __attribute__((aligned(8)));

struct bpf_map_info {
Expand Down
Loading

0 comments on commit 5620e1a

Please sign in to comment.