]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.fixes/xfs-kern_32215a_Clean-up-dquot-pincount-code.patch
Reenabled linux-xen and xen-image build
[ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / xfs-kern_32215a_Clean-up-dquot-pincount-code.patch
CommitLineData
00e5a55c
BS
1Date: Fri, Sep 26 2008 15:20:10 +1000
2From: Peter Leckie <pleckie@sgi.com>
3References: SGI:PV986789 bnc#482148
4Subject: Clean up dquot pincount code
5Patch-mainline: 2.6.28
6
7Clean up dquot pincount code.
8
9This is a code cleanup and optimization that removes a per mount point
10spinlock from the quota code and cleans up the code.
11
12The patch changes the pincount from being an int protected by a spinlock
13to an atomic_t allowing the pincount to be manipulated without holding
14the spinlock.
15
16This cleanup also protects against random wakup's of both the aild and
17xfssyncd by reevaluating the pincount after been woken. Two latter patches
18will address the Spurious wakeups.
19
20Signed-off-by: Peter Leckie <pleckie@sgi.com>
21Acked-by: Jan Kara <jack@suse.cz>
22
23Index: linux/fs/xfs/quota/xfs_dquot_item.c
24===================================================================
25--- linux.orig/fs/xfs/quota/xfs_dquot_item.c 2008-10-09 17:13:53.000000000 -0500
26+++ linux/fs/xfs/quota/xfs_dquot_item.c 2009-03-09 10:24:24.000000000 -0500
27@@ -88,25 +88,23 @@ xfs_qm_dquot_logitem_format(
28
29 /*
30 * Increment the pin count of the given dquot.
31- * This value is protected by pinlock spinlock in the xQM structure.
32 */
33 STATIC void
34 xfs_qm_dquot_logitem_pin(
35 xfs_dq_logitem_t *logitem)
36 {
37- xfs_dquot_t *dqp;
38+ xfs_dquot_t *dqp = logitem->qli_dquot;
39
40- dqp = logitem->qli_dquot;
41 ASSERT(XFS_DQ_IS_LOCKED(dqp));
42- spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
43- dqp->q_pincount++;
44- spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
45+ atomic_inc(&dqp->q_pincount);
46+
47 }
48
49 /*
50 * Decrement the pin count of the given dquot, and wake up
51 * anyone in xfs_dqwait_unpin() if the count goes to 0. The
52- * dquot must have been previously pinned with a call to xfs_dqpin().
53+ * dquot must have been previously pinned with a call to
54+ * xfs_qm_dquot_logitem_pin().
55 */
56 /* ARGSUSED */
57 STATIC void
58@@ -114,16 +112,12 @@ xfs_qm_dquot_logitem_unpin(
59 xfs_dq_logitem_t *logitem,
60 int stale)
61 {
62- xfs_dquot_t *dqp;
63+xfs_dquot_t *dqp = logitem->qli_dquot;
64+
65+ ASSERT(atomic_read(&dqp->q_pincount) > 0);
66+ if (atomic_dec_and_test(&dqp->q_pincount))
67+ wake_up(&dqp->q_pinwait);
68
69- dqp = logitem->qli_dquot;
70- ASSERT(dqp->q_pincount > 0);
71- spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
72- dqp->q_pincount--;
73- if (dqp->q_pincount == 0) {
74- sv_broadcast(&dqp->q_pinwait);
75- }
76- spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
77 }
78
79 /* ARGSUSED */
80@@ -193,7 +187,7 @@ xfs_qm_dqunpin_wait(
81 xfs_dquot_t *dqp)
82 {
83 ASSERT(XFS_DQ_IS_LOCKED(dqp));
84- if (dqp->q_pincount == 0) {
85+ if (atomic_read(&dqp->q_pincount) == 0) {
86 return;
87 }
88
89@@ -201,13 +195,7 @@ xfs_qm_dqunpin_wait(
90 * Give the log a push so we don't wait here too long.
91 */
92 xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE);
93- spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
94- if (dqp->q_pincount == 0) {
95- spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
96- return;
97- }
98- sv_wait(&(dqp->q_pinwait), PINOD,
99- &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s);
100+ wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
101 }
102
103 /*
104@@ -310,7 +298,7 @@ xfs_qm_dquot_logitem_trylock(
105 uint retval;
106
107 dqp = qip->qli_dquot;
108- if (dqp->q_pincount > 0)
109+ if (atomic_read(&dqp->q_pincount) > 0)
110 return (XFS_ITEM_PINNED);
111
112 if (! xfs_qm_dqlock_nowait(dqp))
113Index: linux/fs/xfs/quota/xfs_dquot.h
114===================================================================
115--- linux.orig/fs/xfs/quota/xfs_dquot.h 2008-10-09 17:13:53.000000000 -0500
116+++ linux/fs/xfs/quota/xfs_dquot.h 2009-03-09 10:36:25.000000000 -0500
117@@ -83,8 +83,9 @@ typedef struct xfs_dquot {
118 xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */
119 mutex_t q_qlock; /* quota lock */
120 struct completion q_flush; /* flush completion queue */
121- uint q_pincount; /* pin count for this dquot */
122- sv_t q_pinwait; /* sync var for pinning */
123+ atomic_t q_pincount; /* dquot pin count */
124+ wait_queue_head_t q_pinwait; /* dquot pinning wait queue */
125+
126 #ifdef XFS_DQUOT_TRACE
127 struct ktrace *q_trace; /* trace header structure */
128 #endif
129Index: linux/fs/xfs/quota/xfs_dquot.c
130===================================================================
131--- linux.orig/fs/xfs/quota/xfs_dquot.c 2008-10-09 17:13:53.000000000 -0500
132+++ linux/fs/xfs/quota/xfs_dquot.c 2009-03-09 10:38:06.000000000 -0500
133@@ -101,7 +101,7 @@ xfs_qm_dqinit(
134 if (brandnewdquot) {
135 dqp->dq_flnext = dqp->dq_flprev = dqp;
136 mutex_init(&dqp->q_qlock);
137- sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");
138+ init_waitqueue_head(&dqp->q_pinwait);
139
140 /*
141 * Because we want to use a counting completion, complete
142@@ -131,7 +131,7 @@ xfs_qm_dqinit(
143 dqp->q_res_bcount = 0;
144 dqp->q_res_icount = 0;
145 dqp->q_res_rtbcount = 0;
146- dqp->q_pincount = 0;
147+ atomic_set(&dqp->q_pincount, 0);
148 dqp->q_hash = NULL;
149 ASSERT(dqp->dq_flnext == dqp->dq_flprev);
150
151@@ -1489,7 +1489,7 @@ xfs_qm_dqpurge(
152 "xfs_qm_dqpurge: dquot %p flush failed", dqp);
153 xfs_dqflock(dqp);
154 }
155- ASSERT(dqp->q_pincount == 0);
156+ ASSERT(atomic_read(&dqp->q_pincount) == 0);
157 ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
158 !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
159
160Index: linux/fs/xfs/quota/xfs_qm.h
161===================================================================
162--- linux.orig/fs/xfs/quota/xfs_qm.h 2008-10-09 17:13:53.000000000 -0500
163+++ linux/fs/xfs/quota/xfs_qm.h 2009-03-09 10:11:15.000000000 -0500
164@@ -106,7 +106,6 @@ typedef struct xfs_qm {
165 typedef struct xfs_quotainfo {
166 xfs_inode_t *qi_uquotaip; /* user quota inode */
167 xfs_inode_t *qi_gquotaip; /* group quota inode */
168- spinlock_t qi_pinlock; /* dquot pinning lock */
169 xfs_dqlist_t qi_dqlist; /* all dquots in filesys */
170 int qi_dqreclaims; /* a change here indicates
171 a removal in the dqlist */
172Index: linux/fs/xfs/quota/xfs_qm.c
173===================================================================
174--- linux.orig/fs/xfs/quota/xfs_qm.c 2008-10-09 17:13:53.000000000 -0500
175+++ linux/fs/xfs/quota/xfs_qm.c 2009-03-09 10:12:12.000000000 -0500
176@@ -1137,7 +1137,6 @@ xfs_qm_init_quotainfo(
177 return error;
178 }
179
180- spin_lock_init(&qinf->qi_pinlock);
181 xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0);
182 qinf->qi_dqreclaims = 0;
183
184@@ -1234,7 +1233,6 @@ xfs_qm_destroy_quotainfo(
185 */
186 xfs_qm_rele_quotafs_ref(mp);
187
188- spinlock_destroy(&qi->qi_pinlock);
189 xfs_qm_list_destroy(&qi->qi_dqlist);
190
191 if (qi->qi_uquotaip) {