Commit c20fb5f1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3: create a slab cache for transaction handles

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.
parent 9aabee2e
...@@ -1907,6 +1907,29 @@ static void __exit remove_jbd_proc_entry(void) ...@@ -1907,6 +1907,29 @@ static void __exit remove_jbd_proc_entry(void)
#endif #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 * Module startup and shutdown
*/ */
...@@ -1918,6 +1941,8 @@ static int __init journal_init_caches(void) ...@@ -1918,6 +1941,8 @@ static int __init journal_init_caches(void)
ret = journal_init_revoke_caches(); ret = journal_init_revoke_caches();
if (ret == 0) if (ret == 0)
ret = journal_init_journal_head_cache(); ret = journal_init_journal_head_cache();
if (ret == 0)
ret = journal_init_handle_cache();
return ret; return ret;
} }
...@@ -1925,6 +1950,7 @@ static void journal_destroy_caches(void) ...@@ -1925,6 +1950,7 @@ static void journal_destroy_caches(void)
{ {
journal_destroy_revoke_caches(); journal_destroy_revoke_caches();
journal_destroy_journal_head_cache(); journal_destroy_journal_head_cache();
journal_destroy_handle_cache();
} }
static int __init journal_init(void) static int __init journal_init(void)
......
...@@ -211,10 +211,10 @@ static int start_this_handle(journal_t *journal, handle_t *handle) ...@@ -211,10 +211,10 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
/* Allocate a new handle. This should probably be in a slab... */ /* Allocate a new handle. This should probably be in a slab... */
static handle_t *new_handle(int nblocks) 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) if (!handle)
return NULL; return NULL;
memset(handle, 0, sizeof (handle_t)); memset(handle, 0, sizeof(*handle));
handle->h_buffer_credits = nblocks; handle->h_buffer_credits = nblocks;
handle->h_ref = 1; handle->h_ref = 1;
INIT_LIST_HEAD(&handle->h_jcb); INIT_LIST_HEAD(&handle->h_jcb);
...@@ -258,7 +258,7 @@ handle_t *journal_start(journal_t *journal, int nblocks) ...@@ -258,7 +258,7 @@ handle_t *journal_start(journal_t *journal, int nblocks)
err = start_this_handle(journal, handle); err = start_this_handle(journal, handle);
if (err < 0) { if (err < 0) {
kfree(handle); jbd_free_handle(handle);
current->journal_info = NULL; current->journal_info = NULL;
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -1404,7 +1404,7 @@ int journal_stop(handle_t *handle) ...@@ -1404,7 +1404,7 @@ int journal_stop(handle_t *handle)
if (handle->h_sync && !(current->flags & PF_MEMALLOC)) if (handle->h_sync && !(current->flags & PF_MEMALLOC))
log_wait_commit(journal, tid); log_wait_commit(journal, tid);
} }
kfree(handle); jbd_free_handle(handle);
return err; return err;
} }
......
...@@ -814,6 +814,21 @@ extern void journal_remove_journal_head(struct buffer_head *bh); ...@@ -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_remove_journal_head(struct buffer_head *bh);
extern void journal_unlock_journal_head(struct journal_head *jh); 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 */ /* Primary revoke support */
#define JOURNAL_REVOKE_DEFAULT_HASH 256 #define JOURNAL_REVOKE_DEFAULT_HASH 256
extern int journal_init_revoke(journal_t *, int); extern int journal_init_revoke(journal_t *, int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment