Skip to content

Commit 9299924

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-fix-warning-in-check_obj_size'
Hou Tao says: ==================== bpf: Fix warning in check_obj_size() From: Hou Tao <houtao1@huawei.com> Hi, The patch set aims to fix the warning in check_obj_size() as reported by lkp [1]. Patch #1 fixes the warning by selecting target cache for free request through c->unit_size, so the unnecessary adjustment of size_index and the checking in check_obj_size() can be removed. Patch #2 fixes the test failure in test_bpf_ma after applying patch #1. Please see individual patches for more details. And comments are always welcome. [1]: https://lore.kernel.org/bpf/202310302113.9f8fe705-oliver.sang@intel.com/ ==================== Link: https://lore.kernel.org/r/20231216131052.27621-1-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents 32f2493 + 69ff403 commit 9299924

File tree

2 files changed

+60
-145
lines changed

2 files changed

+60
-145
lines changed

kernel/bpf/memalloc.c

Lines changed: 11 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -490,27 +490,6 @@ static void prefill_mem_cache(struct bpf_mem_cache *c, int cpu)
490490
alloc_bulk(c, c->unit_size <= 256 ? 4 : 1, cpu_to_node(cpu), false);
491491
}
492492

493-
static int check_obj_size(struct bpf_mem_cache *c, unsigned int idx)
494-
{
495-
struct llist_node *first;
496-
unsigned int obj_size;
497-
498-
first = c->free_llist.first;
499-
if (!first)
500-
return 0;
501-
502-
if (c->percpu_size)
503-
obj_size = pcpu_alloc_size(((void **)first)[1]);
504-
else
505-
obj_size = ksize(first);
506-
if (obj_size != c->unit_size) {
507-
WARN_ONCE(1, "bpf_mem_cache[%u]: percpu %d, unexpected object size %u, expect %u\n",
508-
idx, c->percpu_size, obj_size, c->unit_size);
509-
return -EINVAL;
510-
}
511-
return 0;
512-
}
513-
514493
/* When size != 0 bpf_mem_cache for each cpu.
515494
* This is typical bpf hash map use case when all elements have equal size.
516495
*
@@ -521,10 +500,10 @@ static int check_obj_size(struct bpf_mem_cache *c, unsigned int idx)
521500
int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
522501
{
523502
static u16 sizes[NUM_CACHES] = {96, 192, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096};
524-
int cpu, i, err, unit_size, percpu_size = 0;
525503
struct bpf_mem_caches *cc, __percpu *pcc;
526504
struct bpf_mem_cache *c, __percpu *pc;
527505
struct obj_cgroup *objcg = NULL;
506+
int cpu, i, unit_size, percpu_size = 0;
528507

529508
/* room for llist_node and per-cpu pointer */
530509
if (percpu)
@@ -560,7 +539,6 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
560539
pcc = __alloc_percpu_gfp(sizeof(*cc), 8, GFP_KERNEL);
561540
if (!pcc)
562541
return -ENOMEM;
563-
err = 0;
564542
#ifdef CONFIG_MEMCG_KMEM
565543
objcg = get_obj_cgroup_from_current();
566544
#endif
@@ -574,28 +552,12 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
574552
c->tgt = c;
575553

576554
init_refill_work(c);
577-
/* Another bpf_mem_cache will be used when allocating
578-
* c->unit_size in bpf_mem_alloc(), so doesn't prefill
579-
* for the bpf_mem_cache because these free objects will
580-
* never be used.
581-
*/
582-
if (i != bpf_mem_cache_idx(c->unit_size))
583-
continue;
584555
prefill_mem_cache(c, cpu);
585-
err = check_obj_size(c, i);
586-
if (err)
587-
goto out;
588556
}
589557
}
590558

591-
out:
592559
ma->caches = pcc;
593-
/* refill_work is either zeroed or initialized, so it is safe to
594-
* call irq_work_sync().
595-
*/
596-
if (err)
597-
bpf_mem_alloc_destroy(ma);
598-
return err;
560+
return 0;
599561
}
600562

601563
static void drain_mem_cache(struct bpf_mem_cache *c)
@@ -869,7 +831,7 @@ void notrace *bpf_mem_alloc(struct bpf_mem_alloc *ma, size_t size)
869831
void *ret;
870832

871833
if (!size)
872-
return ZERO_SIZE_PTR;
834+
return NULL;
873835

874836
idx = bpf_mem_cache_idx(size + LLIST_NODE_SZ);
875837
if (idx < 0)
@@ -879,40 +841,33 @@ void notrace *bpf_mem_alloc(struct bpf_mem_alloc *ma, size_t size)
879841
return !ret ? NULL : ret + LLIST_NODE_SZ;
880842
}
881843

882-
static notrace int bpf_mem_free_idx(void *ptr, bool percpu)
883-
{
884-
size_t size;
885-
886-
if (percpu)
887-
size = pcpu_alloc_size(*((void **)ptr));
888-
else
889-
size = ksize(ptr - LLIST_NODE_SZ);
890-
return bpf_mem_cache_idx(size);
891-
}
892-
893844
void notrace bpf_mem_free(struct bpf_mem_alloc *ma, void *ptr)
894845
{
846+
struct bpf_mem_cache *c;
895847
int idx;
896848

897849
if (!ptr)
898850
return;
899851

900-
idx = bpf_mem_free_idx(ptr, ma->percpu);
901-
if (idx < 0)
852+
c = *(void **)(ptr - LLIST_NODE_SZ);
853+
idx = bpf_mem_cache_idx(c->unit_size);
854+
if (WARN_ON_ONCE(idx < 0))
902855
return;
903856

904857
unit_free(this_cpu_ptr(ma->caches)->cache + idx, ptr);
905858
}
906859

907860
void notrace bpf_mem_free_rcu(struct bpf_mem_alloc *ma, void *ptr)
908861
{
862+
struct bpf_mem_cache *c;
909863
int idx;
910864

911865
if (!ptr)
912866
return;
913867

914-
idx = bpf_mem_free_idx(ptr, ma->percpu);
915-
if (idx < 0)
868+
c = *(void **)(ptr - LLIST_NODE_SZ);
869+
idx = bpf_mem_cache_idx(c->unit_size);
870+
if (WARN_ON_ONCE(idx < 0))
916871
return;
917872

918873
unit_free_rcu(this_cpu_ptr(ma->caches)->cache + idx, ptr);
@@ -986,41 +941,3 @@ void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags)
986941

987942
return !ret ? NULL : ret + LLIST_NODE_SZ;
988943
}
989-
990-
/* The alignment of dynamic per-cpu area is 8, so c->unit_size and the
991-
* actual size of dynamic per-cpu area will always be matched and there is
992-
* no need to adjust size_index for per-cpu allocation. However for the
993-
* simplicity of the implementation, use an unified size_index for both
994-
* kmalloc and per-cpu allocation.
995-
*/
996-
static __init int bpf_mem_cache_adjust_size(void)
997-
{
998-
unsigned int size;
999-
1000-
/* Adjusting the indexes in size_index() according to the object_size
1001-
* of underlying slab cache, so bpf_mem_alloc() will select a
1002-
* bpf_mem_cache with unit_size equal to the object_size of
1003-
* the underlying slab cache.
1004-
*
1005-
* The maximal value of KMALLOC_MIN_SIZE and __kmalloc_minalign() is
1006-
* 256-bytes, so only do adjustment for [8-bytes, 192-bytes].
1007-
*/
1008-
for (size = 192; size >= 8; size -= 8) {
1009-
unsigned int kmalloc_size, index;
1010-
1011-
kmalloc_size = kmalloc_size_roundup(size);
1012-
if (kmalloc_size == size)
1013-
continue;
1014-
1015-
if (kmalloc_size <= 192)
1016-
index = size_index[(kmalloc_size - 1) / 8];
1017-
else
1018-
index = fls(kmalloc_size - 1) - 1;
1019-
/* Only overwrite if necessary */
1020-
if (size_index[(size - 1) / 8] != index)
1021-
size_index[(size - 1) / 8] = index;
1022-
}
1023-
1024-
return 0;
1025-
}
1026-
subsys_initcall(bpf_mem_cache_adjust_size);

tools/testing/selftests/bpf/progs/test_bpf_ma.c

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct generic_map_value {
1717

1818
char _license[] SEC("license") = "GPL";
1919

20-
const unsigned int data_sizes[] = {8, 16, 32, 64, 96, 128, 192, 256, 512, 1024, 2048, 4096};
20+
const unsigned int data_sizes[] = {16, 32, 64, 96, 128, 192, 256, 512, 1024, 2048, 4096};
2121
const volatile unsigned int data_btf_ids[ARRAY_SIZE(data_sizes)] = {};
2222

2323
int err = 0;
@@ -166,7 +166,7 @@ static __always_inline void batch_percpu_free(struct bpf_map *map, unsigned int
166166
batch_percpu_free((struct bpf_map *)(&array_percpu_##size), batch, idx); \
167167
} while (0)
168168

169-
DEFINE_ARRAY_WITH_KPTR(8);
169+
/* kptr doesn't support bin_data_8 which is a zero-sized array */
170170
DEFINE_ARRAY_WITH_KPTR(16);
171171
DEFINE_ARRAY_WITH_KPTR(32);
172172
DEFINE_ARRAY_WITH_KPTR(64);
@@ -198,21 +198,20 @@ int test_batch_alloc_free(void *ctx)
198198
if ((u32)bpf_get_current_pid_tgid() != pid)
199199
return 0;
200200

201-
/* Alloc 128 8-bytes objects in batch to trigger refilling,
202-
* then free 128 8-bytes objects in batch to trigger freeing.
201+
/* Alloc 128 16-bytes objects in batch to trigger refilling,
202+
* then free 128 16-bytes objects in batch to trigger freeing.
203203
*/
204-
CALL_BATCH_ALLOC_FREE(8, 128, 0);
205-
CALL_BATCH_ALLOC_FREE(16, 128, 1);
206-
CALL_BATCH_ALLOC_FREE(32, 128, 2);
207-
CALL_BATCH_ALLOC_FREE(64, 128, 3);
208-
CALL_BATCH_ALLOC_FREE(96, 128, 4);
209-
CALL_BATCH_ALLOC_FREE(128, 128, 5);
210-
CALL_BATCH_ALLOC_FREE(192, 128, 6);
211-
CALL_BATCH_ALLOC_FREE(256, 128, 7);
212-
CALL_BATCH_ALLOC_FREE(512, 64, 8);
213-
CALL_BATCH_ALLOC_FREE(1024, 32, 9);
214-
CALL_BATCH_ALLOC_FREE(2048, 16, 10);
215-
CALL_BATCH_ALLOC_FREE(4096, 8, 11);
204+
CALL_BATCH_ALLOC_FREE(16, 128, 0);
205+
CALL_BATCH_ALLOC_FREE(32, 128, 1);
206+
CALL_BATCH_ALLOC_FREE(64, 128, 2);
207+
CALL_BATCH_ALLOC_FREE(96, 128, 3);
208+
CALL_BATCH_ALLOC_FREE(128, 128, 4);
209+
CALL_BATCH_ALLOC_FREE(192, 128, 5);
210+
CALL_BATCH_ALLOC_FREE(256, 128, 6);
211+
CALL_BATCH_ALLOC_FREE(512, 64, 7);
212+
CALL_BATCH_ALLOC_FREE(1024, 32, 8);
213+
CALL_BATCH_ALLOC_FREE(2048, 16, 9);
214+
CALL_BATCH_ALLOC_FREE(4096, 8, 10);
216215

217216
return 0;
218217
}
@@ -223,21 +222,20 @@ int test_free_through_map_free(void *ctx)
223222
if ((u32)bpf_get_current_pid_tgid() != pid)
224223
return 0;
225224

226-
/* Alloc 128 8-bytes objects in batch to trigger refilling,
225+
/* Alloc 128 16-bytes objects in batch to trigger refilling,
227226
* then free these objects through map free.
228227
*/
229-
CALL_BATCH_ALLOC(8, 128, 0);
230-
CALL_BATCH_ALLOC(16, 128, 1);
231-
CALL_BATCH_ALLOC(32, 128, 2);
232-
CALL_BATCH_ALLOC(64, 128, 3);
233-
CALL_BATCH_ALLOC(96, 128, 4);
234-
CALL_BATCH_ALLOC(128, 128, 5);
235-
CALL_BATCH_ALLOC(192, 128, 6);
236-
CALL_BATCH_ALLOC(256, 128, 7);
237-
CALL_BATCH_ALLOC(512, 64, 8);
238-
CALL_BATCH_ALLOC(1024, 32, 9);
239-
CALL_BATCH_ALLOC(2048, 16, 10);
240-
CALL_BATCH_ALLOC(4096, 8, 11);
228+
CALL_BATCH_ALLOC(16, 128, 0);
229+
CALL_BATCH_ALLOC(32, 128, 1);
230+
CALL_BATCH_ALLOC(64, 128, 2);
231+
CALL_BATCH_ALLOC(96, 128, 3);
232+
CALL_BATCH_ALLOC(128, 128, 4);
233+
CALL_BATCH_ALLOC(192, 128, 5);
234+
CALL_BATCH_ALLOC(256, 128, 6);
235+
CALL_BATCH_ALLOC(512, 64, 7);
236+
CALL_BATCH_ALLOC(1024, 32, 8);
237+
CALL_BATCH_ALLOC(2048, 16, 9);
238+
CALL_BATCH_ALLOC(4096, 8, 10);
241239

242240
return 0;
243241
}
@@ -251,17 +249,17 @@ int test_batch_percpu_alloc_free(void *ctx)
251249
/* Alloc 128 16-bytes per-cpu objects in batch to trigger refilling,
252250
* then free 128 16-bytes per-cpu objects in batch to trigger freeing.
253251
*/
254-
CALL_BATCH_PERCPU_ALLOC_FREE(16, 128, 1);
255-
CALL_BATCH_PERCPU_ALLOC_FREE(32, 128, 2);
256-
CALL_BATCH_PERCPU_ALLOC_FREE(64, 128, 3);
257-
CALL_BATCH_PERCPU_ALLOC_FREE(96, 128, 4);
258-
CALL_BATCH_PERCPU_ALLOC_FREE(128, 128, 5);
259-
CALL_BATCH_PERCPU_ALLOC_FREE(192, 128, 6);
260-
CALL_BATCH_PERCPU_ALLOC_FREE(256, 128, 7);
261-
CALL_BATCH_PERCPU_ALLOC_FREE(512, 64, 8);
262-
CALL_BATCH_PERCPU_ALLOC_FREE(1024, 32, 9);
263-
CALL_BATCH_PERCPU_ALLOC_FREE(2048, 16, 10);
264-
CALL_BATCH_PERCPU_ALLOC_FREE(4096, 8, 11);
252+
CALL_BATCH_PERCPU_ALLOC_FREE(16, 128, 0);
253+
CALL_BATCH_PERCPU_ALLOC_FREE(32, 128, 1);
254+
CALL_BATCH_PERCPU_ALLOC_FREE(64, 128, 2);
255+
CALL_BATCH_PERCPU_ALLOC_FREE(96, 128, 3);
256+
CALL_BATCH_PERCPU_ALLOC_FREE(128, 128, 4);
257+
CALL_BATCH_PERCPU_ALLOC_FREE(192, 128, 5);
258+
CALL_BATCH_PERCPU_ALLOC_FREE(256, 128, 6);
259+
CALL_BATCH_PERCPU_ALLOC_FREE(512, 64, 7);
260+
CALL_BATCH_PERCPU_ALLOC_FREE(1024, 32, 8);
261+
CALL_BATCH_PERCPU_ALLOC_FREE(2048, 16, 9);
262+
CALL_BATCH_PERCPU_ALLOC_FREE(4096, 8, 10);
265263

266264
return 0;
267265
}
@@ -275,17 +273,17 @@ int test_percpu_free_through_map_free(void *ctx)
275273
/* Alloc 128 16-bytes per-cpu objects in batch to trigger refilling,
276274
* then free these object through map free.
277275
*/
278-
CALL_BATCH_PERCPU_ALLOC(16, 128, 1);
279-
CALL_BATCH_PERCPU_ALLOC(32, 128, 2);
280-
CALL_BATCH_PERCPU_ALLOC(64, 128, 3);
281-
CALL_BATCH_PERCPU_ALLOC(96, 128, 4);
282-
CALL_BATCH_PERCPU_ALLOC(128, 128, 5);
283-
CALL_BATCH_PERCPU_ALLOC(192, 128, 6);
284-
CALL_BATCH_PERCPU_ALLOC(256, 128, 7);
285-
CALL_BATCH_PERCPU_ALLOC(512, 64, 8);
286-
CALL_BATCH_PERCPU_ALLOC(1024, 32, 9);
287-
CALL_BATCH_PERCPU_ALLOC(2048, 16, 10);
288-
CALL_BATCH_PERCPU_ALLOC(4096, 8, 11);
276+
CALL_BATCH_PERCPU_ALLOC(16, 128, 0);
277+
CALL_BATCH_PERCPU_ALLOC(32, 128, 1);
278+
CALL_BATCH_PERCPU_ALLOC(64, 128, 2);
279+
CALL_BATCH_PERCPU_ALLOC(96, 128, 3);
280+
CALL_BATCH_PERCPU_ALLOC(128, 128, 4);
281+
CALL_BATCH_PERCPU_ALLOC(192, 128, 5);
282+
CALL_BATCH_PERCPU_ALLOC(256, 128, 6);
283+
CALL_BATCH_PERCPU_ALLOC(512, 64, 7);
284+
CALL_BATCH_PERCPU_ALLOC(1024, 32, 8);
285+
CALL_BATCH_PERCPU_ALLOC(2048, 16, 9);
286+
CALL_BATCH_PERCPU_ALLOC(4096, 8, 10);
289287

290288
return 0;
291289
}

0 commit comments

Comments
 (0)