mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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
This commit is contained in:
commit
05cef13fa8
5 files changed
+323
-131
No files matched your search
@@ -24495,6 +24495,7 @@ F: Documentation/admin-guide/mm/slab.rst
|
||||
F: Documentation/mm/slab.rst
|
||||
F: include/linux/mempool.h
|
||||
F: include/linux/slab.h
|
||||
F: lib/tests/slub_kunit.c
|
||||
F: mm/failslab.c
|
||||
F: mm/mempool.c
|
||||
F: mm/slab.h
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include "../mm/slab.h"
|
||||
|
||||
static struct kunit_resource resource;
|
||||
@@ -291,6 +292,94 @@ static void test_krealloc_redzone_zeroing(struct kunit *test)
|
||||
kmem_cache_destroy(s);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
#define NR_ITERATIONS 1000
|
||||
#define NR_OBJECTS 1000
|
||||
static void *objects[NR_OBJECTS];
|
||||
|
||||
struct test_nolock_context {
|
||||
struct kunit *test;
|
||||
int callback_count;
|
||||
int alloc_ok;
|
||||
int alloc_fail;
|
||||
struct perf_event *event;
|
||||
};
|
||||
|
||||
static struct perf_event_attr hw_attr = {
|
||||
.type = PERF_TYPE_HARDWARE,
|
||||
.config = PERF_COUNT_HW_CPU_CYCLES,
|
||||
.size = sizeof(struct perf_event_attr),
|
||||
.pinned = 1,
|
||||
.disabled = 1,
|
||||
.freq = 1,
|
||||
.sample_freq = 100000,
|
||||
};
|
||||
|
||||
static void overflow_handler_test_kmalloc_kfree_nolock(struct perf_event *event,
|
||||
struct perf_sample_data *data,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
void *objp;
|
||||
gfp_t gfp;
|
||||
struct test_nolock_context *ctx = event->overflow_handler_context;
|
||||
|
||||
/* __GFP_ACCOUNT to test kmalloc_nolock() in alloc_slab_obj_exts() */
|
||||
gfp = (ctx->callback_count % 2) ? 0 : __GFP_ACCOUNT;
|
||||
objp = kmalloc_nolock(64, gfp, NUMA_NO_NODE);
|
||||
|
||||
if (objp)
|
||||
ctx->alloc_ok++;
|
||||
else
|
||||
ctx->alloc_fail++;
|
||||
|
||||
kfree_nolock(objp);
|
||||
ctx->callback_count++;
|
||||
}
|
||||
|
||||
static void test_kmalloc_kfree_nolock(struct kunit *test)
|
||||
{
|
||||
int i, j;
|
||||
struct test_nolock_context ctx = { .test = test };
|
||||
struct perf_event *event;
|
||||
bool alloc_fail = false;
|
||||
|
||||
event = perf_event_create_kernel_counter(&hw_attr, -1, current,
|
||||
overflow_handler_test_kmalloc_kfree_nolock,
|
||||
&ctx);
|
||||
if (IS_ERR(event))
|
||||
kunit_skip(test, "Failed to create perf event");
|
||||
ctx.event = event;
|
||||
perf_event_enable(ctx.event);
|
||||
for (i = 0; i < NR_ITERATIONS; i++) {
|
||||
for (j = 0; j < NR_OBJECTS; j++) {
|
||||
gfp_t gfp = (i % 2) ? GFP_KERNEL : GFP_KERNEL_ACCOUNT;
|
||||
|
||||
objects[j] = kmalloc(64, gfp);
|
||||
if (!objects[j]) {
|
||||
j--;
|
||||
while (j >= 0)
|
||||
kfree(objects[j--]);
|
||||
alloc_fail = true;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < NR_OBJECTS; j++)
|
||||
kfree(objects[j]);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
perf_event_disable(ctx.event);
|
||||
perf_event_release_kernel(ctx.event);
|
||||
|
||||
kunit_info(test, "callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
|
||||
ctx.callback_count, ctx.alloc_ok, ctx.alloc_fail);
|
||||
|
||||
if (alloc_fail)
|
||||
kunit_skip(test, "Allocation failed");
|
||||
KUNIT_EXPECT_EQ(test, 0, slab_errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_init(struct kunit *test)
|
||||
{
|
||||
slab_errors = 0;
|
||||
@@ -315,6 +404,9 @@ static struct kunit_case test_cases[] = {
|
||||
KUNIT_CASE(test_kfree_rcu_wq_destroy),
|
||||
KUNIT_CASE(test_leak_destroy),
|
||||
KUNIT_CASE(test_krealloc_redzone_zeroing),
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
KUNIT_CASE_SLOW(test_kmalloc_kfree_nolock),
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ config SLUB
|
||||
config KVFREE_RCU_BATCHED
|
||||
def_bool y
|
||||
depends on !SLUB_TINY && !TINY_RCU
|
||||
depends on !RCU_STRICT_GRACE_PERIOD
|
||||
|
||||
config SLUB_TINY
|
||||
bool "Configure for minimal memory footprint"
|
||||
|
||||
@@ -191,6 +191,11 @@ struct kmem_cache_order_objects {
|
||||
unsigned int x;
|
||||
};
|
||||
|
||||
struct kmem_cache_per_node_ptrs {
|
||||
struct node_barn *barn;
|
||||
struct kmem_cache_node *node;
|
||||
};
|
||||
|
||||
/*
|
||||
* Slab cache management.
|
||||
*/
|
||||
@@ -247,7 +252,7 @@ struct kmem_cache {
|
||||
struct kmem_cache_stats __percpu *cpu_stats;
|
||||
#endif
|
||||
|
||||
struct kmem_cache_node *node[MAX_NUMNODES];
|
||||
struct kmem_cache_per_node_ptrs per_node[MAX_NUMNODES];
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in new issue
Block a user