aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2011-06-15 11:41:48 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-07-15 04:32:11 -0400
commit7cf8dcd3b68a760d66fbc7f0d75d3fbb8f21775d (patch)
treef529dace79c044e6128e9cf283a5c1a584fed5db /fs/gfs2/glock.c
parent17d539f0499fa2c0321b7c260831cca2bb36d119 (diff)
GFS2: Automatically adjust glock min hold time
This patch is a performance improvement for GFS2 in a clustered environment. It makes the glock hold time self-adjusting. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1c1336e7b3b2..88e8a23d0026 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -409,6 +409,10 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
409 if (held1 && held2 && list_empty(&gl->gl_holders)) 409 if (held1 && held2 && list_empty(&gl->gl_holders))
410 clear_bit(GLF_QUEUED, &gl->gl_flags); 410 clear_bit(GLF_QUEUED, &gl->gl_flags);
411 411
412 if (new_state != gl->gl_target)
413 /* shorten our minimum hold time */
414 gl->gl_hold_time = max(gl->gl_hold_time - GL_GLOCK_HOLD_DECR,
415 GL_GLOCK_MIN_HOLD);
412 gl->gl_state = new_state; 416 gl->gl_state = new_state;
413 gl->gl_tchange = jiffies; 417 gl->gl_tchange = jiffies;
414} 418}
@@ -668,7 +672,7 @@ static void glock_work_func(struct work_struct *work)
668 gl->gl_demote_state != LM_ST_EXCLUSIVE) { 672 gl->gl_demote_state != LM_ST_EXCLUSIVE) {
669 unsigned long holdtime, now = jiffies; 673 unsigned long holdtime, now = jiffies;
670 674
671 holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; 675 holdtime = gl->gl_tchange + gl->gl_hold_time;
672 if (time_before(now, holdtime)) 676 if (time_before(now, holdtime))
673 delay = holdtime - now; 677 delay = holdtime - now;
674 678
@@ -679,9 +683,14 @@ static void glock_work_func(struct work_struct *work)
679 } 683 }
680 run_queue(gl, 0); 684 run_queue(gl, 0);
681 spin_unlock(&gl->gl_spin); 685 spin_unlock(&gl->gl_spin);
682 if (!delay || 686 if (!delay)
683 queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
684 gfs2_glock_put(gl); 687 gfs2_glock_put(gl);
688 else {
689 if (gl->gl_name.ln_type != LM_TYPE_INODE)
690 delay = 0;
691 if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
692 gfs2_glock_put(gl);
693 }
685 if (drop_ref) 694 if (drop_ref)
686 gfs2_glock_put(gl); 695 gfs2_glock_put(gl);
687} 696}
@@ -743,6 +752,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
743 gl->gl_tchange = jiffies; 752 gl->gl_tchange = jiffies;
744 gl->gl_object = NULL; 753 gl->gl_object = NULL;
745 gl->gl_sbd = sdp; 754 gl->gl_sbd = sdp;
755 gl->gl_hold_time = GL_GLOCK_DFT_HOLD;
746 INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); 756 INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
747 INIT_WORK(&gl->gl_delete, delete_work_func); 757 INIT_WORK(&gl->gl_delete, delete_work_func);
748 758
@@ -855,8 +865,15 @@ static int gfs2_glock_demote_wait(void *word)
855 865
856static void wait_on_holder(struct gfs2_holder *gh) 866static void wait_on_holder(struct gfs2_holder *gh)
857{ 867{
868 unsigned long time1 = jiffies;
869
858 might_sleep(); 870 might_sleep();
859 wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE); 871 wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE);
872 if (time_after(jiffies, time1 + HZ)) /* have we waited > a second? */
873 /* Lengthen the minimum hold time. */
874 gh->gh_gl->gl_hold_time = min(gh->gh_gl->gl_hold_time +
875 GL_GLOCK_HOLD_INCR,
876 GL_GLOCK_MAX_HOLD);
860} 877}
861 878
862static void wait_on_demote(struct gfs2_glock *gl) 879static void wait_on_demote(struct gfs2_glock *gl)
@@ -1093,8 +1110,9 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1093 1110
1094 gfs2_glock_hold(gl); 1111 gfs2_glock_hold(gl);
1095 if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && 1112 if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
1096 !test_bit(GLF_DEMOTE, &gl->gl_flags)) 1113 !test_bit(GLF_DEMOTE, &gl->gl_flags) &&
1097 delay = gl->gl_ops->go_min_hold_time; 1114 gl->gl_name.ln_type == LM_TYPE_INODE)
1115 delay = gl->gl_hold_time;
1098 if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) 1116 if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
1099 gfs2_glock_put(gl); 1117 gfs2_glock_put(gl);
1100} 1118}
@@ -1273,12 +1291,13 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
1273 unsigned long now = jiffies; 1291 unsigned long now = jiffies;
1274 1292
1275 gfs2_glock_hold(gl); 1293 gfs2_glock_hold(gl);
1276 holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; 1294 holdtime = gl->gl_tchange + gl->gl_hold_time;
1277 if (test_bit(GLF_QUEUED, &gl->gl_flags)) { 1295 if (test_bit(GLF_QUEUED, &gl->gl_flags) &&
1296 gl->gl_name.ln_type == LM_TYPE_INODE) {
1278 if (time_before(now, holdtime)) 1297 if (time_before(now, holdtime))
1279 delay = holdtime - now; 1298 delay = holdtime - now;
1280 if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags)) 1299 if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
1281 delay = gl->gl_ops->go_min_hold_time; 1300 delay = gl->gl_hold_time;
1282 } 1301 }
1283 1302
1284 spin_lock(&gl->gl_spin); 1303 spin_lock(&gl->gl_spin);
@@ -1667,7 +1686,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
1667 dtime *= 1000000/HZ; /* demote time in uSec */ 1686 dtime *= 1000000/HZ; /* demote time in uSec */
1668 if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) 1687 if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
1669 dtime = 0; 1688 dtime = 0;
1670 gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d\n", 1689 gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d m:%ld\n",
1671 state2str(gl->gl_state), 1690 state2str(gl->gl_state),
1672 gl->gl_name.ln_type, 1691 gl->gl_name.ln_type,
1673 (unsigned long long)gl->gl_name.ln_number, 1692 (unsigned long long)gl->gl_name.ln_number,
@@ -1676,7 +1695,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
1676 state2str(gl->gl_demote_state), dtime, 1695 state2str(gl->gl_demote_state), dtime,
1677 atomic_read(&gl->gl_ail_count), 1696 atomic_read(&gl->gl_ail_count),
1678 atomic_read(&gl->gl_revokes), 1697 atomic_read(&gl->gl_revokes),
1679 atomic_read(&gl->gl_ref)); 1698 atomic_read(&gl->gl_ref), gl->gl_hold_time);
1680 1699
1681 list_for_each_entry(gh, &gl->gl_holders, gh_list) { 1700 list_for_each_entry(gh, &gl->gl_holders, gh_list) {
1682 error = dump_holder(seq, gh); 1701 error = dump_holder(seq, gh);