DLM_LOCK_RES_MIGRATING));
 }
 
+/* create/destroy slab caches */
+int dlm_init_master_caches(void);
+void dlm_destroy_master_caches(void);
+
+int dlm_init_lock_cache(void);
+void dlm_destroy_lock_cache(void);
 
 int dlm_init_mle_cache(void);
 void dlm_destroy_mle_cache(void);
+
 void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
 int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
                         struct dlm_lock_resource *res);
 
        status = dlm_init_mle_cache();
        if (status) {
                mlog(ML_ERROR, "Could not create o2dlm_mle slabcache\n");
-               return -1;
+               goto error;
+       }
+
+       status = dlm_init_master_caches();
+       if (status) {
+               mlog(ML_ERROR, "Could not create o2dlm_lockres and "
+                    "o2dlm_lockname slabcaches\n");
+               goto error;
+       }
+
+       status = dlm_init_lock_cache();
+       if (status) {
+               mlog(ML_ERROR, "Count not create o2dlm_lock slabcache\n");
+               goto error;
        }
 
        status = dlm_register_net_handlers();
        if (status) {
-               dlm_destroy_mle_cache();
-               return -1;
+               mlog(ML_ERROR, "Unable to register network handlers\n");
+               goto error;
        }
 
        return 0;
+error:
+       dlm_destroy_lock_cache();
+       dlm_destroy_master_caches();
+       dlm_destroy_mle_cache();
+       return -1;
 }
 
 static void __exit dlm_exit (void)
 {
        dlm_unregister_net_handlers();
+       dlm_destroy_lock_cache();
+       dlm_destroy_master_caches();
        dlm_destroy_mle_cache();
 }
 
 
 #define MLOG_MASK_PREFIX ML_DLM
 #include "cluster/masklog.h"
 
+static struct kmem_cache *dlm_lock_cache = NULL;
+
 static DEFINE_SPINLOCK(dlm_cookie_lock);
 static u64 dlm_next_cookie = 1;
 
 static void dlm_lock_release(struct kref *kref);
 static void dlm_lock_detach_lockres(struct dlm_lock *lock);
 
+int dlm_init_lock_cache(void)
+{
+       dlm_lock_cache = kmem_cache_create("o2dlm_lock",
+                                          sizeof(struct dlm_lock),
+                                          0, SLAB_HWCACHE_ALIGN, NULL);
+       if (dlm_lock_cache == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
+void dlm_destroy_lock_cache(void)
+{
+       if (dlm_lock_cache)
+               kmem_cache_destroy(dlm_lock_cache);
+}
+
 /* Tell us whether we can grant a new lock request.
  * locking:
  *   caller needs:  res->spinlock
                mlog(0, "freeing kernel-allocated lksb\n");
                kfree(lock->lksb);
        }
-       kfree(lock);
+       kmem_cache_free(dlm_lock_cache, lock);
 }
 
 /* associate a lock with it's lockres, getting a ref on the lockres */
        struct dlm_lock *lock;
        int kernel_allocated = 0;
 
-       lock = kzalloc(sizeof(*lock), GFP_NOFS);
+       lock = (struct dlm_lock *) kmem_cache_zalloc(dlm_lock_cache, GFP_NOFS);
        if (!lock)
                return NULL;
 
 
 
 #endif  /*  0  */
 
-
+static struct kmem_cache *dlm_lockres_cache = NULL;
+static struct kmem_cache *dlm_lockname_cache = NULL;
 static struct kmem_cache *dlm_mle_cache = NULL;
 
-
 static void dlm_mle_release(struct kref *kref);
 static void dlm_init_mle(struct dlm_master_list_entry *mle,
                        enum dlm_mle_type type,
  * LOCK RESOURCE FUNCTIONS
  */
 
+int dlm_init_master_caches(void)
+{
+       dlm_lockres_cache = kmem_cache_create("o2dlm_lockres",
+                                             sizeof(struct dlm_lock_resource),
+                                             0, SLAB_HWCACHE_ALIGN, NULL);
+       if (!dlm_lockres_cache)
+               goto bail;
+
+       dlm_lockname_cache = kmem_cache_create("o2dlm_lockname",
+                                              DLM_LOCKID_NAME_MAX, 0,
+                                              SLAB_HWCACHE_ALIGN, NULL);
+       if (!dlm_lockname_cache)
+               goto bail;
+
+       return 0;
+bail:
+       dlm_destroy_master_caches();
+       return -ENOMEM;
+}
+
+void dlm_destroy_master_caches(void)
+{
+       if (dlm_lockname_cache)
+               kmem_cache_destroy(dlm_lockname_cache);
+
+       if (dlm_lockres_cache)
+               kmem_cache_destroy(dlm_lockres_cache);
+}
+
 static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
                                  struct dlm_lock_resource *res,
                                  u8 owner)
        BUG_ON(!list_empty(&res->recovering));
        BUG_ON(!list_empty(&res->purge));
 
-       kfree(res->lockname.name);
+       kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
 
-       kfree(res);
+       kmem_cache_free(dlm_lockres_cache, res);
 }
 
 void dlm_lockres_put(struct dlm_lock_resource *res)
                                   const char *name,
                                   unsigned int namelen)
 {
-       struct dlm_lock_resource *res;
+       struct dlm_lock_resource *res = NULL;
 
-       res = kmalloc(sizeof(struct dlm_lock_resource), GFP_NOFS);
+       res = (struct dlm_lock_resource *)
+                               kmem_cache_zalloc(dlm_lockres_cache, GFP_NOFS);
        if (!res)
-               return NULL;
+               goto error;
 
-       res->lockname.name = kmalloc(namelen, GFP_NOFS);
-       if (!res->lockname.name) {
-               kfree(res);
-               return NULL;
-       }
+       res->lockname.name = (char *)
+                               kmem_cache_zalloc(dlm_lockname_cache, GFP_NOFS);
+       if (!res->lockname.name)
+               goto error;
 
        dlm_init_lockres(dlm, res, name, namelen);
        return res;
+
+error:
+       if (res && res->lockname.name)
+               kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
+
+       if (res)
+               kmem_cache_free(dlm_lockres_cache, res);
+       return NULL;
 }
 
 void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,