[PATCH 46/50] xfs: Combine CIL insert and prepare passes

Mark Tinguely tinguely at sgi.com
Tue Aug 13 09:02:06 CDT 2013


On 08/12/13 05:50, Dave Chinner wrote:
> From: Dave Chinner<dchinner at redhat.com>
>
> Now that all the log item preparation and formatting is done under
> the CIL lock, we can get rid of the intermediate log vector chain
> used to track items to be inserted into the CIL.
>
> We can already find all the items to be committed from the
> transaction handle, so as long as we attach the log vectors to the
> item before we insert the items into the CIL, we don't need to
> create a log vector chain to pass around.
>
> This means we can move all the item insertion code into and optimise
> it into a pair of simple passes across all the items in the
> transaction. The first pass does the formatting and accounting, the
> second inserts them all into the CIL.
>
> We keep this two pass split so that we can separate the CIL
> insertion - which must be done under the CIL spinlock - from the
> formatting. We could insert each item into the CIL with a single
> pass, but that massively increases the number of times we have to
> grab the CIL spinlock. It is much more efficient (and hence
> scalable) to do a batch operation and insert all objects in a single
> lock grab.
>
> Signed-off-by: Dave Chinner<dchinner at redhat.com>
> ---
>   fs/xfs/xfs_log_cil.c | 227 +++++++++++++++++++++++----------------------------
>   1 file changed, 100 insertions(+), 127 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
> index b20b157..c1a3384 100644
> --- a/fs/xfs/xfs_log_cil.c
> +++ b/fs/xfs/xfs_log_cil.c
> @@ -111,6 +111,53 @@ xlog_cil_lv_item_format(
>   }
>
>   /*
> + * Prepare the log item for insertion into the CIL. Calculate the difference in
> + * log space and vectors it will consume, and if it is a new item pin it as
> + * well.
> + */
> +STATIC void
> +xfs_cil_prepare_item(
> +	struct xlog		*log,
> +	struct xfs_log_vec	*lv,
> +	struct xfs_log_vec	*old_lv,
> +	int			*diff_len,
> +	int			*diff_iovecs)
> +{
> +	/* Account for the new LV being passed in */
> +	if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) {
> +		*diff_len += lv->lv_buf_len;
> +		*diff_iovecs += lv->lv_niovecs;
> +	}
> +
> +	/*
> +	 * If there is no old LV, this is the first time we've seen the item in
> +	 * this CIL context and so we need to pin it. If we are replacing the
> +	 * old_lv, then remove the space it accounts for and free it.
> +	 */
> +	if (!old_lv)
> +		lv->lv_item->li_ops->iop_pin(lv->lv_item);
> +	else if (old_lv != lv) {
> +		ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED);

This should never happen, but I liked the original if .. then here
as well as the assert...

> +
> +		*diff_len -= old_lv->lv_buf_len;
> +		*diff_iovecs -= old_lv->lv_niovecs;
> +		kmem_free(old_lv);
> +	}

... but not enough to make you repost.

Unless someone else has strong opinions, the CIL lock series (patches 
43-47) have been reviewed and tested.

Reviewed-by: Mark Tinguely <tinguely at sgi.com>



More information about the xfs mailing list