Commit 66981003 authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch '"map_extra" and bloom filter fixups'

Joanne Koong says:

====================

There are 3 patches in this patchset:

1/3 - Bloom filter naming fixups (kernel/bpf/bloom_filter.c)

2/3 - Add alignment padding for map_extra, rearrange fields in
bpf_map struct to consolidate holes

3/3 - Bloom filter tests (prog_tests/bloom_filter_map):
Add test for successful userspace calls, some refactoring to
use bpf_create_map instead of bpf_create_map_xattr

v1 -> v2:
    * In prog_tests/bloom_filter_map: remove unneeded line break,
	also change the inner_map_test to use bpf_create_map instead
	of bpf_create_map_xattr.
    * Add acked-bys to commit messages
====================
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents f27a6fad 7a670872
...@@ -168,23 +168,23 @@ struct bpf_map { ...@@ -168,23 +168,23 @@ struct bpf_map {
u32 key_size; u32 key_size;
u32 value_size; u32 value_size;
u32 max_entries; u32 max_entries;
u32 map_flags;
u64 map_extra; /* any per-map-type extra fields */ u64 map_extra; /* any per-map-type extra fields */
u32 map_flags;
int spin_lock_off; /* >=0 valid offset, <0 error */ int spin_lock_off; /* >=0 valid offset, <0 error */
int timer_off; /* >=0 valid offset, <0 error */ int timer_off; /* >=0 valid offset, <0 error */
u32 id; u32 id;
int numa_node; int numa_node;
u32 btf_key_type_id; u32 btf_key_type_id;
u32 btf_value_type_id; u32 btf_value_type_id;
u32 btf_vmlinux_value_type_id;
struct btf *btf; struct btf *btf;
#ifdef CONFIG_MEMCG_KMEM #ifdef CONFIG_MEMCG_KMEM
struct mem_cgroup *memcg; struct mem_cgroup *memcg;
#endif #endif
char name[BPF_OBJ_NAME_LEN]; char name[BPF_OBJ_NAME_LEN];
u32 btf_vmlinux_value_type_id;
bool bypass_spec_v1; bool bypass_spec_v1;
bool frozen; /* write-once; write-protected by freeze_mutex */ bool frozen; /* write-once; write-protected by freeze_mutex */
/* 22 bytes hole */ /* 14 bytes hole */
/* The 3rd and 4th cacheline with misc members to avoid false sharing /* The 3rd and 4th cacheline with misc members to avoid false sharing
* particularly with refcounting. * particularly with refcounting.
......
...@@ -5662,6 +5662,7 @@ struct bpf_map_info { ...@@ -5662,6 +5662,7 @@ struct bpf_map_info {
__u32 btf_id; __u32 btf_id;
__u32 btf_key_type_id; __u32 btf_key_type_id;
__u32 btf_value_type_id; __u32 btf_value_type_id;
__u32 :32; /* alignment pad */
__u64 map_extra; __u64 map_extra;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
......
...@@ -40,7 +40,7 @@ static u32 hash(struct bpf_bloom_filter *bloom, void *value, ...@@ -40,7 +40,7 @@ static u32 hash(struct bpf_bloom_filter *bloom, void *value,
return h & bloom->bitset_mask; return h & bloom->bitset_mask;
} }
static int peek_elem(struct bpf_map *map, void *value) static int bloom_map_peek_elem(struct bpf_map *map, void *value)
{ {
struct bpf_bloom_filter *bloom = struct bpf_bloom_filter *bloom =
container_of(map, struct bpf_bloom_filter, map); container_of(map, struct bpf_bloom_filter, map);
...@@ -55,7 +55,7 @@ static int peek_elem(struct bpf_map *map, void *value) ...@@ -55,7 +55,7 @@ static int peek_elem(struct bpf_map *map, void *value)
return 0; return 0;
} }
static int push_elem(struct bpf_map *map, void *value, u64 flags) static int bloom_map_push_elem(struct bpf_map *map, void *value, u64 flags)
{ {
struct bpf_bloom_filter *bloom = struct bpf_bloom_filter *bloom =
container_of(map, struct bpf_bloom_filter, map); container_of(map, struct bpf_bloom_filter, map);
...@@ -72,12 +72,12 @@ static int push_elem(struct bpf_map *map, void *value, u64 flags) ...@@ -72,12 +72,12 @@ static int push_elem(struct bpf_map *map, void *value, u64 flags)
return 0; return 0;
} }
static int pop_elem(struct bpf_map *map, void *value) static int bloom_map_pop_elem(struct bpf_map *map, void *value)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static struct bpf_map *map_alloc(union bpf_attr *attr) static struct bpf_map *bloom_map_alloc(union bpf_attr *attr)
{ {
u32 bitset_bytes, bitset_mask, nr_hash_funcs, nr_bits; u32 bitset_bytes, bitset_mask, nr_hash_funcs, nr_bits;
int numa_node = bpf_map_attr_numa_node(attr); int numa_node = bpf_map_attr_numa_node(attr);
...@@ -90,11 +90,13 @@ static struct bpf_map *map_alloc(union bpf_attr *attr) ...@@ -90,11 +90,13 @@ static struct bpf_map *map_alloc(union bpf_attr *attr)
attr->max_entries == 0 || attr->max_entries == 0 ||
attr->map_flags & ~BLOOM_CREATE_FLAG_MASK || attr->map_flags & ~BLOOM_CREATE_FLAG_MASK ||
!bpf_map_flags_access_ok(attr->map_flags) || !bpf_map_flags_access_ok(attr->map_flags) ||
/* The lower 4 bits of map_extra (0xF) specify the number
* of hash functions
*/
(attr->map_extra & ~0xF)) (attr->map_extra & ~0xF))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/* The lower 4 bits of map_extra specify the number of hash functions */ nr_hash_funcs = attr->map_extra;
nr_hash_funcs = attr->map_extra & 0xF;
if (nr_hash_funcs == 0) if (nr_hash_funcs == 0)
/* Default to using 5 hash functions if unspecified */ /* Default to using 5 hash functions if unspecified */
nr_hash_funcs = 5; nr_hash_funcs = 5;
...@@ -150,7 +152,7 @@ static struct bpf_map *map_alloc(union bpf_attr *attr) ...@@ -150,7 +152,7 @@ static struct bpf_map *map_alloc(union bpf_attr *attr)
return &bloom->map; return &bloom->map;
} }
static void map_free(struct bpf_map *map) static void bloom_map_free(struct bpf_map *map)
{ {
struct bpf_bloom_filter *bloom = struct bpf_bloom_filter *bloom =
container_of(map, struct bpf_bloom_filter, map); container_of(map, struct bpf_bloom_filter, map);
...@@ -158,38 +160,39 @@ static void map_free(struct bpf_map *map) ...@@ -158,38 +160,39 @@ static void map_free(struct bpf_map *map)
bpf_map_area_free(bloom); bpf_map_area_free(bloom);
} }
static void *lookup_elem(struct bpf_map *map, void *key) static void *bloom_map_lookup_elem(struct bpf_map *map, void *key)
{ {
/* The eBPF program should use map_peek_elem instead */ /* The eBPF program should use map_peek_elem instead */
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
static int update_elem(struct bpf_map *map, void *key, static int bloom_map_update_elem(struct bpf_map *map, void *key,
void *value, u64 flags) void *value, u64 flags)
{ {
/* The eBPF program should use map_push_elem instead */ /* The eBPF program should use map_push_elem instead */
return -EINVAL; return -EINVAL;
} }
static int check_btf(const struct bpf_map *map, const struct btf *btf, static int bloom_map_check_btf(const struct bpf_map *map,
const struct btf_type *key_type, const struct btf *btf,
const struct btf_type *value_type) const struct btf_type *key_type,
const struct btf_type *value_type)
{ {
/* Bloom filter maps are keyless */ /* Bloom filter maps are keyless */
return btf_type_is_void(key_type) ? 0 : -EINVAL; return btf_type_is_void(key_type) ? 0 : -EINVAL;
} }
static int bpf_bloom_btf_id; static int bpf_bloom_map_btf_id;
const struct bpf_map_ops bloom_filter_map_ops = { const struct bpf_map_ops bloom_filter_map_ops = {
.map_meta_equal = bpf_map_meta_equal, .map_meta_equal = bpf_map_meta_equal,
.map_alloc = map_alloc, .map_alloc = bloom_map_alloc,
.map_free = map_free, .map_free = bloom_map_free,
.map_push_elem = push_elem, .map_push_elem = bloom_map_push_elem,
.map_peek_elem = peek_elem, .map_peek_elem = bloom_map_peek_elem,
.map_pop_elem = pop_elem, .map_pop_elem = bloom_map_pop_elem,
.map_lookup_elem = lookup_elem, .map_lookup_elem = bloom_map_lookup_elem,
.map_update_elem = update_elem, .map_update_elem = bloom_map_update_elem,
.map_check_btf = check_btf, .map_check_btf = bloom_map_check_btf,
.map_btf_name = "bpf_bloom_filter", .map_btf_name = "bpf_bloom_filter",
.map_btf_id = &bpf_bloom_btf_id, .map_btf_id = &bpf_bloom_map_btf_id,
}; };
...@@ -5662,6 +5662,7 @@ struct bpf_map_info { ...@@ -5662,6 +5662,7 @@ struct bpf_map_info {
__u32 btf_id; __u32 btf_id;
__u32 btf_key_type_id; __u32 btf_key_type_id;
__u32 btf_value_type_id; __u32 btf_value_type_id;
__u32 :32; /* alignment pad */
__u64 map_extra; __u64 map_extra;
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
......
...@@ -7,44 +7,31 @@ ...@@ -7,44 +7,31 @@
static void test_fail_cases(void) static void test_fail_cases(void)
{ {
struct bpf_create_map_attr xattr = {
.name = "bloom_filter_map",
.map_type = BPF_MAP_TYPE_BLOOM_FILTER,
.max_entries = 100,
.value_size = 11,
};
__u32 value; __u32 value;
int fd, err; int fd, err;
/* Invalid key size */ /* Invalid key size */
xattr.key_size = 4; fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 4, sizeof(value), 100, 0);
fd = bpf_create_map_xattr(&xattr);
if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid key size")) if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid key size"))
close(fd); close(fd);
xattr.key_size = 0;
/* Invalid value size */ /* Invalid value size */
xattr.value_size = 0; fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, 0, 100, 0);
fd = bpf_create_map_xattr(&xattr);
if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid value size 0")) if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid value size 0"))
close(fd); close(fd);
xattr.value_size = 11;
/* Invalid max entries size */ /* Invalid max entries size */
xattr.max_entries = 0; fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 0, 0);
fd = bpf_create_map_xattr(&xattr);
if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid max entries size")) if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid max entries size"))
close(fd); close(fd);
xattr.max_entries = 100;
/* Bloom filter maps do not support BPF_F_NO_PREALLOC */ /* Bloom filter maps do not support BPF_F_NO_PREALLOC */
xattr.map_flags = BPF_F_NO_PREALLOC; fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100,
fd = bpf_create_map_xattr(&xattr); BPF_F_NO_PREALLOC);
if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid flags")) if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid flags"))
close(fd); close(fd);
xattr.map_flags = 0;
fd = bpf_create_map_xattr(&xattr); fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100, 0);
if (!ASSERT_GE(fd, 0, "bpf_create_map bloom filter")) if (!ASSERT_GE(fd, 0, "bpf_create_map bloom filter"))
return; return;
...@@ -67,6 +54,30 @@ static void test_fail_cases(void) ...@@ -67,6 +54,30 @@ static void test_fail_cases(void)
close(fd); close(fd);
} }
static void test_success_cases(void)
{
char value[11];
int fd, err;
/* Create a map */
fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100,
BPF_F_ZERO_SEED | BPF_F_NUMA_NODE);
if (!ASSERT_GE(fd, 0, "bpf_create_map bloom filter success case"))
return;
/* Add a value to the bloom filter */
err = bpf_map_update_elem(fd, NULL, &value, 0);
if (!ASSERT_OK(err, "bpf_map_update_elem bloom filter success case"))
goto done;
/* Lookup a value in the bloom filter */
err = bpf_map_lookup_elem(fd, NULL, &value);
ASSERT_OK(err, "bpf_map_update_elem bloom filter success case");
done:
close(fd);
}
static void check_bloom(struct bloom_filter_map *skel) static void check_bloom(struct bloom_filter_map *skel)
{ {
struct bpf_link *link; struct bpf_link *link;
...@@ -86,16 +97,11 @@ static void test_inner_map(struct bloom_filter_map *skel, const __u32 *rand_vals ...@@ -86,16 +97,11 @@ static void test_inner_map(struct bloom_filter_map *skel, const __u32 *rand_vals
__u32 nr_rand_vals) __u32 nr_rand_vals)
{ {
int outer_map_fd, inner_map_fd, err, i, key = 0; int outer_map_fd, inner_map_fd, err, i, key = 0;
struct bpf_create_map_attr xattr = {
.name = "bloom_filter_inner_map",
.map_type = BPF_MAP_TYPE_BLOOM_FILTER,
.value_size = sizeof(__u32),
.max_entries = nr_rand_vals,
};
struct bpf_link *link; struct bpf_link *link;
/* Create a bloom filter map that will be used as the inner map */ /* Create a bloom filter map that will be used as the inner map */
inner_map_fd = bpf_create_map_xattr(&xattr); inner_map_fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(*rand_vals),
nr_rand_vals, 0);
if (!ASSERT_GE(inner_map_fd, 0, "bpf_create_map bloom filter inner map")) if (!ASSERT_GE(inner_map_fd, 0, "bpf_create_map bloom filter inner map"))
return; return;
...@@ -190,6 +196,7 @@ void test_bloom_filter_map(void) ...@@ -190,6 +196,7 @@ void test_bloom_filter_map(void)
int err; int err;
test_fail_cases(); test_fail_cases();
test_success_cases();
err = setup_progs(&skel, &rand_vals, &nr_rand_vals); err = setup_progs(&skel, &rand_vals, &nr_rand_vals);
if (err) if (err)
......
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