diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2019-01-31 18:40:05 -0500 |
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-02-01 14:55:38 -0500 |
| commit | e16d2f1ab96849b4b65e64b82550a7ecdbf405eb (patch) | |
| tree | c5bb1bfee577712f7a0c1312716b2fb573560c74 /kernel | |
| parent | d83525ca62cf8ebe3271d14c36fb900c294274a2 (diff) | |
bpf: add support for bpf_spin_lock to cgroup local storage
Allow 'struct bpf_spin_lock' to reside inside cgroup local storage.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/local_storage.c | 2 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 3 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 2 |
3 files changed, 6 insertions, 1 deletions
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c index 07a34ef562a0..0295427f06e2 100644 --- a/kernel/bpf/local_storage.c +++ b/kernel/bpf/local_storage.c | |||
| @@ -147,6 +147,7 @@ static int cgroup_storage_update_elem(struct bpf_map *map, void *_key, | |||
| 147 | return -ENOMEM; | 147 | return -ENOMEM; |
| 148 | 148 | ||
| 149 | memcpy(&new->data[0], value, map->value_size); | 149 | memcpy(&new->data[0], value, map->value_size); |
| 150 | check_and_init_map_lock(map, new->data); | ||
| 150 | 151 | ||
| 151 | new = xchg(&storage->buf, new); | 152 | new = xchg(&storage->buf, new); |
| 152 | kfree_rcu(new, rcu); | 153 | kfree_rcu(new, rcu); |
| @@ -483,6 +484,7 @@ struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog, | |||
| 483 | storage->buf = kmalloc_node(size, flags, map->numa_node); | 484 | storage->buf = kmalloc_node(size, flags, map->numa_node); |
| 484 | if (!storage->buf) | 485 | if (!storage->buf) |
| 485 | goto enomem; | 486 | goto enomem; |
| 487 | check_and_init_map_lock(map, storage->buf->data); | ||
| 486 | } else { | 488 | } else { |
| 487 | storage->percpu_buf = __alloc_percpu_gfp(size, 8, flags); | 489 | storage->percpu_buf = __alloc_percpu_gfp(size, 8, flags); |
| 488 | if (!storage->percpu_buf) | 490 | if (!storage->percpu_buf) |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index ebf0a673cb83..b29e6dc44650 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -482,7 +482,8 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf, | |||
| 482 | 482 | ||
| 483 | if (map_value_has_spin_lock(map)) { | 483 | if (map_value_has_spin_lock(map)) { |
| 484 | if (map->map_type != BPF_MAP_TYPE_HASH && | 484 | if (map->map_type != BPF_MAP_TYPE_HASH && |
| 485 | map->map_type != BPF_MAP_TYPE_ARRAY) | 485 | map->map_type != BPF_MAP_TYPE_ARRAY && |
| 486 | map->map_type != BPF_MAP_TYPE_CGROUP_STORAGE) | ||
| 486 | return -ENOTSUPP; | 487 | return -ENOTSUPP; |
| 487 | if (map->spin_lock_off + sizeof(struct bpf_spin_lock) > | 488 | if (map->spin_lock_off + sizeof(struct bpf_spin_lock) > |
| 488 | map->value_size) { | 489 | map->value_size) { |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 38892bdee651..b63bc77af2d1 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -3089,6 +3089,8 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn | |||
| 3089 | regs[BPF_REG_0].map_ptr = meta.map_ptr; | 3089 | regs[BPF_REG_0].map_ptr = meta.map_ptr; |
| 3090 | if (fn->ret_type == RET_PTR_TO_MAP_VALUE) { | 3090 | if (fn->ret_type == RET_PTR_TO_MAP_VALUE) { |
| 3091 | regs[BPF_REG_0].type = PTR_TO_MAP_VALUE; | 3091 | regs[BPF_REG_0].type = PTR_TO_MAP_VALUE; |
| 3092 | if (map_value_has_spin_lock(meta.map_ptr)) | ||
| 3093 | regs[BPF_REG_0].id = ++env->id_gen; | ||
| 3092 | } else { | 3094 | } else { |
| 3093 | regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; | 3095 | regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; |
| 3094 | regs[BPF_REG_0].id = ++env->id_gen; | 3096 | regs[BPF_REG_0].id = ++env->id_gen; |
