Skip to content

Commit 4eb5606

Browse files
dgchinnerdchinner
authored andcommitted
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>
1 parent 1692485 commit 4eb5606

2 files changed

Lines changed: 12 additions & 5 deletions

File tree

fs/xfs/xfs_log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct xfs_cil_ctx;
1010

1111
struct xfs_log_vec {
1212
struct list_head lv_list; /* CIL lv chain ptrs */
13+
uint32_t lv_order_id; /* chain ordering info */
1314
int lv_niovecs; /* number of iovecs in lv */
1415
struct xfs_log_iovec *lv_iovecp; /* iovec array */
1516
struct xfs_log_item *lv_item; /* owner */

fs/xfs/xfs_log_cil.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,10 +1095,10 @@ xlog_cil_order_cmp(
10951095
const struct list_head *a,
10961096
const struct list_head *b)
10971097
{
1098-
struct xfs_log_item *l1 = container_of(a, struct xfs_log_item, li_cil);
1099-
struct xfs_log_item *l2 = container_of(b, struct xfs_log_item, li_cil);
1098+
struct xfs_log_vec *l1 = container_of(a, struct xfs_log_vec, lv_list);
1099+
struct xfs_log_vec *l2 = container_of(b, struct xfs_log_vec, lv_list);
11001100

1101-
return l1->li_order_id > l2->li_order_id;
1101+
return l1->lv_order_id > l2->lv_order_id;
11021102
}
11031103

11041104
/*
@@ -1117,8 +1117,6 @@ xlog_cil_build_lv_chain(
11171117
uint32_t *num_iovecs,
11181118
uint32_t *num_bytes)
11191119
{
1120-
list_sort(NULL, &ctx->log_items, xlog_cil_order_cmp);
1121-
11221120
while (!list_empty(&ctx->log_items)) {
11231121
struct xfs_log_item *item;
11241122
struct xfs_log_vec *lv;
@@ -1133,6 +1131,7 @@ xlog_cil_build_lv_chain(
11331131
}
11341132

11351133
lv = item->li_lv;
1134+
lv->lv_order_id = item->li_order_id;
11361135

11371136
/* we don't write ordered log vectors */
11381137
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
@@ -1292,6 +1291,13 @@ xlog_cil_push_work(
12921291
spin_unlock(&cil->xc_push_lock);
12931292
up_write(&cil->xc_ctx_lock);
12941293

1294+
/*
1295+
* Sort the log vector chain before we add the transaction headers.
1296+
* This ensures we always have the transaction headers at the start
1297+
* of the chain.
1298+
*/
1299+
list_sort(NULL, &ctx->lv_chain, xlog_cil_order_cmp);
1300+
12951301
/*
12961302
* Build a checkpoint transaction header and write it to the log to
12971303
* begin the transaction. We need to account for the space used by the

0 commit comments

Comments
 (0)