All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
To: Ming Lei <ming.lei@redhat.com>
Cc: dm-devel@redhat.com, Damien Le Moal <damien.lemoal@wdc.com>,
	Mike Snitzer <snitzer@redhat.com>
Subject: Re: [dm-devel] [PATCH 1/3] dm: don't grab target io reference in dm_zone_map_bio
Date: Tue, 12 Apr 2022 08:33:04 +0900	[thread overview]
Message-ID: <869a7210-a0f0-4aae-3e90-cdfe30a72434@opensource.wdc.com> (raw)
In-Reply-To: <YlQ4na/HwBSm5C3U@T590>

On 4/11/22 23:18, Ming Lei wrote:
>>>> This fixes the issue:
>>>>
>>>> diff --git a/drivers/md/dm.c b/drivers/md/dm.c
>>>> index 3c5fad7c4ee6..3dd6735450c5 100644
>>>> --- a/drivers/md/dm.c
>>>> +++ b/drivers/md/dm.c
>>>> @@ -581,7 +581,7 @@ static struct dm_io *alloc_io(struct mapped_device
>>>> *md, struct bio *bio)
>>>>         io->status = 0;
>>>>         atomic_set(&io->io_count, 1);
>>>>         this_cpu_inc(*md->pending_io);
>>>> -       io->orig_bio = NULL;
>>>> +       io->orig_bio = bio;
>>>>         io->md = md;
>>>>         io->map_task = current;
>>>>         spin_lock_init(&io->lock);
>>>>
>>>> Otherwise, the dm-zone.c code sees a NULL orig_bio.
>>>> However, this change may be messing up the bio accounting. Need to check that.
>>>
>>> Looks it is one recent regression since:
>>>
>>> commit 0fbb4d93b38b ("dm: add dm_submit_bio_remap interface")
>>
>> Yep, saw that. Problem is, I really do not understand that change setting
>> io->orig_bio *after* __map_bio() is called. It seems that the accounting
>> is done on each fragment of the orig_bio instead of once for the entire
>> BIO... So my "fix" above seems wrong. Apart from passing along orig_bio as
>> an argument to  __map_bio() from __split_and_process_bio(), I do not think
>> my change is correct. Thoughts ?
> 
> Frankly speaking, both changing ->orig_bio after split and setting ->orig_bio
> after ->map() looks ugly & tricky, and the following change should avoid the
> issue, meantime simplify dm accounting a bit:
> 
> diff --git a/drivers/md/dm.c b/drivers/md/dm.c
> index 3c5fad7c4ee6..f1fe83113608 100644
> --- a/drivers/md/dm.c
> +++ b/drivers/md/dm.c
> @@ -581,7 +581,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
>  	io->status = 0;
>  	atomic_set(&io->io_count, 1);
>  	this_cpu_inc(*md->pending_io);
> -	io->orig_bio = NULL;
> +	io->orig_bio = bio;
>  	io->md = md;
>  	io->map_task = current;
>  	spin_lock_init(&io->lock);
> @@ -1223,19 +1223,11 @@ void dm_submit_bio_remap(struct bio *clone, struct bio *tgt_clone)
>  	 * Account io->origin_bio to DM dev on behalf of target
>  	 * that took ownership of IO with DM_MAPIO_SUBMITTED.
>  	 */
> -	if (io->map_task == current) {
> +	if (io->map_task == current)
>  		/* Still in target's map function */
>  		dm_io_set_flag(io, DM_IO_START_ACCT);
> -	} else {
> -		/*
> -		 * Called by another thread, managed by DM target,
> -		 * wait for dm_split_and_process_bio() to store
> -		 * io->orig_bio
> -		 */
> -		while (unlikely(!smp_load_acquire(&io->orig_bio)))
> -			msleep(1);
> +	else

Curly brackets around the else here.

>  		dm_start_io_acct(io, clone);
> -	}
>  
>  	__dm_submit_bio_remap(tgt_clone, disk_devt(io->md->disk),
>  			      tio->old_sector);
> @@ -1562,7 +1554,7 @@ static void dm_split_and_process_bio(struct mapped_device *md,
>  				     struct dm_table *map, struct bio *bio)
>  {
>  	struct clone_info ci;
> -	struct bio *orig_bio = NULL;
> +	struct bio *new_bio = NULL;
>  	int error = 0;
>  
>  	init_clone_info(&ci, md, map, bio);
> @@ -1578,22 +1570,14 @@ static void dm_split_and_process_bio(struct mapped_device *md,
>  	if (error || !ci.sector_count)
>  		goto out;
>  
> -	/*
> -	 * Remainder must be passed to submit_bio_noacct() so it gets handled
> -	 * *after* bios already submitted have been completely processed.
> -	 * We take a clone of the original to store in ci.io->orig_bio to be
> -	 * used by dm_end_io_acct() and for dm_io_complete() to use for
> -	 * completion handling.
> -	 */

This comment should remain with some adjustment.

> -	orig_bio = bio_split(bio, bio_sectors(bio) - ci.sector_count,
> -			     GFP_NOIO, &md->queue->bio_split);
> -	bio_chain(orig_bio, bio);
> -	trace_block_split(orig_bio, bio->bi_iter.bi_sector);
> -	submit_bio_noacct(bio);
> +	new_bio = bio_alloc_clone(bio->bi_bdev, bio, GFP_NOIO,
> +			&md->queue->bio_split);

Why not keep using bio_split() ?

> +	bio_trim(new_bio, bio_sectors(bio) - ci.sector_count, ci.sector_count);
> +	bio_trim(bio, 0, bio_sectors(bio) - ci.sector_count);
> +	bio_chain(new_bio, bio);
> +	trace_block_split(new_bio, new_bio->bi_iter.bi_sector);
> +	submit_bio_noacct(new_bio);
>  out:
> -	if (!orig_bio)
> -		orig_bio = bio;
> -	smp_store_release(&ci.io->orig_bio, orig_bio);
>  	if (dm_io_flagged(ci.io, DM_IO_START_ACCT))
>  		dm_start_io_acct(ci.io, NULL);

I tested this and it works. Need to check the accounting though.
And I agree this is a lot cleaner :)

-- 
Damien Le Moal
Western Digital Research

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


  reply	other threads:[~2022-04-11 23:33 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-08 17:12 [dm-devel] [PATCH 0/3] dm: improvement on io referencing and io poll Ming Lei
2022-04-08 17:12 ` [dm-devel] [PATCH 1/3] dm: don't grab target io reference in dm_zone_map_bio Ming Lei
2022-04-11  0:18   ` Damien Le Moal
2022-04-11  0:36     ` Ming Lei
2022-04-11  0:50       ` Damien Le Moal
2022-04-11  1:04         ` Ming Lei
2022-04-11  1:08           ` Damien Le Moal
2022-04-11  2:19           ` Damien Le Moal
2022-04-11  2:55             ` Damien Le Moal
2022-04-11  3:10               ` Damien Le Moal
2022-04-11  7:34               ` Ming Lei
2022-04-11  7:42                 ` Damien Le Moal
2022-04-11 14:18                   ` Ming Lei
2022-04-11 23:33                     ` Damien Le Moal [this message]
2022-04-12  0:09                       ` Ming Lei
2022-04-12  0:28                         ` Damien Le Moal
2022-04-12  1:02                           ` Ming Lei
2022-04-12  1:17                             ` Damien Le Moal
2022-04-11  9:40   ` Damien Le Moal
2022-04-08 17:12 ` [dm-devel] [PATCH 2/3] dm: improve target io referencing Ming Lei
2022-04-08 17:12 ` [dm-devel] [PATCH 3/3] dm: put all polled io into one single list Ming Lei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=869a7210-a0f0-4aae-3e90-cdfe30a72434@opensource.wdc.com \
    --to=damien.lemoal@opensource.wdc.com \
    --cc=damien.lemoal@wdc.com \
    --cc=dm-devel@redhat.com \
    --cc=ming.lei@redhat.com \
    --cc=snitzer@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.