slab/slub: adjust kmem_cache_alloc_bulk API
authorJesper Dangaard Brouer <brouer@redhat.com>
Fri, 20 Nov 2015 23:57:58 +0000 (15:57 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 22 Nov 2015 19:58:44 +0000 (11:58 -0800)
Adjust kmem_cache_alloc_bulk API before we have any real users.

Adjust API to return type 'int' instead of previously type 'bool'.  This
is done to allow future extension of the bulk alloc API.

A future extension could be to allow SLUB to stop at a page boundary, when
specified by a flag, and then return the number of objects.

The advantage of this approach, would make it easier to make bulk alloc
run without local IRQs disabled.  With an approach of cmpxchg "stealing"
the entire c->freelist or page->freelist.  To avoid overshooting we would
stop processing at a slab-page boundary.  Else we always end up returning
some objects at the cost of another cmpxchg.

To keep compatible with future users of this API linking against an older
kernel when using the new flag, we need to return the number of allocated
objects with this API change.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Cc: Vladimir Davydov <vdavydov@virtuozzo.com>
Acked-by: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/slab.h
mm/slab.c
mm/slab.h
mm/slab_common.c
mm/slob.c
mm/slub.c

index 96940772bb92715b10028fde03ead671e6c3df56..2037a861e3679910152a98ba98a667b395c6773c 100644 (file)
@@ -316,7 +316,7 @@ void kmem_cache_free(struct kmem_cache *, void *);
  * Note that interrupts must be enabled when calling these functions.
  */
 void kmem_cache_free_bulk(struct kmem_cache *, size_t, void **);
-bool kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
+int kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment;
index e0819fa96559f3d166a35001dbefd4982ffd2a08..4765c97ce6900d98b8ce2968cf9ff62a176f6e42 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3419,7 +3419,7 @@ void kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
 }
 EXPORT_SYMBOL(kmem_cache_free_bulk);
 
-bool 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)
 {
        return __kmem_cache_alloc_bulk(s, flags, size, p);
index 27492eb678f722400147e22da62a68de893497e8..7b608719799763cb075c35e3fd4c15e0fddc18b5 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -170,7 +170,7 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
  * may be allocated or freed using these operations.
  */
 void __kmem_cache_free_bulk(struct kmem_cache *, size_t, void **);
-bool __kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
+int __kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
 
 #ifdef CONFIG_MEMCG_KMEM
 /*
index d88e97c10a2e31669753681efc74f6bf50fdf2ef..3c6a86b4ec25f8462c1584dcb5bcf01e4edbd4ff 100644 (file)
@@ -112,7 +112,7 @@ void __kmem_cache_free_bulk(struct kmem_cache *s, size_t nr, void **p)
                kmem_cache_free(s, p[i]);
 }
 
-bool __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr,
+int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr,
                                                                void **p)
 {
        size_t i;
@@ -121,10 +121,10 @@ bool __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr,
                void *x = p[i] = kmem_cache_alloc(s, flags);
                if (!x) {
                        __kmem_cache_free_bulk(s, i, p);
-                       return false;
+                       return 0;
                }
        }
-       return true;
+       return i;
 }
 
 #ifdef CONFIG_MEMCG_KMEM
index 0d7e5df74d1f03e7069d1d938452b9474bc9a969..17e8f8cc7c534adca165f6d0e9b546e2f8484148 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -617,7 +617,7 @@ void kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
 }
 EXPORT_SYMBOL(kmem_cache_free_bulk);
 
-bool 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)
 {
        return __kmem_cache_alloc_bulk(s, flags, size, p);
index 34847044dfe531b42a65e24c317f83cad6d42fce..46997517406ede0e987388763c9fa1d07875c1db 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2909,8 +2909,8 @@ void kmem_cache_free_bulk(struct kmem_cache *orig_s, size_t size, void **p)
 EXPORT_SYMBOL(kmem_cache_free_bulk);
 
 /* Note that interrupts must be enabled when calling this function. */
-bool kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
-                          void **p)
+int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
+                         void **p)
 {
        struct kmem_cache_cpu *c;
        int i;
@@ -2959,12 +2959,12 @@ bool kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
 
        /* memcg and kmem_cache debug support */
        slab_post_alloc_hook(s, flags, size, p);
-       return true;
+       return i;
 error:
        local_irq_enable();
        slab_post_alloc_hook(s, flags, i, p);
        __kmem_cache_free_bulk(s, i, p);
-       return false;
+       return 0;
 }
 EXPORT_SYMBOL(kmem_cache_alloc_bulk);