From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> 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@xxxxxxxxxx> Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- include/xfs_trans.h | 20 ++++++++++++++++++++ libxfs/xfs_defer.c | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) 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);