struct slab_sheaf {
struct kmem_cache *cache;
unsigned int size;
+ bool oversized;
void *objects[];
};
void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
struct slab_sheaf *sheaf);
+void kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
+ struct slab_sheaf *sheaf, unsigned long more);
+
+static inline unsigned int kmem_cache_sheaf_count(struct slab_sheaf *sheaf)
+{
+ return sheaf->size;
+}
#endif /* _TOOLS_SLAB_H */
{
struct slab_sheaf *sheaf;
size_t size;
+ bool oversized = false;
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 *) * count;
+ oversized = true;
+ } else {
+ size = sizeof(*sheaf) + sizeof(void *) * s->sheaf_capacity;
}
- 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 sheaf;
}
+void kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
+ struct slab_sheaf *sheaf, unsigned long more)
+{
+ unsigned char refill;
+
+ refill = kmem_cache_alloc_bulk(s, gfp, more,
+ sheaf->objects[sheaf->size - 1]);
+ if (!refill)
+ return;
+
+ sheaf->size += refill;
+}
+
void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
struct slab_sheaf *sheaf)
{
- if (sheaf->size)
+ if (sheaf->size) {
+ //s->non_kernel += sheaf->size;
kmem_cache_free_bulk(s, sheaf->size, &sheaf->objects[0]);
+ }
free(sheaf);
}