]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tools: Add sheafs support to testing infrastructure
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Tue, 3 Dec 2024 16:46:31 +0000 (11:46 -0500)
committerVlastimil Babka <vbabka@suse.cz>
Mon, 20 Jan 2025 15:25:08 +0000 (16:25 +0100)
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 <Liam.Howlett@Oracle.com>
tools/include/linux/slab.h
tools/testing/shared/linux.c

index a475364cfd9fcdb10db252aab18ea3a620326b6b..f466a4135c5c4294b45d2c3334401b8789ec91db 100644 (file)
@@ -22,6 +22,13 @@ enum slab_state {
        FULL
 };
 
+struct slab_sheaf {
+       struct kmem_cache *cache;
+       unsigned int size;
+       bool oversized;
+       void *objects[];
+};
+
 struct kmem_cache_args {
        unsigned int align;
        unsigned int sheaf_capacity;
@@ -79,4 +86,21 @@ 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);
+int kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
+               struct slab_sheaf *sheaf);
+
+static inline unsigned int kmem_cache_sheaf_count(struct slab_sheaf *sheaf)
+{
+       return sheaf->size;
+}
+
 #endif         /* _TOOLS_SLAB_H */
index 9f5fd722f27f1d3877be8927be30409cd74ab3c3..6936d3f7acf2150ddbaf32c56b331a21c7685875 100644 (file)
@@ -181,6 +181,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;
@@ -270,6 +276,77 @@ __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;
+       bool oversized = false;
+
+       if (count > s->sheaf_capacity) {
+               size = sizeof(*sheaf) + sizeof(void *) * count;
+               oversized = true;
+       } else {
+               size = sizeof(*sheaf) + sizeof(void *) * s->sheaf_capacity;
+       }
+
+       sheaf = malloc(size);
+       if (!sheaf) {
+               return NULL;
+       }
+
+       memset(sheaf, 0, size);
+       sheaf->cache = s;
+       sheaf->oversized = oversized;
+       sheaf->size = kmem_cache_alloc_bulk(s, gfp, count, sheaf->objects);
+       if (!sheaf->size) {
+               free(sheaf);
+               return NULL;
+       }
+
+       return sheaf;
+}
+
+int kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
+                struct slab_sheaf *sheaf)
+{
+       unsigned char refill;
+
+       refill = s->sheaf_capacity - sheaf->size;
+       if (!refill)
+               return 0;
+
+       refill = kmem_cache_alloc_bulk(s, gfp, refill,
+                                      &sheaf->objects[sheaf->size]);
+       if (!refill)
+               return -ENOMEM;
+
+       sheaf->size += refill;
+       return 0;
+}
+
+void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
+                struct slab_sheaf *sheaf)
+{
+       if (sheaf->size) {
+               //s->non_kernel += 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.
  */