Skip to content

Commit 5155682

Browse files
author
Andreas Gruenbacher
committed
gfs2: Fix LM_FLAG_TRY* logic in add_to_queue
JIRA: https://issues.redhat.com/browse/RHEL-116886 Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git The logic in add_to_queue() for determining whether a LM_FLAG_TRY or LM_FLAG_TRY_1CB holder should be queued does not make any sense: we are interested in wether or not the new operation will block behind an existing or future holder in the queue, but the current code checks for ongoing locking or ->go_inval() operations, which has little to do with that. Replace that code with something more sensible, remove the incorrect add_to_queue() function annotations, remove the similarly misguided do_error(gl, 0) call in do_xmote(), and add a missing comment to the same call in do_promote(). Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> (cherry picked from commit 0c23e24)
1 parent 13ed81a commit 5155682

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

fs/gfs2/glock.c

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ static bool do_promote(struct gfs2_glock *gl)
503503
*/
504504
if (list_is_first(&gh->gh_list, &gl->gl_holders))
505505
return false;
506-
do_error(gl, 0);
506+
do_error(gl, 0); /* Fail queued try locks */
507507
break;
508508
}
509509
set_bit(HIF_HOLDER, &gh->gh_iflags);
@@ -714,7 +714,6 @@ __acquires(&gl->gl_lockref.lock)
714714
if (test_and_set_bit(GLF_INVALIDATE_IN_PROGRESS,
715715
&gl->gl_flags))
716716
return;
717-
do_error(gl, 0); /* Fail queued try locks */
718717
}
719718
if (!glops->go_inval && !glops->go_sync)
720719
goto skip_inval;
@@ -1459,6 +1458,24 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
14591458
va_end(args);
14601459
}
14611460

1461+
static bool gfs2_should_queue_trylock(struct gfs2_glock *gl,
1462+
struct gfs2_holder *gh)
1463+
{
1464+
struct gfs2_holder *current_gh, *gh2;
1465+
1466+
current_gh = find_first_holder(gl);
1467+
if (current_gh && !may_grant(gl, current_gh, gh))
1468+
return false;
1469+
1470+
list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
1471+
if (test_bit(HIF_HOLDER, &gh2->gh_iflags))
1472+
continue;
1473+
if (!(gh2->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
1474+
return false;
1475+
}
1476+
return true;
1477+
}
1478+
14621479
static inline bool pid_is_meaningful(const struct gfs2_holder *gh)
14631480
{
14641481
if (!(gh->gh_flags & GL_NOPID))
@@ -1477,27 +1494,20 @@ static inline bool pid_is_meaningful(const struct gfs2_holder *gh)
14771494
*/
14781495

14791496
static inline void add_to_queue(struct gfs2_holder *gh)
1480-
__releases(&gl->gl_lockref.lock)
1481-
__acquires(&gl->gl_lockref.lock)
14821497
{
14831498
struct gfs2_glock *gl = gh->gh_gl;
14841499
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
14851500
struct gfs2_holder *gh2;
1486-
int try_futile = 0;
14871501

14881502
GLOCK_BUG_ON(gl, gh->gh_owner_pid == NULL);
14891503
if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags))
14901504
GLOCK_BUG_ON(gl, true);
14911505

1492-
if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
1493-
if (test_bit(GLF_LOCK, &gl->gl_flags)) {
1494-
struct gfs2_holder *current_gh;
1495-
1496-
current_gh = find_first_holder(gl);
1497-
try_futile = !may_grant(gl, current_gh, gh);
1498-
}
1499-
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
1500-
goto fail;
1506+
if ((gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) &&
1507+
!gfs2_should_queue_trylock(gl, gh)) {
1508+
gh->gh_error = GLR_TRYFAILED;
1509+
gfs2_holder_wake(gh);
1510+
return;
15011511
}
15021512

15031513
list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
@@ -1509,15 +1519,6 @@ __acquires(&gl->gl_lockref.lock)
15091519
continue;
15101520
goto trap_recursive;
15111521
}
1512-
list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
1513-
if (try_futile &&
1514-
!(gh2->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) {
1515-
fail:
1516-
gh->gh_error = GLR_TRYFAILED;
1517-
gfs2_holder_wake(gh);
1518-
return;
1519-
}
1520-
}
15211522
trace_gfs2_glock_queue(gh, 1);
15221523
gfs2_glstats_inc(gl, GFS2_LKS_QCOUNT);
15231524
gfs2_sbstats_inc(gl, GFS2_LKS_QCOUNT);

0 commit comments

Comments
 (0)