]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: only relog deferred intent items if free space in the log gets low
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 12 Nov 2020 22:21:54 +0000 (17:21 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 12 Nov 2020 22:21:54 +0000 (17:21 -0500)
Source kernel commit: 74f4d6a1e065c92428c5b588099e307a582d79d9

Now that we have the ability to ask the log how far the tail needs to be
pushed to maintain its free space targets, augment the decision to relog
an intent item so that we only do it if the log has hit the 75% full
threshold.  There's no point in relogging an intent into the same
checkpoint, and there's no need to relog if there's plenty of free space
in the log.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_trans.h
libxfs/xfs_defer.c

index d3683441894de76397c4973e2c566e266e3ccb1c..f51e38afdaabc1881e046838758b8376550e00cd 100644 (file)
@@ -151,4 +151,26 @@ libxfs_trans_read_buf(
 #define xfs_log_item_in_current_chkpt(lip)     (false)
 #define xfs_trans_item_relog(lip, tp)          (NULL)
 
+/* Contorted mess to make gcc shut up about unused vars. */
+#define xlog_grant_push_threshold(log, need)    \
+               ((log) == (log) ? NULLCOMMITLSN : NULLCOMMITLSN)
+
+/* from xfs_log.h */
+/*
+ * By comparing each component, we don't have to worry about extra
+ * endian issues in treating two 32 bit numbers as one 64 bit number
+ */
+static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
+{
+       if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
+               return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
+
+       if (BLOCK_LSN(lsn1) != BLOCK_LSN(lsn2))
+               return (BLOCK_LSN(lsn1)<BLOCK_LSN(lsn2))? -999 : 999;
+
+       return 0;
+}
+
+#define XFS_LSN_CMP(a, b)                      _lsn_cmp(a, b)
+
 #endif /* __XFS_TRANS_H__ */
index abee6d4260e262d418302126c586b54d6027f1f0..1fdf6c7203577326f2c099550b5cfdaf9b70b8ec 100644 (file)
@@ -352,7 +352,10 @@ xfs_defer_relog(
        struct xfs_trans                **tpp,
        struct list_head                *dfops)
 {
+       struct xlog                     *log = (*tpp)->t_mountp->m_log;
        struct xfs_defer_pending        *dfp;
+       xfs_lsn_t                       threshold_lsn = NULLCOMMITLSN;
+
 
        ASSERT((*tpp)->t_flags & XFS_TRANS_PERM_LOG_RES);
 
@@ -368,6 +371,19 @@ xfs_defer_relog(
                    xfs_log_item_in_current_chkpt(dfp->dfp_intent))
                        continue;
 
+               /*
+                * Figure out where we need the tail to be in order to maintain
+                * the minimum required free space in the log.  Only sample
+                * the log threshold once per call.
+                */
+               if (threshold_lsn == NULLCOMMITLSN) {
+                       threshold_lsn = xlog_grant_push_threshold(log, 0);
+                       if (threshold_lsn == NULLCOMMITLSN)
+                               break;
+               }
+               if (XFS_LSN_CMP(dfp->dfp_intent->li_lsn, threshold_lsn) >= 0)
+                       continue;
+
                trace_xfs_defer_relog_intent((*tpp)->t_mountp, dfp);
                XFS_STATS_INC((*tpp)->t_mountp, defer_relog);
                dfp->dfp_intent = xfs_trans_item_relog(dfp->dfp_intent, *tpp);