]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/xfs-kern_32215a_Clean-up-dquot-pincount-code.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / xfs-kern_32215a_Clean-up-dquot-pincount-code.patch
1 Date: Fri, Sep 26 2008 15:20:10 +1000
2 From: Peter Leckie <pleckie@sgi.com>
3 References: SGI:PV986789 bnc#482148
4 Subject: Clean up dquot pincount code
5 Patch-mainline: 2.6.28
6
7 Clean up dquot pincount code.
8
9 This is a code cleanup and optimization that removes a per mount point
10 spinlock from the quota code and cleans up the code.
11
12 The patch changes the pincount from being an int protected by a spinlock
13 to an atomic_t allowing the pincount to be manipulated without holding
14 the spinlock.
15
16 This cleanup also protects against random wakup's of both the aild and
17 xfssyncd by reevaluating the pincount after been woken. Two latter patches
18 will address the Spurious wakeups.
19
20 Signed-off-by: Peter Leckie <pleckie@sgi.com>
21 Acked-by: Jan Kara <jack@suse.cz>
22
23 Index: 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))
113 Index: 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
129 Index: 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
160 Index: 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 */
172 Index: 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) {