Not all dlm_lock_resource use lvb. It's a waste of memory for those
dlm_lock_resources since lvb is a "char lvb[64];".

This patch allocates lvb for dlm_lock_resources who use lvb.

Without the patch applied,
[...@cool linux-2.6]$ egrep "o2dlm_lockres" /proc/slabinfo
o2dlm_lockres         42     42    256   32    2 : tunables    0    0    0 : 
slabdata      2      2      0

After patch applied,
[...@cool linux-2.6]$ egrep "o2dlm_lockres" /proc/slabinfo
o2dlm_lockres         42     42    192   21    1 : tunables    0    0    0 : 
slabdata      2      2      0

#that's on i686.

Signed-off-by: Wengang Wang <[email protected]>
---
 fs/ocfs2/dlm/dlmast.c    |    2 ++
 fs/ocfs2/dlm/dlmcommon.h |    3 ++-
 fs/ocfs2/dlm/dlmlock.c   |    6 ++++++
 fs/ocfs2/dlm/dlmmaster.c |   31 ++++++++++++++++++++++++++++---
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index f449991..fe272b1 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -191,6 +191,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct 
dlm_lock_resource *res,
                        mlog(0, "getting lvb from lockres for %s node\n",
                                  lock->ml.node == dlm->node_num ? "master" :
                                  "remote");
+                       mlog_bug_on_msg(!res->lvb, "lockname : %.*s\n",
+                                       res->lockname.len, res->lockname.name);
                        memcpy(lksb->lvb, res->lvb, DLM_LVB_LEN);
                }
                /* Do nothing for lvb put requests - they should be done in
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 4b6ae2c..49e6492 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -329,7 +329,7 @@ struct dlm_lock_resource
        wait_queue_head_t wq;
        u8  owner;              //node which owns the lock resource, or unknown
        u16 state;
-       char lvb[DLM_LVB_LEN];
+       char *lvb;
        unsigned int inflight_locks;
        unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
 };
@@ -1033,6 +1033,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm,
 int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 int __dlm_lockres_has_locks(struct dlm_lock_resource *res);
 int __dlm_lockres_unused(struct dlm_lock_resource *res);
+char *dlm_alloc_lvb(char **lvb);
 
 static inline const char * dlm_lock_mode_name(int mode)
 {
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index 69cf369..5c7ece7 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -425,6 +425,12 @@ static void dlm_init_lock(struct dlm_lock *newlock, int 
type,
        kref_init(&newlock->lock_refs);
 }
 
+char *dlm_alloc_lvb(char **lvb)
+{
+       *lvb = kzalloc(DLM_LVB_LEN, GFP_NOFS);
+       return *lvb;
+}
+
 struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
                               struct dlm_lockstatus *lksb)
 {
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index ffb4c68..77315a4 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -545,6 +545,7 @@ static void dlm_lockres_release(struct kref *kref)
 
        kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
 
+       kfree(res->lvb);
        kmem_cache_free(dlm_lockres_cache, res);
 }
 
@@ -553,7 +554,20 @@ void dlm_lockres_put(struct dlm_lock_resource *res)
        kref_put(&res->refs, dlm_lockres_release);
 }
 
-static void dlm_init_lockres(struct dlm_ctxt *dlm,
+static int dlm_lockres_uses_lvb(struct dlm_lock_resource *res)
+{
+       switch (res->lockname.name[0]) {
+       case 'M':
+       case 'Q':
+       case 'R':
+       case 'P':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int dlm_init_lockres(struct dlm_ctxt *dlm,
                             struct dlm_lock_resource *res,
                             const char *name, unsigned int namelen)
 {
@@ -603,8 +617,16 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
        list_add_tail(&res->tracking, &dlm->tracking_list);
        spin_unlock(&dlm->spinlock);
 
-       memset(res->lvb, 0, DLM_LVB_LEN);
+       if (dlm_lockres_uses_lvb(res)) {
+               if (!dlm_alloc_lvb(&res->lvb)) {
+                       mlog(ML_ERROR, "no memory for lvb\n");
+                       return -ENOMEM;
+               }
+       } else {
+               res->lvb = NULL;
+       }
        memset(res->refmap, 0, sizeof(res->refmap));
+       return 0;
 }
 
 struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
@@ -612,6 +634,7 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt 
*dlm,
                                   unsigned int namelen)
 {
        struct dlm_lock_resource *res = NULL;
+       int ret;
 
        res = kmem_cache_zalloc(dlm_lockres_cache, GFP_NOFS);
        if (!res)
@@ -621,7 +644,9 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt 
*dlm,
        if (!res->lockname.name)
                goto error;
 
-       dlm_init_lockres(dlm, res, name, namelen);
+       ret = dlm_init_lockres(dlm, res, name, namelen);
+       if (ret) 
+               goto error;
        return res;
 
 error:
-- 
1.7.2.1


_______________________________________________
Ocfs2-devel mailing list
[email protected]
http://oss.oracle.com/mailman/listinfo/ocfs2-devel

Reply via email to