diff options
author | Peter Leckie <pleckie@sgi.com> | 2008-10-30 02:05:04 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 02:05:04 -0400 |
commit | bc3048e3cd3806ccfd5b16b1a30e5d6013abbd3d (patch) | |
tree | c6e27010cb66cc52f41bc696def885cb672fb61f /fs/xfs/quota/xfs_dquot_item.c | |
parent | d112f2984592acb774187b3adddc107fb0825500 (diff) |
[XFS] Clean up dquot pincount code.
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>
Diffstat (limited to 'fs/xfs/quota/xfs_dquot_item.c')
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 37 |
1 files changed, 11 insertions, 26 deletions
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index f028644caa5e..e33f8646418b 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -88,25 +88,22 @@ xfs_qm_dquot_logitem_format( | |||
88 | 88 | ||
89 | /* | 89 | /* |
90 | * Increment the pin count of the given dquot. | 90 | * Increment the pin count of the given dquot. |
91 | * This value is protected by pinlock spinlock in the xQM structure. | ||
92 | */ | 91 | */ |
93 | STATIC void | 92 | STATIC void |
94 | xfs_qm_dquot_logitem_pin( | 93 | xfs_qm_dquot_logitem_pin( |
95 | xfs_dq_logitem_t *logitem) | 94 | xfs_dq_logitem_t *logitem) |
96 | { | 95 | { |
97 | xfs_dquot_t *dqp; | 96 | xfs_dquot_t *dqp = logitem->qli_dquot; |
98 | 97 | ||
99 | dqp = logitem->qli_dquot; | ||
100 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 98 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
101 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | 99 | atomic_inc(dqp->q_pincount); |
102 | dqp->q_pincount++; | ||
103 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | ||
104 | } | 100 | } |
105 | 101 | ||
106 | /* | 102 | /* |
107 | * Decrement the pin count of the given dquot, and wake up | 103 | * Decrement the pin count of the given dquot, and wake up |
108 | * anyone in xfs_dqwait_unpin() if the count goes to 0. The | 104 | * anyone in xfs_dqwait_unpin() if the count goes to 0. The |
109 | * dquot must have been previously pinned with a call to xfs_dqpin(). | 105 | * dquot must have been previously pinned with a call to |
106 | * xfs_qm_dquot_logitem_pin(). | ||
110 | */ | 107 | */ |
111 | /* ARGSUSED */ | 108 | /* ARGSUSED */ |
112 | STATIC void | 109 | STATIC void |
@@ -114,16 +111,11 @@ xfs_qm_dquot_logitem_unpin( | |||
114 | xfs_dq_logitem_t *logitem, | 111 | xfs_dq_logitem_t *logitem, |
115 | int stale) | 112 | int stale) |
116 | { | 113 | { |
117 | xfs_dquot_t *dqp; | 114 | xfs_dquot_t *dqp = logitem->qli_dquot; |
118 | 115 | ||
119 | dqp = logitem->qli_dquot; | 116 | ASSERT(atomic_read(&dqp->q_pincount) > 0); |
120 | ASSERT(dqp->q_pincount > 0); | 117 | if (atomic_dec_and_test(&dqp->q_pincount)) |
121 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | 118 | wake_up(&dqp->q_pinwait); |
122 | dqp->q_pincount--; | ||
123 | if (dqp->q_pincount == 0) { | ||
124 | sv_broadcast(&dqp->q_pinwait); | ||
125 | } | ||
126 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | ||
127 | } | 119 | } |
128 | 120 | ||
129 | /* ARGSUSED */ | 121 | /* ARGSUSED */ |
@@ -193,21 +185,14 @@ xfs_qm_dqunpin_wait( | |||
193 | xfs_dquot_t *dqp) | 185 | xfs_dquot_t *dqp) |
194 | { | 186 | { |
195 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 187 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
196 | if (dqp->q_pincount == 0) { | 188 | if (atomic_read(&dqp->q_pincount) == 0) |
197 | return; | 189 | return; |
198 | } | ||
199 | 190 | ||
200 | /* | 191 | /* |
201 | * Give the log a push so we don't wait here too long. | 192 | * Give the log a push so we don't wait here too long. |
202 | */ | 193 | */ |
203 | xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); | 194 | xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); |
204 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | 195 | wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); |
205 | if (dqp->q_pincount == 0) { | ||
206 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); | ||
207 | return; | ||
208 | } | ||
209 | sv_wait(&(dqp->q_pinwait), PINOD, | ||
210 | &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s); | ||
211 | } | 196 | } |
212 | 197 | ||
213 | /* | 198 | /* |
@@ -310,7 +295,7 @@ xfs_qm_dquot_logitem_trylock( | |||
310 | uint retval; | 295 | uint retval; |
311 | 296 | ||
312 | dqp = qip->qli_dquot; | 297 | dqp = qip->qli_dquot; |
313 | if (dqp->q_pincount > 0) | 298 | if (atomic_read(&dqp->q_pincount) > 0) |
314 | return (XFS_ITEM_PINNED); | 299 | return (XFS_ITEM_PINNED); |
315 | 300 | ||
316 | if (! xfs_qm_dqlock_nowait(dqp)) | 301 | if (! xfs_qm_dqlock_nowait(dqp)) |