|
@@ -3392,9 +3392,42 @@ void kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
|
|
EXPORT_SYMBOL(kmem_cache_free_bulk);
|
|
EXPORT_SYMBOL(kmem_cache_free_bulk);
|
|
|
|
|
|
int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
|
|
int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
|
|
- void **p)
|
|
|
|
|
|
+ void **p)
|
|
{
|
|
{
|
|
- return __kmem_cache_alloc_bulk(s, flags, size, p);
|
|
|
|
|
|
+ size_t i;
|
|
|
|
+
|
|
|
|
+ s = slab_pre_alloc_hook(s, flags);
|
|
|
|
+ if (!s)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ cache_alloc_debugcheck_before(s, flags);
|
|
|
|
+
|
|
|
|
+ local_irq_disable();
|
|
|
|
+ for (i = 0; i < size; i++) {
|
|
|
|
+ void *objp = __do_cache_alloc(s, flags);
|
|
|
|
+
|
|
|
|
+ /* this call could be done outside IRQ disabled section */
|
|
|
|
+ objp = cache_alloc_debugcheck_after(s, flags, objp, _RET_IP_);
|
|
|
|
+
|
|
|
|
+ if (unlikely(!objp))
|
|
|
|
+ goto error;
|
|
|
|
+ p[i] = objp;
|
|
|
|
+ }
|
|
|
|
+ local_irq_enable();
|
|
|
|
+
|
|
|
|
+ /* Clear memory outside IRQ disabled section */
|
|
|
|
+ if (unlikely(flags & __GFP_ZERO))
|
|
|
|
+ for (i = 0; i < size; i++)
|
|
|
|
+ memset(p[i], 0, s->object_size);
|
|
|
|
+
|
|
|
|
+ slab_post_alloc_hook(s, flags, size, p);
|
|
|
|
+ /* FIXME: Trace call missing. Christoph would like a bulk variant */
|
|
|
|
+ return size;
|
|
|
|
+error:
|
|
|
|
+ local_irq_enable();
|
|
|
|
+ slab_post_alloc_hook(s, flags, i, p);
|
|
|
|
+ __kmem_cache_free_bulk(s, i, p);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(kmem_cache_alloc_bulk);
|
|
EXPORT_SYMBOL(kmem_cache_alloc_bulk);
|
|
|
|
|