Skip to content

Commit fdbebab

Browse files
howletttehcaster
authored andcommitted
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 <[email protected]> Reviewed-by: Suren Baghdasaryan <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]>
1 parent 025f931 commit fdbebab

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

tools/include/linux/slab.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ struct kmem_cache_args {
123123
void (*ctor)(void *);
124124
};
125125

126+
struct slab_sheaf {
127+
union {
128+
struct list_head barn_list;
129+
/* only used for prefilled sheafs */
130+
unsigned int capacity;
131+
};
132+
struct kmem_cache *cache;
133+
unsigned int size;
134+
int node; /* only used for rcu_sheaf */
135+
void *objects[];
136+
};
137+
126138
static inline void *kzalloc(size_t size, gfp_t gfp)
127139
{
128140
return kmalloc(size, gfp | __GFP_ZERO);
@@ -173,5 +185,21 @@ __kmem_cache_create(const char *name, unsigned int size, unsigned int align,
173185
void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list);
174186
int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size,
175187
void **list);
188+
struct slab_sheaf *
189+
kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size);
190+
191+
void *
192+
kmem_cache_alloc_from_sheaf(struct kmem_cache *s, gfp_t gfp,
193+
struct slab_sheaf *sheaf);
194+
195+
void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
196+
struct slab_sheaf *sheaf);
197+
int kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
198+
struct slab_sheaf **sheafp, unsigned int size);
199+
200+
static inline unsigned int kmem_cache_sheaf_size(struct slab_sheaf *sheaf)
201+
{
202+
return sheaf->size;
203+
}
176204

177205
#endif /* _TOOLS_SLAB_H */

tools/testing/shared/linux.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list)
137137
if (kmalloc_verbose)
138138
pr_debug("Bulk free %p[0-%zu]\n", list, size - 1);
139139

140+
if (cachep->exec_callback) {
141+
if (cachep->callback)
142+
cachep->callback(cachep->private);
143+
cachep->exec_callback = false;
144+
}
145+
140146
pthread_mutex_lock(&cachep->lock);
141147
for (int i = 0; i < size; i++)
142148
kmem_cache_free_locked(cachep, list[i]);
@@ -242,6 +248,89 @@ __kmem_cache_create_args(const char *name, unsigned int size,
242248
return ret;
243249
}
244250

251+
struct slab_sheaf *
252+
kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
253+
{
254+
struct slab_sheaf *sheaf;
255+
unsigned int capacity;
256+
257+
if (s->exec_callback) {
258+
if (s->callback)
259+
s->callback(s->private);
260+
s->exec_callback = false;
261+
}
262+
263+
capacity = max(size, s->sheaf_capacity);
264+
265+
sheaf = calloc(1, sizeof(*sheaf) + sizeof(void *) * capacity);
266+
if (!sheaf)
267+
return NULL;
268+
269+
sheaf->cache = s;
270+
sheaf->capacity = capacity;
271+
sheaf->size = kmem_cache_alloc_bulk(s, gfp, size, sheaf->objects);
272+
if (!sheaf->size) {
273+
free(sheaf);
274+
return NULL;
275+
}
276+
277+
return sheaf;
278+
}
279+
280+
int kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
281+
struct slab_sheaf **sheafp, unsigned int size)
282+
{
283+
struct slab_sheaf *sheaf = *sheafp;
284+
int refill;
285+
286+
if (sheaf->size >= size)
287+
return 0;
288+
289+
if (size > sheaf->capacity) {
290+
sheaf = kmem_cache_prefill_sheaf(s, gfp, size);
291+
if (!sheaf)
292+
return -ENOMEM;
293+
294+
kmem_cache_return_sheaf(s, gfp, *sheafp);
295+
*sheafp = sheaf;
296+
return 0;
297+
}
298+
299+
refill = kmem_cache_alloc_bulk(s, gfp, size - sheaf->size,
300+
&sheaf->objects[sheaf->size]);
301+
if (!refill)
302+
return -ENOMEM;
303+
304+
sheaf->size += refill;
305+
return 0;
306+
}
307+
308+
void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
309+
struct slab_sheaf *sheaf)
310+
{
311+
if (sheaf->size)
312+
kmem_cache_free_bulk(s, sheaf->size, &sheaf->objects[0]);
313+
314+
free(sheaf);
315+
}
316+
317+
void *
318+
kmem_cache_alloc_from_sheaf(struct kmem_cache *s, gfp_t gfp,
319+
struct slab_sheaf *sheaf)
320+
{
321+
void *obj;
322+
323+
if (sheaf->size == 0) {
324+
printf("Nothing left in sheaf!\n");
325+
return NULL;
326+
}
327+
328+
obj = sheaf->objects[--sheaf->size];
329+
sheaf->objects[sheaf->size] = NULL;
330+
331+
return obj;
332+
}
333+
245334
/*
246335
* Test the test infrastructure for kem_cache_alloc/free and bulk counterparts.
247336
*/

0 commit comments

Comments
 (0)