summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log_cil.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2022-07-07 18:56:08 +1000
committerDave Chinner <david@fromorbit.com>2022-07-07 18:56:08 +1000
commit4eb56069cb2835fafe569e27e746e6a4c9735186 (patch)
tree03a3e764b3ceca81df2fb0994618eb2b1aabf97d /fs/xfs/xfs_log_cil.c
parent169248536a2b28e4228ba63772936c1ba979c9c0 (diff)
xfs: move CIL ordering to the logvec chain
Adding a list_sort() call to the CIL push work while the xc_ctx_lock is held exclusively has resulted in fairly long lock hold times and that stops all front end transaction commits from making progress. We can move the sorting out of the xc_ctx_lock if we can transfer the ordering information to the log vectors as they are detached from the log items and then we can sort the log vectors. With these changes, we can move the list_sort() call to just before we call xlog_write() when we aren't holding any locks at all. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r--fs/xfs/xfs_log_cil.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 0e69e855d710..8bb251d2b4d3 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -1095,10 +1095,10 @@ xlog_cil_order_cmp(
const struct list_head *a,
const struct list_head *b)
{
- struct xfs_log_item *l1 = container_of(a, struct xfs_log_item, li_cil);
- struct xfs_log_item *l2 = container_of(b, struct xfs_log_item, li_cil);
+ struct xfs_log_vec *l1 = container_of(a, struct xfs_log_vec, lv_list);
+ struct xfs_log_vec *l2 = container_of(b, struct xfs_log_vec, lv_list);
- return l1->li_order_id > l2->li_order_id;
+ return l1->lv_order_id > l2->lv_order_id;
}
/*
@@ -1117,8 +1117,6 @@ xlog_cil_build_lv_chain(
uint32_t *num_iovecs,
uint32_t *num_bytes)
{
- list_sort(NULL, &ctx->log_items, xlog_cil_order_cmp);
-
while (!list_empty(&ctx->log_items)) {
struct xfs_log_item *item;
struct xfs_log_vec *lv;
@@ -1133,6 +1131,7 @@ xlog_cil_build_lv_chain(
}
lv = item->li_lv;
+ lv->lv_order_id = item->li_order_id;
/* we don't write ordered log vectors */
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
@@ -1293,6 +1292,13 @@ xlog_cil_push_work(
up_write(&cil->xc_ctx_lock);
/*
+ * Sort the log vector chain before we add the transaction headers.
+ * This ensures we always have the transaction headers at the start
+ * of the chain.
+ */
+ list_sort(NULL, &ctx->lv_chain, xlog_cil_order_cmp);
+
+ /*
* Build a checkpoint transaction header and write it to the log to
* begin the transaction. We need to account for the space used by the
* transaction header here as it is not accounted for in xlog_write().