Whamcloud - gitweb
LU-10773 obdclass: yield cpu during changelog_block_trim_ext 06/31506/5
authorFan Yong <fan.yong@intel.com>
Mon, 5 Mar 2018 15:49:56 +0000 (23:49 +0800)
committerJohn L. Hammond <john.hammond@intel.com>
Thu, 5 Apr 2018 20:02:39 +0000 (20:02 +0000)
To avoid soft-lockup if there are too many records to be handled.
The patch also filters out zero-sized records to avoid dead loop.

Master-change: https://review.whamcloud.com/31516

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Ia094f9153b5ef2602103d2ee13ee7ad3ffe6dc4f
Reviewed-on: https://review.whamcloud.com/31506
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
lustre/obdclass/llog_osd.c

index 9d458f4..c16cc63 100644 (file)
@@ -795,8 +795,26 @@ static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
        do {
                struct changelog_rec *rec = (struct changelog_rec *)(hdr + 1);
 
+               if (unlikely(hdr->lrh_len == 0)) {
+                       /* It is corruption case, we cannot know the next rec,
+                        * jump to the last one directly to avoid dead loop. */
+                       LCONSOLE(D_WARNING, "Hit invalid llog record: "
+                                "idx %u, type %u, id %u\n",
+                                hdr->lrh_index, hdr->lrh_type, hdr->lrh_id);
+                       hdr = llog_rec_hdr_next(last_hdr);
+                       if (unlikely(hdr == last_hdr))
+                               LCONSOLE(D_WARNING, "The last record crashed: "
+                                        "idx %u, type %u, id %u\n",
+                                        hdr->lrh_index, hdr->lrh_type,
+                                        hdr->lrh_id);
+                       break;
+               }
+
                changelog_remap_rec(rec, rec->cr_flags & flags);
                hdr = llog_rec_hdr_next(hdr);
+               /* Yield CPU to avoid soft-lockup if there are too many records
+                * to be handled. */
+               cond_resched();
        } while ((char *)hdr <= (char *)last_hdr);
 }