xfs: don't do memory allocation under the CIL context lock
Formatting items requires memory allocation when using delayed logging. Currently that memory allocation is done while holding the CIL context lock in read mode. This means that if memory allocation takes some time (e.g. enters reclaim), we cannot push on the CIL until the allocation(s) required by formatting complete. This can stall CIL pushes for some time, and once a push is stalled so are all new transaction commits. Fix this splitting the item formatting into two steps. The first step which does the allocation and memcpy() into the allocated buffer is now done outside the CIL context lock, and only the CIL insert is done inside the CIL context lock. This avoids the stall issue. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
a44f13edf0
commit
3b93c7aaef
|
@ -270,15 +270,10 @@ xlog_cil_insert(
|
|||
static void
|
||||
xlog_cil_format_items(
|
||||
struct log *log,
|
||||
struct xfs_log_vec *log_vector,
|
||||
struct xlog_ticket *ticket,
|
||||
xfs_lsn_t *start_lsn)
|
||||
struct xfs_log_vec *log_vector)
|
||||
{
|
||||
struct xfs_log_vec *lv;
|
||||
|
||||
if (start_lsn)
|
||||
*start_lsn = log->l_cilp->xc_ctx->sequence;
|
||||
|
||||
ASSERT(log_vector);
|
||||
for (lv = log_vector; lv; lv = lv->lv_next) {
|
||||
void *ptr;
|
||||
|
@ -302,11 +297,26 @@ xlog_cil_format_items(
|
|||
ptr += vec->i_len;
|
||||
}
|
||||
ASSERT(ptr == lv->lv_buf + lv->lv_buf_len);
|
||||
|
||||
xlog_cil_insert(log, ticket, lv->lv_item, lv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xlog_cil_insert_items(
|
||||
struct log *log,
|
||||
struct xfs_log_vec *log_vector,
|
||||
struct xlog_ticket *ticket,
|
||||
xfs_lsn_t *start_lsn)
|
||||
{
|
||||
struct xfs_log_vec *lv;
|
||||
|
||||
if (start_lsn)
|
||||
*start_lsn = log->l_cilp->xc_ctx->sequence;
|
||||
|
||||
ASSERT(log_vector);
|
||||
for (lv = log_vector; lv; lv = lv->lv_next)
|
||||
xlog_cil_insert(log, ticket, lv->lv_item, lv);
|
||||
}
|
||||
|
||||
static void
|
||||
xlog_cil_free_logvec(
|
||||
struct xfs_log_vec *log_vector)
|
||||
|
@ -612,9 +622,17 @@ xfs_log_commit_cil(
|
|||
return XFS_ERROR(EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* do all the hard work of formatting items (including memory
|
||||
* allocation) outside the CIL context lock. This prevents stalling CIL
|
||||
* pushes when we are low on memory and a transaction commit spends a
|
||||
* lot of time in memory reclaim.
|
||||
*/
|
||||
xlog_cil_format_items(log, log_vector);
|
||||
|
||||
/* lock out background commit */
|
||||
down_read(&log->l_cilp->xc_ctx_lock);
|
||||
xlog_cil_format_items(log, log_vector, tp->t_ticket, commit_lsn);
|
||||
xlog_cil_insert_items(log, log_vector, tp->t_ticket, commit_lsn);
|
||||
|
||||
/* check we didn't blow the reservation */
|
||||
if (tp->t_ticket->t_curr_res < 0)
|
||||
|
|
Loading…
Reference in New Issue