mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
tools/testing: Add support for prefilled slab sheafs
Add the prefilled sheaf structs to the slab header and the associated functions to the testing/shared/linux.c file. Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com> Reviewed-by: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
This commit is contained in:
parent
025f93101b
commit
fdbebab19f
2 changed files with 117 additions and 0 deletions
|
|
@ -123,6 +123,18 @@ struct kmem_cache_args {
|
|||
void (*ctor)(void *);
|
||||
};
|
||||
|
||||
struct slab_sheaf {
|
||||
union {
|
||||
struct list_head barn_list;
|
||||
/* only used for prefilled sheafs */
|
||||
unsigned int capacity;
|
||||
};
|
||||
struct kmem_cache *cache;
|
||||
unsigned int size;
|
||||
int node; /* only used for rcu_sheaf */
|
||||
void *objects[];
|
||||
};
|
||||
|
||||
static inline void *kzalloc(size_t size, gfp_t gfp)
|
||||
{
|
||||
return kmalloc(size, gfp | __GFP_ZERO);
|
||||
|
|
@ -173,5 +185,21 @@ __kmem_cache_create(const char *name, unsigned int size, unsigned int align,
|
|||
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 size);
|
||||
|
||||
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 **sheafp, unsigned int size);
|
||||
|
||||
static inline unsigned int kmem_cache_sheaf_size(struct slab_sheaf *sheaf)
|
||||
{
|
||||
return sheaf->size;
|
||||
}
|
||||
|
||||
#endif /* _TOOLS_SLAB_H */
|
||||
|
|
|
|||
|
|
@ -137,6 +137,12 @@ void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list)
|
|||
if (kmalloc_verbose)
|
||||
pr_debug("Bulk free %p[0-%zu]\n", list, size - 1);
|
||||
|
||||
if (cachep->exec_callback) {
|
||||
if (cachep->callback)
|
||||
cachep->callback(cachep->private);
|
||||
cachep->exec_callback = false;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&cachep->lock);
|
||||
for (int i = 0; i < size; i++)
|
||||
kmem_cache_free_locked(cachep, list[i]);
|
||||
|
|
@ -242,6 +248,89 @@ __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 size)
|
||||
{
|
||||
struct slab_sheaf *sheaf;
|
||||
unsigned int capacity;
|
||||
|
||||
if (s->exec_callback) {
|
||||
if (s->callback)
|
||||
s->callback(s->private);
|
||||
s->exec_callback = false;
|
||||
}
|
||||
|
||||
capacity = max(size, s->sheaf_capacity);
|
||||
|
||||
sheaf = calloc(1, sizeof(*sheaf) + sizeof(void *) * capacity);
|
||||
if (!sheaf)
|
||||
return NULL;
|
||||
|
||||
sheaf->cache = s;
|
||||
sheaf->capacity = capacity;
|
||||
sheaf->size = kmem_cache_alloc_bulk(s, gfp, size, 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 **sheafp, unsigned int size)
|
||||
{
|
||||
struct slab_sheaf *sheaf = *sheafp;
|
||||
int refill;
|
||||
|
||||
if (sheaf->size >= size)
|
||||
return 0;
|
||||
|
||||
if (size > sheaf->capacity) {
|
||||
sheaf = kmem_cache_prefill_sheaf(s, gfp, size);
|
||||
if (!sheaf)
|
||||
return -ENOMEM;
|
||||
|
||||
kmem_cache_return_sheaf(s, gfp, *sheafp);
|
||||
*sheafp = sheaf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
refill = kmem_cache_alloc_bulk(s, gfp, size - sheaf->size,
|
||||
&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)
|
||||
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)
|
||||
{
|
||||
void *obj;
|
||||
|
||||
if (sheaf->size == 0) {
|
||||
printf("Nothing left in sheaf!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = sheaf->objects[--sheaf->size];
|
||||
sheaf->objects[sheaf->size] = NULL;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the test infrastructure for kem_cache_alloc/free and bulk counterparts.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue