]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ext3: create a slab cache for transaction handles
authorAndrew Morton <akpm@digeo.com>
Thu, 3 Apr 2003 00:29:36 +0000 (16:29 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 3 Apr 2003 00:29:36 +0000 (16:29 -0800)
ext3 allocates and frees at least one handle structure for each system call.
kmalloc and kfree are apparent in the profiles.

Adding a slab cache for these objects takes the overhead for a write() from
1.63 microseconds down to 1.56.

fs/jbd/journal.c
fs/jbd/transaction.c
include/linux/jbd.h

index 2ef05640414e95ec2d57163899e994dca8acaf5c..167e632c4b518813eed3367489306bf8fbb9a4c5 100644 (file)
@@ -1907,6 +1907,29 @@ static void __exit remove_jbd_proc_entry(void)
 
 #endif
 
+kmem_cache_t *jbd_handle_cache;
+
+static int __init journal_init_handle_cache(void)
+{
+       jbd_handle_cache = kmem_cache_create("journal_handle",
+                               sizeof(handle_t),
+                               0,              /* offset */
+                               0,              /* flags */
+                               NULL,           /* ctor */
+                               NULL);          /* dtor */
+       if (jbd_handle_cache == NULL) {
+               printk(KERN_EMERG "JBD: failed to create handle cache\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void journal_destroy_handle_cache(void)
+{
+       if (jbd_handle_cache)
+               kmem_cache_destroy(jbd_handle_cache);
+}
+
 /*
  * Module startup and shutdown
  */
@@ -1918,6 +1941,8 @@ static int __init journal_init_caches(void)
        ret = journal_init_revoke_caches();
        if (ret == 0)
                ret = journal_init_journal_head_cache();
+       if (ret == 0)
+               ret = journal_init_handle_cache();
        return ret;
 }
 
@@ -1925,6 +1950,7 @@ static void journal_destroy_caches(void)
 {
        journal_destroy_revoke_caches();
        journal_destroy_journal_head_cache();
+       journal_destroy_handle_cache();
 }
 
 static int __init journal_init(void)
index 15694bfcb1470910631b0b853e2413ab02403376..74b51b7fd584326b65125c5d4d88b2ce92dd8ce0 100644 (file)
@@ -211,10 +211,10 @@ repeat_locked:
 /* Allocate a new handle.  This should probably be in a slab... */
 static handle_t *new_handle(int nblocks)
 {
-       handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
+       handle_t *handle = jbd_alloc_handle(GFP_NOFS);
        if (!handle)
                return NULL;
-       memset(handle, 0, sizeof (handle_t));
+       memset(handle, 0, sizeof(*handle));
        handle->h_buffer_credits = nblocks;
        handle->h_ref = 1;
        INIT_LIST_HEAD(&handle->h_jcb);
@@ -258,7 +258,7 @@ handle_t *journal_start(journal_t *journal, int nblocks)
 
        err = start_this_handle(journal, handle);
        if (err < 0) {
-               kfree(handle);
+               jbd_free_handle(handle);
                current->journal_info = NULL;
                return ERR_PTR(err);
        }
@@ -1404,7 +1404,7 @@ int journal_stop(handle_t *handle)
                if (handle->h_sync && !(current->flags & PF_MEMALLOC))
                        log_wait_commit(journal, tid);
        }
-       kfree(handle);
+       jbd_free_handle(handle);
        return err;
 }
 
index 34bf7c8787ecb30782838ed216a266e9fcb481ef..2362b90db9e73ae8d7253e981dc6b3a708e51659 100644 (file)
@@ -814,6 +814,21 @@ extern void        journal_remove_journal_head(struct buffer_head *bh);
 extern void    __journal_remove_journal_head(struct buffer_head *bh);
 extern void    journal_unlock_journal_head(struct journal_head *jh);
 
+/*
+ * handle management
+ */
+extern kmem_cache_t *jbd_handle_cache;
+
+static inline handle_t *jbd_alloc_handle(int gfp_flags)
+{
+       return kmem_cache_alloc(jbd_handle_cache, gfp_flags);
+}
+
+static inline void jbd_free_handle(handle_t *handle)
+{
+       kmem_cache_free(jbd_handle_cache, handle);
+}
+
 /* Primary revoke support */
 #define JOURNAL_REVOKE_DEFAULT_HASH 256
 extern int        journal_init_revoke(journal_t *, int);