Re: [dm-devel] dm: use cloned bio as head, not remainder, in __split_and_process_bio()

NeilBrown
2017-11-28T22:18:23Z

[-- Attachment #1: Type: text/plain, Size: 1802 bytes --]

On Mon, Nov 27 2017, Mike Snitzer wrote:

> On Thu, Nov 23 2017 at 5:52pm -0500,
> NeilBrown <neilb@suse.com> wrote:
>
>>
>> When we use bio_clone_bioset() to split off the front part of a bio
>> and chain the two together and submit the remainder to
>> generic_make_request(), it is important that the newly allocated
>> bio is used as the head to be processed immediately, and the original
>> bio gets "bio_advance()"d and sent to generic_make_request() as the
>> remainder.
>>
>> If the newly allocated bio is used as the remainder, and if it then
>> needs to be split again, then the next bio_clone_bioset() call will
>> be made while holding a reference a bio (result of the first clone)
>> from the same bioset. This can potentially exhaust the bioset mempool
>> and result in a memory allocation deadlock.
>>
>> So the result of the bio_clone_bioset() must be attached to the new
>> dm_io struct, and the original must be resubmitted. The current code
>> is backwards.
>>
>> Note that there is no race caused by reassigning cio.io->bio after already
>> calling __map_bio(). This bio will only be dereferenced again after
>> dec_pending() has found io->io_count to be zero, and this cannot happen
>> before the dec_pending() call at the end of __split_and_process_bio().
>>
>> Reported-by: Mikulas Patocka <mpatocka@redhat.com>
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>
>> Hi,
>> I think this should resolve the problem Mikulas noticed that the
>> bios form a deep chain instead of a wide tree.
>
> I'm inclined to just fold this into the original commit.
> I'd update that header to make mention of the details captured in this
> header.
>
> Would you be OK with that?

Perfectly OK with that. Thanks for asking.

NeilBrown

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]