[Devel] [RFC PATCH vz9 v6 40/62] dm-ploop: make ploop_bat_write_complete ready for parallel pio completion

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Jan 17 11:09:42 MSK 2025


> --- a/drivers/md/dm-ploop-map.c
> +++ b/drivers/md/dm-ploop-map.c
> @@ -893,35 +893,47 @@ static void ploop_bat_write_complete(struct pio *pio, void *piwb_ptr,
>   	struct ploop_cow *cow;
>   	struct pio *data_pio;
>   	unsigned long flags;
> -
> -	if (!bi_status) {
> -		/*
> -		 * Success: now update local BAT copy. We could do this
> -		 * from our delayed work, but we want to publish new
> -		 * mapping in the fastest way. This must be done before
> -		 * data bios completion, since right after we complete
> -		 * a bio, subsequent read wants to see written data
> -		 * (ploop_map() wants to see not zero bat_entries[.]).
> -		 */
> -		ploop_advance_local_after_bat_wb(ploop, piwb, true);
> +	LIST_HEAD(lready_pios);
> +	LIST_HEAD(lcow_pios);
> +	int completed = atomic_read(&piwb->count) == 1;

Maybe we can use this construct:

if (atomic_dec_and_test(&piwb->count)) {do}

> +
> +	if (completed) {
> +		/* We are the last count so it is safe to advance bat */
> +		if (!bi_status) {
> +			/*
> +			 * Success: now update local BAT copy. We could do this
> +			 * from our delayed work, but we want to publish new
> +			 * mapping in the fastest way. This must be done before
> +			 * data bios completion, since right after we complete
> +			 * a bio, subsequent read wants to see written data
> +			 * (ploop_map() wants to see not zero bat_entries[.]).
> +			 */
> +			ploop_advance_local_after_bat_wb(ploop, piwb, true);
> +		}
>   	}
>   
>   	spin_lock_irqsave(&piwb->lock, flags);
> -	piwb->completed = true;
> +	if (completed)
> +		piwb->completed = completed;
>   	piwb->bi_status = bi_status;
> +	list_splice_init(&piwb->ready_data_pios, &lready_pios);
>   	spin_unlock_irqrestore(&piwb->lock, flags);
>   
> +	spin_lock_irqsave(&ploop->deferred_lock, flags);
> +	list_splice_init(&piwb->cow_list, &lcow_pios);
> +	spin_unlock_irqrestore(&ploop->deferred_lock, flags);
> +
>   	/*
> -	 * End pending data bios. Unlocked, as nobody can
> -	 * add a new element after piwc->completed is true.
> +	 * End pending data bios.
>   	 */
> -	while ((data_pio = ploop_pio_list_pop(&piwb->ready_data_pios)) != NULL) {
> +
> +	while ((data_pio = ploop_pio_list_pop(&lready_pios)) != NULL) {
>   		if (bi_status)
>   			data_pio->bi_status = bi_status;
>   		ploop_pio_endio(data_pio);
>   	}
>   
> -	while ((aux_pio = ploop_pio_list_pop(&piwb->cow_list))) {
> +	while ((aux_pio = ploop_pio_list_pop(&lcow_pios))) {
>   		cow = aux_pio->endio_cb_data;
>   		ploop_complete_cow(cow, bi_status);
>   	}

-- 
Best regards, Tikhomirov Pavel
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list