aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-01-19 04:30:01 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2011-01-21 04:39:08 -0500
commitbc015cb84129eb1451913cfebece270bf7a39e0f (patch)
tree4f116a61b802d87ae80051e9ae05d8fcb73d9ae7 /fs/gfs2/glops.c
parent2b1caf6ed7b888c95a1909d343799672731651a5 (diff)
GFS2: Use RCU for glock hash table
This has a number of advantages: - Reduces contention on the hash table lock - Makes the code smaller and simpler - Should speed up glock dumps when under load - Removes ref count changing in examine_bucket - No longer need hash chain lock in glock_put() in common case There are some further changes which this enables and which we may do in the future. One is to look at using SLAB_RCU, and another is to look at using a per-cpu counter for the per-sb glock counter, since that is touched twice in the lifetime of each glock (but only used at umount time). Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 263561bf1a50..ac5fac948f87 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -206,8 +206,17 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
206static int inode_go_demote_ok(const struct gfs2_glock *gl) 206static int inode_go_demote_ok(const struct gfs2_glock *gl)
207{ 207{
208 struct gfs2_sbd *sdp = gl->gl_sbd; 208 struct gfs2_sbd *sdp = gl->gl_sbd;
209 struct gfs2_holder *gh;
210
209 if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) 211 if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
210 return 0; 212 return 0;
213
214 if (!list_empty(&gl->gl_holders)) {
215 gh = list_entry(gl->gl_holders.next, struct gfs2_holder, gh_list);
216 if (gh->gh_list.next != &gl->gl_holders)
217 return 0;
218 }
219
211 return 1; 220 return 1;
212} 221}
213 222
@@ -272,19 +281,6 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
272} 281}
273 282
274/** 283/**
275 * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock
276 * @gl: the glock
277 *
278 * Returns: 1 if it's ok
279 */
280
281static int rgrp_go_demote_ok(const struct gfs2_glock *gl)
282{
283 const struct address_space *mapping = (const struct address_space *)(gl + 1);
284 return !mapping->nrpages;
285}
286
287/**
288 * rgrp_go_lock - operation done after an rgrp lock is locked by 284 * rgrp_go_lock - operation done after an rgrp lock is locked by
289 * a first holder on this node. 285 * a first holder on this node.
290 * @gl: the glock 286 * @gl: the glock
@@ -410,7 +406,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
410const struct gfs2_glock_operations gfs2_rgrp_glops = { 406const struct gfs2_glock_operations gfs2_rgrp_glops = {
411 .go_xmote_th = rgrp_go_sync, 407 .go_xmote_th = rgrp_go_sync,
412 .go_inval = rgrp_go_inval, 408 .go_inval = rgrp_go_inval,
413 .go_demote_ok = rgrp_go_demote_ok,
414 .go_lock = rgrp_go_lock, 409 .go_lock = rgrp_go_lock,
415 .go_unlock = rgrp_go_unlock, 410 .go_unlock = rgrp_go_unlock,
416 .go_dump = gfs2_rgrp_dump, 411 .go_dump = gfs2_rgrp_dump,