xfs: expose the log push threshold

Separate the computation of the log push threshold and the push logic in
xlog_grant_push_ail.  This enables higher level code to determine (for
example) that it is holding on to a logged intent item and the log is so
busy that it is more than 75% full.  In that case, it would be desirable
to move the log item towards the head to release the tail, which we will
cover in the next patch.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
Darrick J. Wong 2020-09-25 17:39:51 -07:00
parent 4e919af782
commit ed1575daf7
2 changed files with 32 additions and 10 deletions

View File

@ -1475,14 +1475,14 @@ xlog_commit_record(
} }
/* /*
* Push on the buffer cache code if we ever use more than 75% of the on-disk * Compute the LSN that we'd need to push the log tail towards in order to have
* log space. This code pushes on the lsn which would supposedly free up * (a) enough on-disk log space to log the number of bytes specified, (b) at
* the 25% which we want to leave free. We may need to adopt a policy which * least 25% of the log space free, and (c) at least 256 blocks free. If the
* pushes on an lsn which is further along in the log once we reach the high * log free space already meets all three thresholds, this function returns
* water mark. In this manner, we would be creating a low water mark. * NULLCOMMITLSN.
*/ */
STATIC void xfs_lsn_t
xlog_grant_push_ail( xlog_grant_push_threshold(
struct xlog *log, struct xlog *log,
int need_bytes) int need_bytes)
{ {
@ -1508,7 +1508,7 @@ xlog_grant_push_ail(
free_threshold = max(free_threshold, (log->l_logBBsize >> 2)); free_threshold = max(free_threshold, (log->l_logBBsize >> 2));
free_threshold = max(free_threshold, 256); free_threshold = max(free_threshold, 256);
if (free_blocks >= free_threshold) if (free_blocks >= free_threshold)
return; return NULLCOMMITLSN;
xlog_crack_atomic_lsn(&log->l_tail_lsn, &threshold_cycle, xlog_crack_atomic_lsn(&log->l_tail_lsn, &threshold_cycle,
&threshold_block); &threshold_block);
@ -1528,13 +1528,33 @@ xlog_grant_push_ail(
if (XFS_LSN_CMP(threshold_lsn, last_sync_lsn) > 0) if (XFS_LSN_CMP(threshold_lsn, last_sync_lsn) > 0)
threshold_lsn = last_sync_lsn; threshold_lsn = last_sync_lsn;
return threshold_lsn;
}
/*
* Push the tail of the log if we need to do so to maintain the free log space
* thresholds set out by xlog_grant_push_threshold. We may need to adopt a
* policy which pushes on an lsn which is further along in the log once we
* reach the high water mark. In this manner, we would be creating a low water
* mark.
*/
STATIC void
xlog_grant_push_ail(
struct xlog *log,
int need_bytes)
{
xfs_lsn_t threshold_lsn;
threshold_lsn = xlog_grant_push_threshold(log, need_bytes);
if (threshold_lsn == NULLCOMMITLSN || XLOG_FORCED_SHUTDOWN(log))
return;
/* /*
* Get the transaction layer to kick the dirty buffers out to * Get the transaction layer to kick the dirty buffers out to
* disk asynchronously. No point in trying to do this if * disk asynchronously. No point in trying to do this if
* the filesystem is shutting down. * the filesystem is shutting down.
*/ */
if (!XLOG_FORCED_SHUTDOWN(log)) xfs_ail_push(log->l_ailp, threshold_lsn);
xfs_ail_push(log->l_ailp, threshold_lsn);
} }
/* /*

View File

@ -141,4 +141,6 @@ void xfs_log_quiesce(struct xfs_mount *mp);
bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
bool xfs_log_in_recovery(struct xfs_mount *); bool xfs_log_in_recovery(struct xfs_mount *);
xfs_lsn_t xlog_grant_push_threshold(struct xlog *log, int need_bytes);
#endif /* __XFS_LOG_H__ */ #endif /* __XFS_LOG_H__ */