]> Pileus Git - ~andy/linux/commitdiff
[XFS] Clean up dquot pincount code.
authorPeter Leckie <pleckie@sgi.com>
Thu, 30 Oct 2008 06:05:04 +0000 (17:05 +1100)
committerLachlan McIlroy <lachlan@sgi.com>
Thu, 30 Oct 2008 06:05:04 +0000 (17:05 +1100)
This is a code cleanup and optimization that removes a per mount point
spinlock from the quota code and cleans up the code.

The patch changes the pincount from being an int protected by a spinlock
to an atomic_t allowing the pincount to be manipulated without holding the
spinlock.

This cleanup also protects against random wakup's of both the aild and
xfssyncd by reevaluating the pincount after been woken. Two latter patches
will address the Spurious wakeups.

SGI-PV: 986789

SGI-Modid: xfs-linux-melb:xfs-kern:32215a

Signed-off-by: Peter Leckie <pleckie@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Donald Douwsma <donaldd@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
fs/xfs/quota/xfs_dquot.c
fs/xfs/quota/xfs_dquot.h
fs/xfs/quota/xfs_dquot_item.c
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm.h

index f2705f2fd43c264674660da0285adb5e5a2c39db..d3f4fbbe24809637886fc21cc96e56cf42a62b10 100644 (file)
@@ -101,7 +101,7 @@ xfs_qm_dqinit(
        if (brandnewdquot) {
                dqp->dq_flnext = dqp->dq_flprev = dqp;
                mutex_init(&dqp->q_qlock);
-               sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");
+               init_waitqueue_head(&dqp->q_pinwait);
 
                /*
                 * Because we want to use a counting completion, complete
@@ -131,7 +131,7 @@ xfs_qm_dqinit(
                 dqp->q_res_bcount = 0;
                 dqp->q_res_icount = 0;
                 dqp->q_res_rtbcount = 0;
-                dqp->q_pincount = 0;
+                atomic_set(&dqp->q_pincount, 0);
                 dqp->q_hash = NULL;
                 ASSERT(dqp->dq_flnext == dqp->dq_flprev);
 
@@ -1489,7 +1489,7 @@ xfs_qm_dqpurge(
                                "xfs_qm_dqpurge: dquot %p flush failed", dqp);
                xfs_dqflock(dqp);
        }
-       ASSERT(dqp->q_pincount == 0);
+       ASSERT(atomic_read(&dqp->q_pincount) == 0);
        ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
               !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
 
index 8958d0faf8d37606c806a1ce22d9c996036bdf08..7e455337e2ba55038199a8afeb1ac85a70786d9c 100644 (file)
@@ -83,8 +83,8 @@ typedef struct xfs_dquot {
        xfs_qcnt_t       q_res_rtbcount;/* total realtime blks used+reserved */
        mutex_t          q_qlock;       /* quota lock */
        struct completion q_flush;      /* flush completion queue */
-       uint             q_pincount;    /* pin count for this dquot */
-       sv_t             q_pinwait;     /* sync var for pinning */
+       atomic_t          q_pincount;   /* dquot pin count */
+       wait_queue_head_t q_pinwait;    /* dquot pinning wait queue */
 #ifdef XFS_DQUOT_TRACE
        struct ktrace   *q_trace;       /* trace header structure */
 #endif
index f028644caa5eb090e93620aae600bd6d9d87d26d..e33f8646418bcfe72589d0182cfd5125484818fc 100644 (file)
@@ -88,25 +88,22 @@ xfs_qm_dquot_logitem_format(
 
 /*
  * Increment the pin count of the given dquot.
- * This value is protected by pinlock spinlock in the xQM structure.
  */
 STATIC void
 xfs_qm_dquot_logitem_pin(
        xfs_dq_logitem_t *logitem)
 {
-       xfs_dquot_t *dqp;
+       xfs_dquot_t *dqp = logitem->qli_dquot;
 
-       dqp = logitem->qli_dquot;
        ASSERT(XFS_DQ_IS_LOCKED(dqp));
-       spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
-       dqp->q_pincount++;
-       spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
+       atomic_inc(dqp->q_pincount);
 }
 
 /*
  * Decrement the pin count of the given dquot, and wake up
  * anyone in xfs_dqwait_unpin() if the count goes to 0.         The
- * dquot must have been previously pinned with a call to xfs_dqpin().
+ * dquot must have been previously pinned with a call to
+ * xfs_qm_dquot_logitem_pin().
  */
 /* ARGSUSED */
 STATIC void
@@ -114,16 +111,11 @@ xfs_qm_dquot_logitem_unpin(
        xfs_dq_logitem_t *logitem,
        int               stale)
 {
-       xfs_dquot_t *dqp;
+       xfs_dquot_t *dqp = logitem->qli_dquot;
 
-       dqp = logitem->qli_dquot;
-       ASSERT(dqp->q_pincount > 0);
-       spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
-       dqp->q_pincount--;
-       if (dqp->q_pincount == 0) {
-               sv_broadcast(&dqp->q_pinwait);
-       }
-       spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
+       ASSERT(atomic_read(&dqp->q_pincount) > 0);
+       if (atomic_dec_and_test(&dqp->q_pincount))
+               wake_up(&dqp->q_pinwait);
 }
 
 /* ARGSUSED */
@@ -193,21 +185,14 @@ xfs_qm_dqunpin_wait(
        xfs_dquot_t     *dqp)
 {
        ASSERT(XFS_DQ_IS_LOCKED(dqp));
-       if (dqp->q_pincount == 0) {
+       if (atomic_read(&dqp->q_pincount) == 0)
                return;
-       }
 
        /*
         * Give the log a push so we don't wait here too long.
         */
        xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE);
-       spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
-       if (dqp->q_pincount == 0) {
-               spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
-               return;
-       }
-       sv_wait(&(dqp->q_pinwait), PINOD,
-               &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s);
+       wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
 }
 
 /*
@@ -310,7 +295,7 @@ xfs_qm_dquot_logitem_trylock(
        uint                    retval;
 
        dqp = qip->qli_dquot;
-       if (dqp->q_pincount > 0)
+       if (atomic_read(&dqp->q_pincount) > 0)
                return (XFS_ITEM_PINNED);
 
        if (! xfs_qm_dqlock_nowait(dqp))
index df0ffef9775ae75d54c647a7b56c4ba248028a01..270f775974e269a4d334d24dfc4eefc1467db15b 100644 (file)
@@ -1137,7 +1137,6 @@ xfs_qm_init_quotainfo(
                return error;
        }
 
-       spin_lock_init(&qinf->qi_pinlock);
        xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0);
        qinf->qi_dqreclaims = 0;
 
@@ -1234,7 +1233,6 @@ xfs_qm_destroy_quotainfo(
         */
        xfs_qm_rele_quotafs_ref(mp);
 
-       spinlock_destroy(&qi->qi_pinlock);
        xfs_qm_list_destroy(&qi->qi_dqlist);
 
        if (qi->qi_uquotaip) {
index 44f25349e478bb7eb7db859da7c49c24c0cf75d1..4f2de9771728d40ac45925809f844740a503bc7a 100644 (file)
@@ -106,7 +106,6 @@ typedef struct xfs_qm {
 typedef struct xfs_quotainfo {
        xfs_inode_t     *qi_uquotaip;    /* user quota inode */
        xfs_inode_t     *qi_gquotaip;    /* group quota inode */
-       spinlock_t       qi_pinlock;     /* dquot pinning lock */
        xfs_dqlist_t     qi_dqlist;      /* all dquots in filesys */
        int              qi_dqreclaims;  /* a change here indicates
                                            a removal in the dqlist */