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:
parent
ea4e61c7f4
commit
d5dc3d9677
|
@ -145,9 +145,6 @@ static void dump_ail_list(struct gfs2_sbd *sdp)
|
||||||
struct gfs2_bufdata *bd;
|
struct gfs2_bufdata *bd;
|
||||||
struct buffer_head *bh;
|
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(tr, &sdp->sd_ail1_list, tr_list) {
|
||||||
list_for_each_entry_reverse(bd, &tr->tr_ail1_list,
|
list_for_each_entry_reverse(bd, &tr->tr_ail1_list,
|
||||||
bd_ail_st_list) {
|
bd_ail_st_list) {
|
||||||
|
@ -197,6 +194,8 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
|
||||||
restart:
|
restart:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (time_after(jiffies, flush_start + (HZ * 600))) {
|
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);
|
dump_ail_list(sdp);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -876,6 +875,28 @@ static void ail_drain(struct gfs2_sbd *sdp)
|
||||||
spin_unlock(&sdp->sd_ail_lock);
|
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)
|
* gfs2_log_flush - flush incore transaction(s)
|
||||||
* @sdp: the filesystem
|
* @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 (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) {
|
||||||
if (!sdp->sd_log_idle) {
|
if (!sdp->sd_log_idle) {
|
||||||
for (;;) {
|
empty_ail1_list(sdp);
|
||||||
gfs2_ail1_start(sdp);
|
|
||||||
gfs2_ail1_wait(sdp);
|
|
||||||
if (gfs2_ail1_empty(sdp, 0))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (gfs2_withdrawn(sdp))
|
if (gfs2_withdrawn(sdp))
|
||||||
goto out;
|
goto out;
|
||||||
atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
|
atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
|
||||||
|
|
Loading…
Reference in New Issue