diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2024-04-09 09:24:27 +0200 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2024-05-29 15:34:55 +0200 |
commit | 51568ac2e9d49b66f456dacd376af308f8695497 (patch) | |
tree | 292bf9f775c61b97dd9f6cc74efce94f4b792cc5 /fs/gfs2/glock.c | |
parent | gfs2: gfs2_glock_get cleanup (diff) | |
download | linux-51568ac2e9d49b66f456dacd376af308f8695497.tar.xz linux-51568ac2e9d49b66f456dacd376af308f8695497.zip |
gfs2: Report when glocks cannot be freed for a long time
When glocks cannot be freed for a long time, avoid the "task blocked for
more than N seconds" messages and report how many glocks are still
outstanding, instead.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 2d4e927c4d2f..b819f8b8d98b 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -2248,13 +2248,25 @@ void gfs2_gl_dq_holders(struct gfs2_sbd *sdp) void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) { + unsigned long start = jiffies; + bool timed_out = false; + set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags); flush_workqueue(glock_workqueue); glock_hash_walk(clear_glock, sdp); flush_workqueue(glock_workqueue); - wait_event_timeout(sdp->sd_kill_wait, - atomic_read(&sdp->sd_glock_disposal) == 0, - HZ * 600); + while (!timed_out) { + wait_event_timeout(sdp->sd_kill_wait, + !atomic_read(&sdp->sd_glock_disposal), + HZ * 60); + if (!atomic_read(&sdp->sd_glock_disposal)) + break; + timed_out = time_after(jiffies, start + (HZ * 600)); + fs_warn(sdp, "%u glocks left after %u seconds%s\n", + atomic_read(&sdp->sd_glock_disposal), + jiffies_to_msecs(jiffies - start) / 1000, + timed_out ? ":" : "; still waiting"); + } gfs2_lm_unmount(sdp); gfs2_free_dead_glocks(sdp); glock_hash_walk(dump_glock_func, sdp); |