@@ -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