Before this patch, function run_queue did a bunch of logic when glocks are being promoted. This patch moves the logic to the glock state machine and simplifies run_queue further.
Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/glock.c | 46 +++++++++++++++++++++++----------------------- fs/gfs2/glock.h | 1 + 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 023e2186b374..6048867b2d66 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -621,37 +621,17 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock) __releases(&gl->gl_lockref.lock) __acquires(&gl->gl_lockref.lock) { - struct gfs2_holder *gh = NULL; - int ret; - if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) return; GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)); if (test_bit(GLF_DEMOTE, &gl->gl_flags) && - gl->gl_demote_state != gl->gl_state) { + gl->gl_demote_state != gl->gl_state) __state_machine(gl, nonblock ? GL_ST_DEMOTE_NONBLOCK : GL_ST_BLOCKING_DEMOTE); - return; - } else { - if (test_bit(GLF_DEMOTE, &gl->gl_flags)) - gfs2_demote_wake(gl); - ret = do_promote(gl); - if (ret == 0) { - clear_bit(GLF_LOCK, &gl->gl_flags); - smp_mb__after_atomic(); - return; - } - if (ret == 2) - return; - gh = find_first_waiter(gl); - gl->gl_target = gh->gh_state; - if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) - do_error(gl, 0); /* Fail queued try locks */ - } - __state_machine(gl, GL_ST_DO_XMOTE); - return; + else + __state_machine(gl, GL_ST_PROMOTE); } /** @@ -668,6 +648,7 @@ __acquires(&gl->gl_lockref.lock) */ static void __state_machine(struct gfs2_glock *gl, int new_state) { + struct gfs2_holder *gh = NULL; int ret; BUG_ON(!spin_is_locked(&gl->gl_lockref.lock)); @@ -727,6 +708,25 @@ static void __state_machine(struct gfs2_glock *gl, int new_state) gl->gl_lockref.count++; __gfs2_glock_queue_work(gl, 0); break; + + case GL_ST_PROMOTE: + gl->gl_mch = GL_ST_IDLE; + if (test_bit(GLF_DEMOTE, &gl->gl_flags)) + gfs2_demote_wake(gl); + ret = do_promote(gl); + if (ret == 0) { + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_atomic(); + break; + } + if (ret == 2) + break; + gh = find_first_waiter(gl); + gl->gl_target = gh->gh_state; + if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) + do_error(gl, 0); /* Fail queued try locks */ + gl->gl_mch = GL_ST_DO_XMOTE; + break; } } while (gl->gl_mch != GL_ST_IDLE); } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index c8b704a73638..76db63d1efae 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -128,6 +128,7 @@ enum gl_machine_states { state change attempt from dlm. */ GL_ST_DEMOTE_NONBLOCK = 4, /* Demote is in progress - non-blocking */ GL_ST_BLOCKING_DEMOTE = 5, /* Demote is in progress - blocking */ + GL_ST_PROMOTE = 6, /* Promote the lock */ }; struct lm_lockops { -- 2.19.1