]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
gfs2: instrumentation wrt log_flush stuck
authorBob Peterson <rpeterso@redhat.com>
Fri, 22 May 2020 19:03:21 +0000 (14:03 -0500)
committerAndreas Gruenbacher <agruenba@redhat.com>
Fri, 5 Jun 2020 17:35:54 +0000 (19:35 +0200)
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>
fs/gfs2/log.c

index 0644e58c6191b3335bfb2313912c01bbfddbb28f..fcc7f58d74f0170aea7bdd50fc5be1397f49dea1 100644 (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 */