Skip to content

Commit 05cef13

Browse files
committed
Merge tag 'slab-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab
Pull slab updates from Vlastimil Babka: - Sheaves performance improvements for systems with memoryless NUMA nodes, developed in response to regression reports. These mainly ensure that percpu sheaves exist and are used on cpus that belong to these memoryless nodes (Vlastimil Babka, Hao Li). - Cleanup API usage and constify sysfs attributes (Thomas Weißschuh) - Disable kfree_rcu() batching on builds intended for fuzzing/debugging that enable CONFIG_RCU_STRICT_GRACE_PERIOD (Jann Horn) - Add a kunit test for kmalloc_nolock()/kfree_nolock() (Harry Yoo) * tag 'slab-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab: slub: clarify kmem_cache_refill_sheaf() comments lib/tests/slub_kunit: add a test case for {kmalloc,kfree}_nolock MAINTAINERS: add lib/tests/slub_kunit.c to SLAB ALLOCATOR section slub: use N_NORMAL_MEMORY in can_free_to_pcs to handle remote frees slab,rcu: disable KVFREE_RCU_BATCHED for strict grace period slab: free remote objects to sheaves on memoryless nodes slab: create barns for online memoryless nodes slab: decouple pointer to barn from kmem_cache_node slab: remove alloc_full_sheaf() mm/slab: constify sysfs attributes mm/slab: create sysfs attribute through default_groups
2 parents a8e7ef3 + 44e0ebe commit 05cef13

5 files changed

Lines changed: 322 additions & 130 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24495,6 +24495,7 @@ F: Documentation/admin-guide/mm/slab.rst
2449524495
F: Documentation/mm/slab.rst
2449624496
F: include/linux/mempool.h
2449724497
F: include/linux/slab.h
24498+
F: lib/tests/slub_kunit.c
2449824499
F: mm/failslab.c
2449924500
F: mm/mempool.c
2450024501
F: mm/slab.h

lib/tests/slub_kunit.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/kernel.h>
88
#include <linux/rcupdate.h>
99
#include <linux/delay.h>
10+
#include <linux/perf_event.h>
1011
#include "../mm/slab.h"
1112

1213
static struct kunit_resource resource;
@@ -291,6 +292,94 @@ static void test_krealloc_redzone_zeroing(struct kunit *test)
291292
kmem_cache_destroy(s);
292293
}
293294

295+
#ifdef CONFIG_PERF_EVENTS
296+
#define NR_ITERATIONS 1000
297+
#define NR_OBJECTS 1000
298+
static void *objects[NR_OBJECTS];
299+
300+
struct test_nolock_context {
301+
struct kunit *test;
302+
int callback_count;
303+
int alloc_ok;
304+
int alloc_fail;
305+
struct perf_event *event;
306+
};
307+
308+
static struct perf_event_attr hw_attr = {
309+
.type = PERF_TYPE_HARDWARE,
310+
.config = PERF_COUNT_HW_CPU_CYCLES,
311+
.size = sizeof(struct perf_event_attr),
312+
.pinned = 1,
313+
.disabled = 1,
314+
.freq = 1,
315+
.sample_freq = 100000,
316+
};
317+
318+
static void overflow_handler_test_kmalloc_kfree_nolock(struct perf_event *event,
319+
struct perf_sample_data *data,
320+
struct pt_regs *regs)
321+
{
322+
void *objp;
323+
gfp_t gfp;
324+
struct test_nolock_context *ctx = event->overflow_handler_context;
325+
326+
/* __GFP_ACCOUNT to test kmalloc_nolock() in alloc_slab_obj_exts() */
327+
gfp = (ctx->callback_count % 2) ? 0 : __GFP_ACCOUNT;
328+
objp = kmalloc_nolock(64, gfp, NUMA_NO_NODE);
329+
330+
if (objp)
331+
ctx->alloc_ok++;
332+
else
333+
ctx->alloc_fail++;
334+
335+
kfree_nolock(objp);
336+
ctx->callback_count++;
337+
}
338+
339+
static void test_kmalloc_kfree_nolock(struct kunit *test)
340+
{
341+
int i, j;
342+
struct test_nolock_context ctx = { .test = test };
343+
struct perf_event *event;
344+
bool alloc_fail = false;
345+
346+
event = perf_event_create_kernel_counter(&hw_attr, -1, current,
347+
overflow_handler_test_kmalloc_kfree_nolock,
348+
&ctx);
349+
if (IS_ERR(event))
350+
kunit_skip(test, "Failed to create perf event");
351+
ctx.event = event;
352+
perf_event_enable(ctx.event);
353+
for (i = 0; i < NR_ITERATIONS; i++) {
354+
for (j = 0; j < NR_OBJECTS; j++) {
355+
gfp_t gfp = (i % 2) ? GFP_KERNEL : GFP_KERNEL_ACCOUNT;
356+
357+
objects[j] = kmalloc(64, gfp);
358+
if (!objects[j]) {
359+
j--;
360+
while (j >= 0)
361+
kfree(objects[j--]);
362+
alloc_fail = true;
363+
goto cleanup;
364+
}
365+
}
366+
for (j = 0; j < NR_OBJECTS; j++)
367+
kfree(objects[j]);
368+
}
369+
370+
cleanup:
371+
perf_event_disable(ctx.event);
372+
perf_event_release_kernel(ctx.event);
373+
374+
kunit_info(test, "callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
375+
ctx.callback_count, ctx.alloc_ok, ctx.alloc_fail);
376+
377+
if (alloc_fail)
378+
kunit_skip(test, "Allocation failed");
379+
KUNIT_EXPECT_EQ(test, 0, slab_errors);
380+
}
381+
#endif
382+
294383
static int test_init(struct kunit *test)
295384
{
296385
slab_errors = 0;
@@ -315,6 +404,9 @@ static struct kunit_case test_cases[] = {
315404
KUNIT_CASE(test_kfree_rcu_wq_destroy),
316405
KUNIT_CASE(test_leak_destroy),
317406
KUNIT_CASE(test_krealloc_redzone_zeroing),
407+
#ifdef CONFIG_PERF_EVENTS
408+
KUNIT_CASE_SLOW(test_kmalloc_kfree_nolock),
409+
#endif
318410
{}
319411
};
320412

mm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ config SLUB
172172
config KVFREE_RCU_BATCHED
173173
def_bool y
174174
depends on !SLUB_TINY && !TINY_RCU
175+
depends on !RCU_STRICT_GRACE_PERIOD
175176

176177
config SLUB_TINY
177178
bool "Configure for minimal memory footprint"

mm/slab.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ struct kmem_cache_order_objects {
191191
unsigned int x;
192192
};
193193

194+
struct kmem_cache_per_node_ptrs {
195+
struct node_barn *barn;
196+
struct kmem_cache_node *node;
197+
};
198+
194199
/*
195200
* Slab cache management.
196201
*/
@@ -247,7 +252,7 @@ struct kmem_cache {
247252
struct kmem_cache_stats __percpu *cpu_stats;
248253
#endif
249254

250-
struct kmem_cache_node *node[MAX_NUMNODES];
255+
struct kmem_cache_per_node_ptrs per_node[MAX_NUMNODES];
251256
};
252257

253258
/*

0 commit comments

Comments
 (0)