Commit 7b5e3d5fcf0d6fce66050bd0313a7dc2ae4abc62

Authored by Steven Whitehouse
1 parent fe08d5a897

GFS2: Don't enforce min hold time when two demotes occur in rapid succession

Due to the design of the VFS, it is quite usual for operations on GFS2
to consist of a lookup (requiring a shared lock) followed by an
operation requiring an exclusive lock. If a remote node has cached an
exclusive lock, then it will receive two demote events in rapid succession
firstly for a shared lock and then to unlocked. The existing min hold time
code was triggering in this case, even if the node was otherwise idle
since the state change time was being updated by the initial demote.

This patch introduces logic to skip the min hold timer in the case that
a "double demote" of this kind has occurred. The min hold timer will
still be used in all other cases.

A new glock flag is introduced which is used to keep track of whether
there have been any newly queued holders since the last glock state
change. The min hold time is only applied if the flag is set.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Tested-by: Abhijith Das <adas@redhat.com>

Showing 3 changed files with 14 additions and 5 deletions Side-by-side Diff

... ... @@ -441,6 +441,8 @@
441 441 else
442 442 gfs2_glock_put_nolock(gl);
443 443 }
  444 + if (held1 && held2 && list_empty(&gl->gl_holders))
  445 + clear_bit(GLF_QUEUED, &gl->gl_flags);
444 446  
445 447 gl->gl_state = new_state;
446 448 gl->gl_tchange = jiffies;
... ... @@ -1012,6 +1014,7 @@
1012 1014 if (unlikely((gh->gh_flags & LM_FLAG_PRIORITY) && !insert_pt))
1013 1015 insert_pt = &gh2->gh_list;
1014 1016 }
  1017 + set_bit(GLF_QUEUED, &gl->gl_flags);
1015 1018 if (likely(insert_pt == NULL)) {
1016 1019 list_add_tail(&gh->gh_list, &gl->gl_holders);
1017 1020 if (unlikely(gh->gh_flags & LM_FLAG_PRIORITY))
... ... @@ -1310,10 +1313,12 @@
1310 1313  
1311 1314 gfs2_glock_hold(gl);
1312 1315 holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
1313   - if (time_before(now, holdtime))
1314   - delay = holdtime - now;
1315   - if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
1316   - delay = gl->gl_ops->go_min_hold_time;
  1316 + if (test_bit(GLF_QUEUED, &gl->gl_flags)) {
  1317 + if (time_before(now, holdtime))
  1318 + delay = holdtime - now;
  1319 + if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
  1320 + delay = gl->gl_ops->go_min_hold_time;
  1321 + }
1317 1322  
1318 1323 spin_lock(&gl->gl_spin);
1319 1324 handle_callback(gl, state, delay);
... ... @@ -1660,6 +1665,8 @@
1660 1665 *p++ = 'I';
1661 1666 if (test_bit(GLF_FROZEN, gflags))
1662 1667 *p++ = 'F';
  1668 + if (test_bit(GLF_QUEUED, gflags))
  1669 + *p++ = 'q';
1663 1670 *p = 0;
1664 1671 return buf;
1665 1672 }
... ... @@ -196,6 +196,7 @@
196 196 GLF_REPLY_PENDING = 9,
197 197 GLF_INITIAL = 10,
198 198 GLF_FROZEN = 11,
  199 + GLF_QUEUED = 12,
199 200 };
200 201  
201 202 struct gfs2_glock {
fs/gfs2/trace_gfs2.h
... ... @@ -39,7 +39,8 @@
39 39 {(1UL << GLF_INVALIDATE_IN_PROGRESS), "i" }, \
40 40 {(1UL << GLF_REPLY_PENDING), "r" }, \
41 41 {(1UL << GLF_INITIAL), "I" }, \
42   - {(1UL << GLF_FROZEN), "F" })
  42 + {(1UL << GLF_FROZEN), "F" }, \
  43 + {(1UL << GLF_QUEUED), "q" })
43 44  
44 45 #ifndef NUMPTY
45 46 #define NUMPTY