Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fadad670 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bpf-extend-info'



Martin KaFai Lau says:

====================
bpf: Extend bpf_{prog,map}_info

This patch series adds more fields to bpf_prog_info and bpf_map_info.
Please see individual patch for details.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cf5d74b8 3a8ad560
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct bpf_map {
	struct work_struct work;
	atomic_t usercnt;
	struct bpf_map *inner_map_meta;
	u8 name[BPF_OBJ_NAME_LEN];
};

/* function argument constraints */
@@ -187,6 +188,8 @@ struct bpf_prog_aux {
	struct bpf_map **used_maps;
	struct bpf_prog *prog;
	struct user_struct *user;
	u64 load_time; /* ns since boottime */
	u8 name[BPF_OBJ_NAME_LEN];
	union {
		struct work_struct work;
		struct rcu_head	rcu;
+10 −0
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@ enum bpf_attach_type {
/* Specify numa node during map creation */
#define BPF_F_NUMA_NODE		(1U << 2)

#define BPF_OBJ_NAME_LEN 16U

union bpf_attr {
	struct { /* anonymous struct used by BPF_MAP_CREATE command */
		__u32	map_type;	/* one of enum bpf_map_type */
@@ -188,6 +190,7 @@ union bpf_attr {
		__u32	numa_node;	/* numa node (effective only if
					 * BPF_F_NUMA_NODE is set).
					 */
		__u8	map_name[BPF_OBJ_NAME_LEN];
	};

	struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
@@ -210,6 +213,7 @@ union bpf_attr {
		__aligned_u64	log_buf;	/* user supplied buffer */
		__u32		kern_version;	/* checked when prog_type=kprobe */
		__u32		prog_flags;
		__u8		prog_name[BPF_OBJ_NAME_LEN];
	};

	struct { /* anonymous struct used by BPF_OBJ_* commands */
@@ -812,6 +816,11 @@ struct bpf_prog_info {
	__u32 xlated_prog_len;
	__aligned_u64 jited_prog_insns;
	__aligned_u64 xlated_prog_insns;
	__u64 load_time;	/* ns since boottime */
	__u32 created_by_uid;
	__u32 nr_map_ids;
	__aligned_u64 map_ids;
	__u8  name[BPF_OBJ_NAME_LEN];
} __attribute__((aligned(8)));

struct bpf_map_info {
@@ -821,6 +830,7 @@ struct bpf_map_info {
	__u32 value_size;
	__u32 max_entries;
	__u32 map_flags;
	__u8  name[BPF_OBJ_NAME_LEN];
} __attribute__((aligned(8)));

/* User bpf_sock_ops struct to access socket values and specify request ops
+56 −2
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/idr.h>
#include <linux/cred.h>
#include <linux/timekeeping.h>
#include <linux/ctype.h>

#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
			   (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
@@ -312,7 +315,31 @@ int bpf_map_new_fd(struct bpf_map *map)
		   offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
		   sizeof(attr->CMD##_LAST_FIELD)) != NULL

#define BPF_MAP_CREATE_LAST_FIELD numa_node
/* dst and src must have at least BPF_OBJ_NAME_LEN number of bytes.
 * Return 0 on success and < 0 on error.
 */
static int bpf_obj_name_cpy(char *dst, const char *src)
{
	const char *end = src + BPF_OBJ_NAME_LEN;

	/* Copy all isalnum() and '_' char */
	while (src < end && *src) {
		if (!isalnum(*src) && *src != '_')
			return -EINVAL;
		*dst++ = *src++;
	}

	/* No '\0' found in BPF_OBJ_NAME_LEN number of bytes */
	if (src == end)
		return -EINVAL;

	/* '\0' terminates dst */
	*dst = 0;

	return 0;
}

#define BPF_MAP_CREATE_LAST_FIELD map_name
/* called via syscall */
static int map_create(union bpf_attr *attr)
{
@@ -334,6 +361,10 @@ static int map_create(union bpf_attr *attr)
	if (IS_ERR(map))
		return PTR_ERR(map);

	err = bpf_obj_name_cpy(map->name, attr->map_name);
	if (err)
		goto free_map_nouncharge;

	atomic_set(&map->refcnt, 1);
	atomic_set(&map->usercnt, 1);

@@ -973,7 +1004,7 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
EXPORT_SYMBOL_GPL(bpf_prog_get_type);

/* last field in 'union bpf_attr' used by this command */
#define	BPF_PROG_LOAD_LAST_FIELD prog_flags
#define	BPF_PROG_LOAD_LAST_FIELD prog_name

static int bpf_prog_load(union bpf_attr *attr)
{
@@ -1037,6 +1068,11 @@ static int bpf_prog_load(union bpf_attr *attr)
	if (err < 0)
		goto free_prog;

	prog->aux->load_time = ktime_get_boot_ns();
	err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name);
	if (err)
		goto free_prog;

	/* run eBPF verifier */
	err = bpf_check(&prog, attr);
	if (err < 0)
@@ -1358,8 +1394,25 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,

	info.type = prog->type;
	info.id = prog->aux->id;
	info.load_time = prog->aux->load_time;
	info.created_by_uid = from_kuid_munged(current_user_ns(),
					       prog->aux->user->uid);

	memcpy(info.tag, prog->tag, sizeof(prog->tag));
	memcpy(info.name, prog->aux->name, sizeof(prog->aux->name));

	ulen = info.nr_map_ids;
	info.nr_map_ids = prog->aux->used_map_cnt;
	ulen = min_t(u32, info.nr_map_ids, ulen);
	if (ulen) {
		u32 *user_map_ids = (u32 *)info.map_ids;
		u32 i;

		for (i = 0; i < ulen; i++)
			if (put_user(prog->aux->used_maps[i]->id,
				     &user_map_ids[i]))
				return -EFAULT;
	}

	if (!capable(CAP_SYS_ADMIN)) {
		info.jited_prog_len = 0;
@@ -1413,6 +1466,7 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
	info.value_size = map->value_size;
	info.max_entries = map->max_entries;
	info.map_flags = map->map_flags;
	memcpy(info.name, map->name, sizeof(map->name));

	if (copy_to_user(uinfo, &info, info_len) ||
	    put_user(info_len, &uattr->info.info_len))
+2 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ static int load_maps(struct bpf_map_data *maps, int nr_maps,
			int inner_map_fd = map_fd[maps[i].def.inner_map_idx];

			map_fd[i] = bpf_create_map_in_map_node(maps[i].def.type,
							maps[i].name,
							maps[i].def.key_size,
							inner_map_fd,
							maps[i].def.max_entries,
@@ -228,6 +229,7 @@ static int load_maps(struct bpf_map_data *maps, int nr_maps,
							numa_node);
		} else {
			map_fd[i] = bpf_create_map_node(maps[i].def.type,
							maps[i].name,
							maps[i].def.key_size,
							maps[i].def.value_size,
							maps[i].def.max_entries,
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ static void do_test_lru(enum test_type test, int cpu)

			inner_lru_map_fds[cpu] =
				bpf_create_map_node(BPF_MAP_TYPE_LRU_HASH,
						    test_map_names[INNER_LRU_HASH_PREALLOC],
						    sizeof(uint32_t),
						    sizeof(long),
						    inner_lru_hash_size, 0,
Loading