From f50966d9a76dee496b4f9f140caf557983f38031 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Tue, 3 Dec 2024 11:46:31 -0500 Subject: [PATCH] tools: Add sheafs support to testing infrastructure Allocate a sheaf and fill it to the count amount. Does not fill to the sheaf limit to detect incorrect allocation requests. Signed-off-by: Liam R. Howlett --- tools/include/linux/slab.h | 16 +++++++++++ tools/testing/shared/linux.c | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/tools/include/linux/slab.h b/tools/include/linux/slab.h index a475364cfd9f..46ae97e87517 100644 --- a/tools/include/linux/slab.h +++ b/tools/include/linux/slab.h @@ -22,6 +22,12 @@ enum slab_state { FULL }; +struct slab_sheaf { + struct kmem_cache *cache; + unsigned int size; + void *objects[]; +}; + struct kmem_cache_args { unsigned int align; unsigned int sheaf_capacity; @@ -79,4 +85,14 @@ void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list); int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size, void **list); +struct slab_sheaf * +kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int count); + +void * +kmem_cache_alloc_from_sheaf(struct kmem_cache *s, gfp_t gfp, + struct slab_sheaf *sheaf); + +void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp, + struct slab_sheaf *sheaf); + #endif /* _TOOLS_SLAB_H */ diff --git a/tools/testing/shared/linux.c b/tools/testing/shared/linux.c index b685c50d6c3a..c2bd723f878e 100644 --- a/tools/testing/shared/linux.c +++ b/tools/testing/shared/linux.c @@ -178,6 +178,12 @@ int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size, if (kmalloc_verbose) pr_debug("Bulk alloc %lu\n", size); + if (cachep->exec_callback) { + if (cachep->callback) + cachep->callback(cachep->private); + cachep->exec_callback = false; + } + pthread_mutex_lock(&cachep->lock); if (cachep->nr_objs >= size) { struct radix_tree_node *node; @@ -266,6 +272,55 @@ __kmem_cache_create_args(const char *name, unsigned int size, return ret; } +struct slab_sheaf * +kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int count) +{ + struct slab_sheaf *sheaf; + size_t size; + + if (count > s->sheaf_capacity) { + printf("No support for over-capacity sheaf %u > %u\n", count, + s->sheaf_capacity); + return NULL; + } + + size = sizeof(*sheaf) + sizeof(void *) * s->sheaf_capacity; + sheaf = malloc(size); + if (!sheaf) { + return NULL; + } + + memset(sheaf, 0, size); + sheaf->cache = s; + sheaf->size = kmem_cache_alloc_bulk(s, gfp, count, sheaf->objects); + if (!sheaf->size) { + free(sheaf); + return NULL; + } + + return sheaf; +} + +void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp, + struct slab_sheaf *sheaf) +{ + if (sheaf->size) + kmem_cache_free_bulk(s, sheaf->size, &sheaf->objects[0]); + free(sheaf); +} + +void * +kmem_cache_alloc_from_sheaf(struct kmem_cache *s, gfp_t gfp, + struct slab_sheaf *sheaf) +{ + if (sheaf->size == 0) { + printf("Nothing left in sheaf!\n"); + return NULL; + } + + return sheaf->objects[--sheaf->size]; +} + /* * Test the test infrastructure for kem_cache_alloc/free and bulk counterparts. */ -- 2.49.0