Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dm-mpath: don't stop probing paths at presuspend

Commit 5c977f102315 ("dm-mpath: Don't grab work_mutex while probing
paths"), added code to make multipath quit probing paths early, if it
was trying to suspend. This isn't necessary. It was just an optimization
to try to keep path probing from delaying a suspend. However it causes
problems with the intended user of this code, qemu. The path probing
code was added because failed ioctls to multipath devices don't cause
paths to fail in cases where a regular IO failure would.

If an ioctl to a path failed because the path was down, and the
multipath device had passed presuspend, the M_MPATH_PROBE_PATHS ioctl
would exit early, without probing the path. The caller would then retry
the original ioctl, hoping to use a different path. But if there was
only one path in the pathgroup, it would pick the same non-working path
again, even if there were working paths in other pathgroups.

ioctls to a suspended dm device will return -EAGAIN, notifying the
caller that the device is suspended, but ioctls to a device that is just
preparing to suspend won't (and in general, shouldn't). This means that
the caller (qemu in this case) would get into a tight loop where it
would issue an ioctl that failed, skip probing the paths because the
device had already passed presuspend, and start over issuing the ioctl
again. This would continue until the multipath device finally fully
suspended, or the caller gave up and failed the ioctl.

multipath's path probing code could return -EAGAIN in this case, and the
caller could delay a bit before retrying, but the whole purpose of
skipping the probe after presuspend was to speed things up, and that
would just slow them down. Instead, remove the is_suspending flag, and
check dm_suspended() instead to decide whether to exit the probing code
early. This means that when the probing code exits early, future ioctls
will also be delayed, because the device is fully suspended.

Fixes: 5c977f102315 ("dm-mpath: Don't grab work_mutex while probing paths")
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

authored by

Benjamin Marzinski and committed by
Mikulas Patocka
51d81e14 a373b3d5

+2 -7
+2 -7
drivers/md/dm-mpath.c
··· 102 102 struct bio_list queued_bios; 103 103 104 104 struct timer_list nopath_timer; /* Timeout for queue_if_no_path */ 105 - bool is_suspending; 106 105 }; 107 106 108 107 /* ··· 1748 1749 { 1749 1750 struct multipath *m = ti->private; 1750 1751 1751 - spin_lock_irq(&m->lock); 1752 - m->is_suspending = true; 1753 - spin_unlock_irq(&m->lock); 1754 1752 /* FIXME: bio-based shouldn't need to always disable queue_if_no_path */ 1755 1753 if (m->queue_mode == DM_TYPE_BIO_BASED || !dm_noflush_suspending(m->ti)) 1756 1754 queue_if_no_path(m, false, true, __func__); ··· 1770 1774 struct multipath *m = ti->private; 1771 1775 1772 1776 spin_lock_irq(&m->lock); 1773 - m->is_suspending = false; 1774 1777 if (test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags)) { 1775 1778 set_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags); 1776 1779 clear_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags); ··· 2093 2098 if (m->current_pg == m->last_probed_pg) 2094 2099 goto skip_probe; 2095 2100 } 2096 - if (!m->current_pg || m->is_suspending || 2101 + if (!m->current_pg || dm_suspended(m->ti) || 2097 2102 test_bit(MPATHF_QUEUE_IO, &m->flags)) 2098 2103 goto skip_probe; 2099 2104 set_bit(MPATHF_DELAY_PG_SWITCH, &m->flags); ··· 2102 2107 2103 2108 list_for_each_entry(pgpath, &pg->pgpaths, list) { 2104 2109 if (pg != READ_ONCE(m->current_pg) || 2105 - READ_ONCE(m->is_suspending)) 2110 + dm_suspended(m->ti)) 2106 2111 goto out; 2107 2112 if (!pgpath->is_active) 2108 2113 continue;