Commit 2beee5f5 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Alexei Starovoitov

bpf: Move owner type, jited info into array auxiliary data

We're going to extend this with further information which is only
relevant for prog array at this point. Given this info is not used
in critical path, move it into its own structure such that the main
array map structure can be kept on diet.
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/b9ddccdb0f6f7026489ee955f16c96381e1e7238.1574452833.git.daniel@iogearbox.net
parent 6332be04
...@@ -560,17 +560,21 @@ struct bpf_prog_aux { ...@@ -560,17 +560,21 @@ struct bpf_prog_aux {
}; };
}; };
struct bpf_array_aux {
/* 'Ownership' of prog array is claimed by the first program that
* is going to use this map or by the first program which FD is
* stored in the map to make sure that all callers and callees have
* the same prog type and JITed flag.
*/
enum bpf_prog_type type;
bool jited;
};
struct bpf_array { struct bpf_array {
struct bpf_map map; struct bpf_map map;
u32 elem_size; u32 elem_size;
u32 index_mask; u32 index_mask;
/* 'ownership' of prog_array is claimed by the first program that struct bpf_array_aux *aux;
* is going to use this map or by the first program which FD is stored
* in the map to make sure that all callers and callees have the same
* prog_type and JITed flag
*/
enum bpf_prog_type owner_prog_type;
bool owner_jited;
union { union {
char value[0] __aligned(8); char value[0] __aligned(8);
void *ptrs[0] __aligned(8); void *ptrs[0] __aligned(8);
......
...@@ -671,10 +671,38 @@ static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key, ...@@ -671,10 +671,38 @@ static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key,
rcu_read_unlock(); rcu_read_unlock();
} }
static struct bpf_map *prog_array_map_alloc(union bpf_attr *attr)
{
struct bpf_array_aux *aux;
struct bpf_map *map;
aux = kzalloc(sizeof(*aux), GFP_KERNEL);
if (!aux)
return ERR_PTR(-ENOMEM);
map = array_map_alloc(attr);
if (IS_ERR(map)) {
kfree(aux);
return map;
}
container_of(map, struct bpf_array, map)->aux = aux;
return map;
}
static void prog_array_map_free(struct bpf_map *map)
{
struct bpf_array_aux *aux;
aux = container_of(map, struct bpf_array, map)->aux;
kfree(aux);
fd_array_map_free(map);
}
const struct bpf_map_ops prog_array_map_ops = { const struct bpf_map_ops prog_array_map_ops = {
.map_alloc_check = fd_array_map_alloc_check, .map_alloc_check = fd_array_map_alloc_check,
.map_alloc = array_map_alloc, .map_alloc = prog_array_map_alloc,
.map_free = fd_array_map_free, .map_free = prog_array_map_free,
.map_get_next_key = array_map_get_next_key, .map_get_next_key = array_map_get_next_key,
.map_lookup_elem = fd_array_map_lookup_elem, .map_lookup_elem = fd_array_map_lookup_elem,
.map_delete_elem = fd_array_map_delete_elem, .map_delete_elem = fd_array_map_delete_elem,
......
...@@ -1691,18 +1691,17 @@ bool bpf_prog_array_compatible(struct bpf_array *array, ...@@ -1691,18 +1691,17 @@ bool bpf_prog_array_compatible(struct bpf_array *array,
if (fp->kprobe_override) if (fp->kprobe_override)
return false; return false;
if (!array->owner_prog_type) { if (!array->aux->type) {
/* There's no owner yet where we could check for /* There's no owner yet where we could check for
* compatibility. * compatibility.
*/ */
array->owner_prog_type = fp->type; array->aux->type = fp->type;
array->owner_jited = fp->jited; array->aux->jited = fp->jited;
return true; return true;
} }
return array->owner_prog_type == fp->type && return array->aux->type == fp->type &&
array->owner_jited == fp->jited; array->aux->jited == fp->jited;
} }
static int bpf_check_tail_call(const struct bpf_prog *fp) static int bpf_check_tail_call(const struct bpf_prog *fp)
......
...@@ -17,9 +17,8 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) ...@@ -17,9 +17,8 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
if (IS_ERR(inner_map)) if (IS_ERR(inner_map))
return inner_map; return inner_map;
/* prog_array->owner_prog_type and owner_jited /* prog_array->aux->{type,jited} is a runtime binding.
* is a runtime binding. Doing static check alone * Doing static check alone in the verifier is not enough.
* in the verifier is not enough.
*/ */
if (inner_map->map_type == BPF_MAP_TYPE_PROG_ARRAY || if (inner_map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
inner_map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE || inner_map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE ||
......
...@@ -389,13 +389,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp) ...@@ -389,13 +389,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
{ {
const struct bpf_map *map = filp->private_data; const struct bpf_map *map = filp->private_data;
const struct bpf_array *array; const struct bpf_array *array;
u32 owner_prog_type = 0; u32 type = 0, jited = 0;
u32 owner_jited = 0;
if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) { if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) {
array = container_of(map, struct bpf_array, map); array = container_of(map, struct bpf_array, map);
owner_prog_type = array->owner_prog_type; type = array->aux->type;
owner_jited = array->owner_jited; jited = array->aux->jited;
} }
seq_printf(m, seq_printf(m,
...@@ -415,12 +414,9 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp) ...@@ -415,12 +414,9 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
map->memory.pages * 1ULL << PAGE_SHIFT, map->memory.pages * 1ULL << PAGE_SHIFT,
map->id, map->id,
READ_ONCE(map->frozen)); READ_ONCE(map->frozen));
if (type) {
if (owner_prog_type) { seq_printf(m, "owner_prog_type:\t%u\n", type);
seq_printf(m, "owner_prog_type:\t%u\n", seq_printf(m, "owner_jited:\t%u\n", jited);
owner_prog_type);
seq_printf(m, "owner_jited:\t%u\n",
owner_jited);
} }
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment