gfs2: instrumentation wrt log_flush stuck

This adds checks for gfs2_log_flush being stuck, similarly to the check
in gfs2_ail1_flush. To faciliate this and make the strings easy to grep
we move the ail1 emptying to its own function, empty_ail1_list.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
Bob Peterson 2020-05-22 14:03:21 -05:00 committed by Andreas Gruenbacher
parent ea4e61c7f4
commit d5dc3d9677
1 changed files with 25 additions and 9 deletions

View File

@ -145,9 +145,6 @@ static void dump_ail_list(struct gfs2_sbd *sdp)
struct gfs2_bufdata *bd;
struct buffer_head *bh;
fs_err(sdp, "Error: In gfs2_ail1_flush for ten minutes! t=%d\n",
current->journal_info ? 1 : 0);
list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
list_for_each_entry_reverse(bd, &tr->tr_ail1_list,
bd_ail_st_list) {
@ -197,6 +194,8 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
restart:
ret = 0;
if (time_after(jiffies, flush_start + (HZ * 600))) {
fs_err(sdp, "Error: In %s for ten minutes! t=%d\n",
__func__, current->journal_info ? 1 : 0);
dump_ail_list(sdp);
goto out;
}
@ -876,6 +875,28 @@ static void ail_drain(struct gfs2_sbd *sdp)
spin_unlock(&sdp->sd_ail_lock);
}
/**
* empty_ail1_list - try to start IO and empty the ail1 list
* @sdp: Pointer to GFS2 superblock
*/
static void empty_ail1_list(struct gfs2_sbd *sdp)
{
unsigned long start = jiffies;
for (;;) {
if (time_after(jiffies, start + (HZ * 600))) {
fs_err(sdp, "Error: In %s for 10 minutes! t=%d\n",
__func__, current->journal_info ? 1 : 0);
dump_ail_list(sdp);
return;
}
gfs2_ail1_start(sdp);
gfs2_ail1_wait(sdp);
if (gfs2_ail1_empty(sdp, 0))
return;
}
}
/**
* gfs2_log_flush - flush incore transaction(s)
* @sdp: the filesystem
@ -965,12 +986,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
if (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) {
if (!sdp->sd_log_idle) {
for (;;) {
gfs2_ail1_start(sdp);
gfs2_ail1_wait(sdp);
if (gfs2_ail1_empty(sdp, 0))
break;
}
empty_ail1_list(sdp);
if (gfs2_withdrawn(sdp))
goto out;
atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */