[GFS2] Reduce size of struct gdlm_lock
authorSteven Whitehouse <swhiteho@redhat.com>
Mon, 14 May 2007 16:43:26 +0000 (17:43 +0100)
committerSteven Whitehouse <swhiteho@redhat.com>
Mon, 9 Jul 2007 07:22:21 +0000 (08:22 +0100)
This patch removes the completion (which is rather large) from struct
gdlm_lock in favour of using the wait_on_bit() functions. We don't need
to add any extra fields to the structure to do this, so we save 32 bytes
(on x86_64) per structure. This adds up to quite a lot when we may
potentially have millions of these lock structures,

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Acked-by: David Teigland <teigland@redhat.com>
fs/gfs2/locking/dlm/lock.c
fs/gfs2/locking/dlm/lock_dlm.h
fs/gfs2/locking/dlm/thread.c

index c305255bfe8ade71b4e53b8d0b7c5389da0623a0..542a797ac89a453f8cf9d691ad56c8888ac092cb 100644 (file)
@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
        lp->cur = DLM_LOCK_IV;
        lp->lvb = NULL;
        lp->hold_null = NULL;
-       init_completion(&lp->ast_wait);
        INIT_LIST_HEAD(&lp->clist);
        INIT_LIST_HEAD(&lp->blist);
        INIT_LIST_HEAD(&lp->delay_list);
@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp)
        lp->lksb.sb_lvbptr = NULL;
 }
 
+static int gdlm_ast_wait(void *word)
+{
+       schedule();
+       return 0;
+}
+
 /* This can do a synchronous dlm request (requiring a lock_dlm thread to get
    the completion) because gfs won't call hold_lvb() during a callback (from
    the context of a lock_dlm thread). */
@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp)
        lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE;
        set_bit(LFL_NOBAST, &lpn->flags);
        set_bit(LFL_INLOCK, &lpn->flags);
+       set_bit(LFL_AST_WAIT, &lpn->flags);
 
-       init_completion(&lpn->ast_wait);
        gdlm_do_lock(lpn);
-       wait_for_completion(&lpn->ast_wait);
+       wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE);
        error = lpn->lksb.sb_status;
        if (error) {
                printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n",
index d074c6e6f9bfc0cacbbaff393f9c4f6c4a4fd454..24d70f73b65124f3a6960099a82dcf5544b0416d 100644 (file)
@@ -101,6 +101,7 @@ enum {
        LFL_NOBAST              = 10,
        LFL_HEADQUE             = 11,
        LFL_UNLOCK_DELETE       = 12,
+       LFL_AST_WAIT            = 13,
 };
 
 struct gdlm_lock {
@@ -117,7 +118,6 @@ struct gdlm_lock {
        unsigned long           flags;          /* lock_dlm flags LFL_ */
 
        int                     bast_mode;      /* protected by async_lock */
-       struct completion       ast_wait;
 
        struct list_head        clist;          /* complete */
        struct list_head        blist;          /* blocking */
index 9cf1f168eaf8b281eacf00778f2c1b3d36642edb..1aca51e45092e0eb6c37691ccfa6c0af3cf51682 100644 (file)
@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode)
        ls->fscb(ls->sdp, cb, &lp->lockname);
 }
 
+static void wake_up_ast(struct gdlm_lock *lp)
+{
+       clear_bit(LFL_AST_WAIT, &lp->flags);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&lp->flags, LFL_AST_WAIT);
+}
+
 static void process_complete(struct gdlm_lock *lp)
 {
        struct gdlm_ls *ls = lp->ls;
@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp)
         */
 
        if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) {
-               complete(&lp->ast_wait);
+               wake_up_ast(lp);
                return;
        }
 
@@ -214,7 +221,7 @@ out:
        if (test_bit(LFL_INLOCK, &lp->flags)) {
                clear_bit(LFL_NOBLOCK, &lp->flags);
                lp->cur = lp->req;
-               complete(&lp->ast_wait);
+               wake_up_ast(lp);
                return;
        }