|
@@ -409,6 +409,10 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
|
|
|
if (held1 && held2 && list_empty(&gl->gl_holders))
|
|
|
clear_bit(GLF_QUEUED, &gl->gl_flags);
|
|
|
|
|
|
+ if (new_state != gl->gl_target)
|
|
|
+ /* shorten our minimum hold time */
|
|
|
+ gl->gl_hold_time = max(gl->gl_hold_time - GL_GLOCK_HOLD_DECR,
|
|
|
+ GL_GLOCK_MIN_HOLD);
|
|
|
gl->gl_state = new_state;
|
|
|
gl->gl_tchange = jiffies;
|
|
|
}
|
|
@@ -668,7 +672,7 @@ static void glock_work_func(struct work_struct *work)
|
|
|
gl->gl_demote_state != LM_ST_EXCLUSIVE) {
|
|
|
unsigned long holdtime, now = jiffies;
|
|
|
|
|
|
- holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
|
|
|
+ holdtime = gl->gl_tchange + gl->gl_hold_time;
|
|
|
if (time_before(now, holdtime))
|
|
|
delay = holdtime - now;
|
|
|
|
|
@@ -679,9 +683,14 @@ static void glock_work_func(struct work_struct *work)
|
|
|
}
|
|
|
run_queue(gl, 0);
|
|
|
spin_unlock(&gl->gl_spin);
|
|
|
- if (!delay ||
|
|
|
- queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
|
|
|
+ if (!delay)
|
|
|
gfs2_glock_put(gl);
|
|
|
+ else {
|
|
|
+ if (gl->gl_name.ln_type != LM_TYPE_INODE)
|
|
|
+ delay = 0;
|
|
|
+ if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
|
|
|
+ gfs2_glock_put(gl);
|
|
|
+ }
|
|
|
if (drop_ref)
|
|
|
gfs2_glock_put(gl);
|
|
|
}
|
|
@@ -743,6 +752,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|
|
gl->gl_tchange = jiffies;
|
|
|
gl->gl_object = NULL;
|
|
|
gl->gl_sbd = sdp;
|
|
|
+ gl->gl_hold_time = GL_GLOCK_DFT_HOLD;
|
|
|
INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
|
|
|
INIT_WORK(&gl->gl_delete, delete_work_func);
|
|
|
|
|
@@ -855,8 +865,15 @@ static int gfs2_glock_demote_wait(void *word)
|
|
|
|
|
|
static void wait_on_holder(struct gfs2_holder *gh)
|
|
|
{
|
|
|
+ unsigned long time1 = jiffies;
|
|
|
+
|
|
|
might_sleep();
|
|
|
wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE);
|
|
|
+ if (time_after(jiffies, time1 + HZ)) /* have we waited > a second? */
|
|
|
+ /* Lengthen the minimum hold time. */
|
|
|
+ gh->gh_gl->gl_hold_time = min(gh->gh_gl->gl_hold_time +
|
|
|
+ GL_GLOCK_HOLD_INCR,
|
|
|
+ GL_GLOCK_MAX_HOLD);
|
|
|
}
|
|
|
|
|
|
static void wait_on_demote(struct gfs2_glock *gl)
|
|
@@ -1093,8 +1110,9 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
|
|
|
|
|
|
gfs2_glock_hold(gl);
|
|
|
if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
|
|
|
- !test_bit(GLF_DEMOTE, &gl->gl_flags))
|
|
|
- delay = gl->gl_ops->go_min_hold_time;
|
|
|
+ !test_bit(GLF_DEMOTE, &gl->gl_flags) &&
|
|
|
+ gl->gl_name.ln_type == LM_TYPE_INODE)
|
|
|
+ delay = gl->gl_hold_time;
|
|
|
if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
|
|
|
gfs2_glock_put(gl);
|
|
|
}
|
|
@@ -1273,12 +1291,13 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
|
|
|
unsigned long now = jiffies;
|
|
|
|
|
|
gfs2_glock_hold(gl);
|
|
|
- holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
|
|
|
- if (test_bit(GLF_QUEUED, &gl->gl_flags)) {
|
|
|
+ holdtime = gl->gl_tchange + gl->gl_hold_time;
|
|
|
+ if (test_bit(GLF_QUEUED, &gl->gl_flags) &&
|
|
|
+ gl->gl_name.ln_type == LM_TYPE_INODE) {
|
|
|
if (time_before(now, holdtime))
|
|
|
delay = holdtime - now;
|
|
|
if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
|
|
|
- delay = gl->gl_ops->go_min_hold_time;
|
|
|
+ delay = gl->gl_hold_time;
|
|
|
}
|
|
|
|
|
|
spin_lock(&gl->gl_spin);
|
|
@@ -1667,7 +1686,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
|
|
|
dtime *= 1000000/HZ; /* demote time in uSec */
|
|
|
if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
|
|
|
dtime = 0;
|
|
|
- gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d\n",
|
|
|
+ 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",
|
|
|
state2str(gl->gl_state),
|
|
|
gl->gl_name.ln_type,
|
|
|
(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)
|
|
|
state2str(gl->gl_demote_state), dtime,
|
|
|
atomic_read(&gl->gl_ail_count),
|
|
|
atomic_read(&gl->gl_revokes),
|
|
|
- atomic_read(&gl->gl_ref));
|
|
|
+ atomic_read(&gl->gl_ref), gl->gl_hold_time);
|
|
|
|
|
|
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
|
|
|
error = dump_holder(seq, gh);
|