All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Marzinski <bmarzins@redhat.com>
To: Martin Wilck <Martin.Wilck@suse.com>
Cc: "dm-devel@redhat.com" <dm-devel@redhat.com>
Subject: Re: [PATCH 0/7] Fix muitpath/multipathd flush issue
Date: Thu, 18 Jun 2020 13:04:58 -0500	[thread overview]
Message-ID: <20200618180458.GI5894@octiron.msp.redhat.com> (raw)
In-Reply-To: <f60b8ea30ee0ce68a46ce8f5c9ebaee6314d57e4.camel@suse.com>

On Thu, Jun 18, 2020 at 09:00:49AM +0000, Martin Wilck wrote:
> On Wed, 2020-06-17 at 19:24 -0500, Benjamin Marzinski wrote:
> > 
> > One source of complexity in these patches is that multipath suspends
> > the
> > device with flushing before removing it, while multipathd
> > doesn't.  It
> > does seem possible that the suspend could hang for a while, so I can
> > understand multipathd not using it.  However, that would take the
> > multipath device getting opened and IO being issued, between the time
> > when _dm_flush_map() verifies that the device isn't opened, and when
> > it
> > suspends the device.  But more importantly, I don't understand how
> > suspending the device is useful.  
> 
> I've looked up the origin of 9a4ff93 in SUSE bugzilla. The problem that
> the patch tried to solve was that if map without healthy paths and with
> queue_if_no_path set was removed, the removal might fail with 
> "map is in use".  Hannes' comment at the time was this:
> 
>  "Problem is that we're not waiting for all outstanding I/Os to
>  complete. So the check for 'map in use' might trigger a false
>  positive, as the outstanding I/O will keep the map busy. Once it's
>  finished we can remove the map."
> 
>  "I'll add an explicit 'suspend/resume' cycle here, which will wait for
>  all outstanding I/O to finish. That should resolve the situation."
> 
> Thus setting queue_if_no_paths = 0 and doing a suspend/resume was
> basically a trick to force dm to flush outstanding IO.

I get the intention, I just don't think it currently is doing anything.

> > If the device were to be opened
> > between when _dm_flush_map() checks the usage, and when it tries to
> > delete the device, device-mapper would simply fail the remove.  And
> > if
> > the device isn't in use, there can't be any outstanding IO to flush.
> > When this code was added in commit 9a4ff93, there was no check if the
> > device was in use,
> 
> Hm, I see this in the code preceding 9a4ff93:
> 
> extern int
> _dm_flush_map (const char * mapname, int need_sync)
> {
> [...]
>         if (dm_get_opencount(mapname)) {
>                 condlog(2, "%s: map in use", mapname);
>                 return 1;
>         }
> 
> ... so it seems that there was a check, even back then.

oops. I missed that. 

> >  and disabling queue_if_no_path could cause anything
> > that had the device open to error out and close it. But now that
> > multipath checks first if the device is open, I don't see the benefit
> > to
> > doing this anymore. Removing it would allow multipathd and multipath
> > to
> > use the same code to remove maps. Any thoughts?
> 
> With queue_if_no_paths, there could be outstanding IO even if the
> opencount was 0.

This is what I don't accept at face value. I wrote a little test
program that fired off an async read, closed the fd without waiting for
a response, and then tried to exit.  running this on a queueing
multipath device causes the exit to hang like this

 cat /proc/22655/task/22655/stack
[<0>] exit_aio+0xdc/0xf0
[<0>] mmput+0x33/0x130
[<0>] do_exit+0x27f/0xb30
[<0>] do_group_exit+0x3a/0xa0
[<0>] __x64_sys_exit_group+0x14/0x20
[<0>] do_syscall_64+0x5b/0x160
[<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[<0>] 0xffffffffffffffff

and the multipath device to remain in use

# dmsetup info mpathb
Name:              mpathb
State:             ACTIVE
Read Ahead:        256
Tables present:    LIVE
Open count:        0
Event number:      7
Major, minor:      253, 5
Number of targets: 1
UUID: mpath-3600d0230000000000e13954ed5f89301

I've asked around, and device-mapper is certainly supposed to flush all
IO before the last close. Of course, there may be a corner case where it
doesn't. If you know of one, that would be worth sharing.

What I think that flush previously accomplished is that, just like the
flush_on_last_del code, if you stop queueing and error out the IO, then
whatever is waiting on it will get those errors, and likely close the
device soon after, hopefully in time for multipath to remove the device.

However, since multipath now checks if the device is in use before
disabling queue_if_no_path, it don't think this code is actually helpful
right now.

> This IO must be flushed somehow before the map can be
> removed. Apparently just setting queue_if_no_path = 0 was not enough,
> that's why Hannes added the suspend/resume. Maybe today we have some
> better way to force the flush? libdm has the _error_device() function 
> (aka dmsetup wipe_table) that replaces the map's table by the error
> target. But this does a map reload, which implies a suspend, too.
> Perhaps simply an fsync() on the dm device, or just wait a while until
> all outstanding IO has errored out? But these alternatives don't
> actually look better to me than Hannes' suspend/resume, they will take
> at least as much time. Do you have a better idea?

To go back to the old behavior, we would need to move the check if the
device is in use until after we suspended the device. Or we can keep the
current behavior, and simply remove the flushing and suspending.

> multipathd 
> 
> Regards
> Martin
> 
> -- 
> Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> SUSE  Software Solutions Germany GmbH
> HRB 36809, AG Nürnberg GF: Felix
> Imendörffer
> 

  reply	other threads:[~2020-06-18 18:04 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-18  0:24 [PATCH 0/7] Fix muitpath/multipathd flush issue Benjamin Marzinski
2020-06-18  0:24 ` [PATCH 1/7] libmultipath: change do_get_info returns Benjamin Marzinski
2020-06-18 15:27   ` Martin Wilck
2020-06-18 23:17     ` Benjamin Marzinski
2020-06-18  0:24 ` [PATCH 2/7] multipathd: fix check_path errors with removed map Benjamin Marzinski
2020-06-18 19:34   ` Martin Wilck
2020-06-18 23:17     ` Benjamin Marzinski
2020-06-19  6:32       ` Hannes Reinecke
2020-06-19 16:30         ` Benjamin Marzinski
2020-06-19 20:03           ` Martin Wilck
2020-06-19 13:42       ` Martin Wilck
2020-06-19 16:52         ` Benjamin Marzinski
2020-06-19 20:09           ` Martin Wilck
2020-06-18  0:24 ` [PATCH 3/7] libmultipath: make dm_flush_maps only return 0 on success Benjamin Marzinski
2020-06-18 20:29   ` Martin Wilck
2020-06-18  0:24 ` [PATCH 4/7] multipathd: add "del maps" multipathd command Benjamin Marzinski
2020-06-18 20:37   ` Martin Wilck
2020-06-18 23:12     ` Benjamin Marzinski
2020-06-19 13:35       ` Martin Wilck
2020-06-18  0:24 ` [PATCH 5/7] multipath: make flushing maps work like other commands Benjamin Marzinski
2020-06-18 20:38   ` Martin Wilck
2020-06-18  0:24 ` [PATCH 6/7] multipath: delegate flushing maps to multipathd Benjamin Marzinski
2020-06-18 20:40   ` Martin Wilck
2020-06-18  0:24 ` [PATCH 7/7] multipath: add option to skip multipathd delegation Benjamin Marzinski
2020-06-18 20:44   ` Martin Wilck
2020-06-18 23:15     ` Benjamin Marzinski
2020-06-18  9:00 ` [PATCH 0/7] Fix muitpath/multipathd flush issue Martin Wilck
2020-06-18 18:04   ` Benjamin Marzinski [this message]
2020-06-18 20:06     ` Martin Wilck
2020-06-18 23:06       ` Benjamin Marzinski
2020-07-01 20:54         ` Martin Wilck
2020-07-02  3:14           ` Benjamin Marzinski
2020-07-02 12:24             ` Martin Wilck
2020-07-02 15:18               ` Benjamin Marzinski
2020-07-02 16:45                 ` Martin Wilck
2020-07-02 19:41                   ` Benjamin Marzinski
2020-07-03 15:12                     ` Martin Wilck
2020-07-03 16:39                       ` Mike Snitzer
2020-07-03 18:50                         ` Martin Wilck

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=20200618180458.GI5894@octiron.msp.redhat.com \
    --to=bmarzins@redhat.com \
    --cc=Martin.Wilck@suse.com \
    --cc=dm-devel@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.