Skip to content

Commit 5a06861

Browse files
davemarchevskyKernel Patches Daemon
authored andcommitted
selftests/bpf: Add local_storage exclusive cache test
Validate local_storage exclusive caching functionality: * Adding >BPF_LOCAL_STORAGE_CACHE_SIZE task_storage maps w/ BPF_LOCAL_STORAGE_FORCE_CACHE results in failure to load program as there are free slots to claim. * Adding BPF_LOCAL_STORAGE_CACHE_SIZE task_storage maps w/ FORCE_CACHE succeeds and results in a filled idx_bitmap for the cache. After first bpf_task_storage_get call for each map, the map's local storage data is in the cache slot. Subsequent bpf_task_storage_get calls to non-exclusive-cached maps don't replace exclusive-cached maps. Signed-off-by: Dave Marchevsky <[email protected]>
1 parent d2678fd commit 5a06861

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3+
4+
#include <linux/bitmap.h>
5+
#include <test_progs.h>
6+
7+
#include "local_storage_excl_cache.skel.h"
8+
#include "local_storage_excl_cache_fail.skel.h"
9+
10+
void test_test_local_storage_excl_cache(void)
11+
{
12+
u64 cache_idx_exclusive, cache_idx_exclusive_expected;
13+
struct local_storage_excl_cache_fail *skel_fail = NULL;
14+
struct local_storage_excl_cache *skel = NULL;
15+
u16 cache_size, i;
16+
int err;
17+
18+
skel_fail = local_storage_excl_cache_fail__open_and_load();
19+
ASSERT_ERR_PTR(skel_fail, "excl_cache_fail load should fail");
20+
local_storage_excl_cache_fail__destroy(skel_fail);
21+
22+
skel = local_storage_excl_cache__open_and_load();
23+
if (!ASSERT_OK_PTR(skel, "excl_cache load should succeed"))
24+
goto cleanup;
25+
26+
cache_size = skel->data->__BPF_LOCAL_STORAGE_CACHE_SIZE;
27+
28+
err = local_storage_excl_cache__attach(skel);
29+
if (!ASSERT_OK(err, "excl_cache__attach"))
30+
goto cleanup;
31+
32+
/* trigger tracepoint */
33+
usleep(1);
34+
cache_idx_exclusive = skel->data->out__cache_bitmap;
35+
cache_idx_exclusive_expected = 0;
36+
for (i = 0; i < cache_size; i++)
37+
cache_idx_exclusive_expected |= (1U << i);
38+
39+
if (!ASSERT_EQ(cache_idx_exclusive & cache_idx_exclusive_expected,
40+
cache_idx_exclusive_expected, "excl cache bitmap should be full"))
41+
goto cleanup;
42+
43+
usleep(1);
44+
for (i = 0; i < cache_size; i++)
45+
if (!ASSERT_EQ(skel->data->out__cache_smaps[i],
46+
skel->data->out__declared_smaps[i],
47+
"cached map not equal"))
48+
goto cleanup;
49+
50+
cleanup:
51+
local_storage_excl_cache__destroy(skel);
52+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3+
4+
#include "vmlinux.h"
5+
#include <bpf/bpf_helpers.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
#define make_task_local_excl_map(name, num) \
10+
struct { \
11+
__uint(type, BPF_MAP_TYPE_TASK_STORAGE); \
12+
__uint(map_flags, BPF_F_NO_PREALLOC); \
13+
__type(key, int); \
14+
__type(value, __u32); \
15+
__uint(map_extra, BPF_LOCAL_STORAGE_FORCE_CACHE); \
16+
} name ## num SEC(".maps");
17+
18+
#define make_task_local_map(name, num) \
19+
struct { \
20+
__uint(type, BPF_MAP_TYPE_TASK_STORAGE); \
21+
__uint(map_flags, BPF_F_NO_PREALLOC); \
22+
__type(key, int); \
23+
__type(value, __u32); \
24+
} name ## num SEC(".maps");
25+
26+
#define task_storage_get_excl(map, num) \
27+
({ \
28+
bpf_task_storage_get(&map ## num, task, 0, BPF_LOCAL_STORAGE_GET_F_CREATE); \
29+
bpf_probe_read_kernel(&out__cache_smaps[num], \
30+
sizeof(void *), \
31+
&task->bpf_storage->cache[num]->smap); \
32+
out__declared_smaps[num] = &map ## num; \
33+
})
34+
35+
/* must match define in bpf_local_storage.h */
36+
#define BPF_LOCAL_STORAGE_CACHE_SIZE 16
37+
38+
/* Try adding BPF_LOCAL_STORAGE_CACHE_SIZE task_storage maps w/ exclusive
39+
* cache slot
40+
*/
41+
make_task_local_excl_map(task_storage_map, 0);
42+
make_task_local_excl_map(task_storage_map, 1);
43+
make_task_local_excl_map(task_storage_map, 2);
44+
make_task_local_excl_map(task_storage_map, 3);
45+
make_task_local_excl_map(task_storage_map, 4);
46+
make_task_local_excl_map(task_storage_map, 5);
47+
make_task_local_excl_map(task_storage_map, 6);
48+
make_task_local_excl_map(task_storage_map, 7);
49+
make_task_local_excl_map(task_storage_map, 8);
50+
make_task_local_excl_map(task_storage_map, 9);
51+
make_task_local_excl_map(task_storage_map, 10);
52+
make_task_local_excl_map(task_storage_map, 11);
53+
make_task_local_excl_map(task_storage_map, 12);
54+
make_task_local_excl_map(task_storage_map, 13);
55+
make_task_local_excl_map(task_storage_map, 14);
56+
make_task_local_excl_map(task_storage_map, 15);
57+
58+
make_task_local_map(task_storage_map, 16);
59+
60+
extern const void task_cache __ksym;
61+
__u64 __BPF_LOCAL_STORAGE_CACHE_SIZE = BPF_LOCAL_STORAGE_CACHE_SIZE;
62+
__u64 out__cache_bitmap = -1;
63+
void *out__cache_smaps[BPF_LOCAL_STORAGE_CACHE_SIZE] = { (void *)-1 };
64+
void *out__declared_smaps[BPF_LOCAL_STORAGE_CACHE_SIZE] = { (void *)-1 };
65+
66+
SEC("raw_tp/sys_enter")
67+
int handler(const void *ctx)
68+
{
69+
struct task_struct *task = bpf_get_current_task_btf();
70+
__u32 *ptr;
71+
72+
bpf_probe_read_kernel(&out__cache_bitmap, sizeof(out__cache_bitmap),
73+
&task_cache +
74+
offsetof(struct bpf_local_storage_cache, idx_exclusive));
75+
76+
/* Get all BPF_LOCAL_STORAGE_CACHE_SIZE exclusive-cache maps into cache,
77+
* and one that shouldn't be cached
78+
*/
79+
task_storage_get_excl(task_storage_map, 0);
80+
task_storage_get_excl(task_storage_map, 1);
81+
task_storage_get_excl(task_storage_map, 2);
82+
task_storage_get_excl(task_storage_map, 3);
83+
task_storage_get_excl(task_storage_map, 4);
84+
task_storage_get_excl(task_storage_map, 5);
85+
task_storage_get_excl(task_storage_map, 6);
86+
task_storage_get_excl(task_storage_map, 7);
87+
task_storage_get_excl(task_storage_map, 8);
88+
task_storage_get_excl(task_storage_map, 9);
89+
task_storage_get_excl(task_storage_map, 10);
90+
task_storage_get_excl(task_storage_map, 11);
91+
task_storage_get_excl(task_storage_map, 12);
92+
task_storage_get_excl(task_storage_map, 13);
93+
task_storage_get_excl(task_storage_map, 14);
94+
task_storage_get_excl(task_storage_map, 15);
95+
96+
bpf_task_storage_get(&task_storage_map16, task, 0,
97+
BPF_LOCAL_STORAGE_GET_F_CREATE);
98+
99+
return 0;
100+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3+
4+
#include "vmlinux.h"
5+
#include <bpf/bpf_helpers.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
#define make_task_local_excl_map(name, num) \
10+
struct { \
11+
__uint(type, BPF_MAP_TYPE_TASK_STORAGE); \
12+
__uint(map_flags, BPF_F_NO_PREALLOC); \
13+
__type(key, int); \
14+
__type(value, __u32); \
15+
__uint(map_extra, BPF_LOCAL_STORAGE_FORCE_CACHE); \
16+
} name ## num SEC(".maps");
17+
18+
/* Try adding BPF_LOCAL_STORAGE_CACHE_SIZE+1 task_storage maps w/ exclusive
19+
* cache slot */
20+
make_task_local_excl_map(task_storage_map, 0);
21+
make_task_local_excl_map(task_storage_map, 1);
22+
make_task_local_excl_map(task_storage_map, 2);
23+
make_task_local_excl_map(task_storage_map, 3);
24+
make_task_local_excl_map(task_storage_map, 4);
25+
make_task_local_excl_map(task_storage_map, 5);
26+
make_task_local_excl_map(task_storage_map, 6);
27+
make_task_local_excl_map(task_storage_map, 7);
28+
make_task_local_excl_map(task_storage_map, 8);
29+
make_task_local_excl_map(task_storage_map, 9);
30+
make_task_local_excl_map(task_storage_map, 10);
31+
make_task_local_excl_map(task_storage_map, 11);
32+
make_task_local_excl_map(task_storage_map, 12);
33+
make_task_local_excl_map(task_storage_map, 13);
34+
make_task_local_excl_map(task_storage_map, 14);
35+
make_task_local_excl_map(task_storage_map, 15);
36+
make_task_local_excl_map(task_storage_map, 16);

0 commit comments

Comments
 (0)