diff mbox series

[19/21] xfs: only relog deferred intent items if free space in the log gets low

Message ID 160375553723.882906.12560590143941032565.stgit@magnolia
State Accepted
Headers show
Series xfsprogs: sync with 5.10, part 2 | expand

Commit Message

Darrick J. Wong Oct. 26, 2020, 11:38 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

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: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfs_trans.h |   20 ++++++++++++++++++++
 libxfs/xfs_defer.c  |   16 ++++++++++++++++
 2 files changed, 36 insertions(+)
diff mbox series

Patch

diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index 1784b8b64cf8..a409757420e4 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -151,4 +151,24 @@  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. */
+#define xlog_grant_push_threshold(log, need)	\
+		((log) == (log) ? NULLCOMMITLSN : NULLCOMMITLSN)
+
+/*
+ * 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__ */
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index abee6d4260e2..1fdf6c720357 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -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);