Add and use slab init_once functionality
authorJens Axboe <jaxboe@fusionio.com>
Fri, 8 Oct 2010 11:37:49 +0000 (13:37 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Fri, 8 Oct 2010 11:37:49 +0000 (13:37 +0200)
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
kcompat.h
main.c

index 366a4f2403cdbfb65e81191bd76d39af87db1ef2..882865288a0df2a4b6b01ca5ee04d000e1db3d5a 100644 (file)
--- a/kcompat.h
+++ b/kcompat.h
@@ -50,13 +50,14 @@ static inline ktime_t ktime_get(void)
 }
 #endif
 
-static inline struct kmem_cache *binject_create_slab(const char *name,
-                                                    size_t obj_size)
+static inline struct kmem_cache *
+binject_create_slab(const char *name, size_t obj_size, unsigned long flags,
+                   void (*init_once)(void *))
 {
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
-       return kmem_cache_create(name, obj_size, 0, 0, NULL);
+       return kmem_cache_create(name, obj_size, 0, flags, NULL);
 #else
-       return kmem_cache_create(name, obj_size, 0, 0, NULL, NULL);
+       return kmem_cache_create(name, obj_size, 0, flags, init_once, NULL);
 #endif
 }
 
diff --git a/main.c b/main.c
index 676fd1e9c43fd4d596892ce2f771c15512bedb89..91f81a27b2a5e8b8557c6f0a579f8b3466265a9a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -160,8 +160,6 @@ static struct b_cmd *get_free_command(struct b_dev *bd)
 
        bc = kmem_cache_alloc(b_slab, GFP_KERNEL);
        if (bc) {
-               memset(bc, 0, sizeof(*bc));
-               INIT_LIST_HEAD(&bc->list);
                bc->bd = bd;
                return bc;
        }
@@ -177,7 +175,7 @@ static struct b_cmd *get_completed_command(struct b_dev *bd)
        if (!list_empty(&bd->done_list)) {
                bc = list_entry(bd->done_list.next, struct b_cmd, list);
                bd->done_cmds--;
-               list_del(&bc->list);
+               list_del_init(&bc->list);
        }
        spin_unlock_irq(&bd->lock);
        return bc;
@@ -412,6 +410,7 @@ static int b_dev_add_command(struct b_dev *bd, struct b_cmd *bc)
 
 static void b_dev_free_command(struct b_dev *bd, struct b_cmd *bc)
 {
+       BUG_ON(!list_empty(&bc->list));
        kmem_cache_free(b_slab, bc);
 }
 
@@ -708,11 +707,19 @@ static void __exit b_exit(void)
        misc_deregister(&b_misc_dev);
 }
 
+static void b_cmd_init_once(void *data)
+{
+       struct b_cmd *bc = data;
+
+       INIT_LIST_HEAD(&bc->list);
+}
+
 static int __init b_init(void)
 {
        int ret;
 
-       b_slab = binject_create_slab("binject", sizeof(struct b_cmd));
+       b_slab = binject_create_slab("binject", sizeof(struct b_cmd),
+                                       SLAB_HWCACHE_ALIGN, b_cmd_init_once);
        if (!b_slab) {
                printk(KERN_ERR "binject: failed to create cmd slab\n");
                return -ENOMEM;