* Re: [PATCH] dm: Fix deadlock when reloading a multipath table [not found] <20251009030431.2895495-1-bmarzins@redhat.com> @ 2025-10-09 9:57 ` Martin Wilck 2025-10-09 22:25 ` Benjamin Marzinski 2025-10-09 23:29 ` Bart Van Assche 0 siblings, 2 replies; 10+ messages in thread From: Martin Wilck @ 2025-10-09 9:57 UTC (permalink / raw) To: Benjamin Marzinski, Mikulas Patocka, Mike Snitzer; +Cc: dm-devel, linux-block On Wed, 2025-10-08 at 23:04 -0400, Benjamin Marzinski wrote: > Request-based devices (dm-multipath) queue I/O in blk-mq on noflush > suspends. Any queued IO will make it impossible to freeze the queue. > If > a process attempts to update the queue limits while there is queued > IO, > it can be get stuck holding the limits lock, while unable to freeze > the > queue. If device-mapper then attempts to update the limits during a > table swap, it will deadlock trying to grab the limits lock while > making > it impossible to flush the IO. > > Disallow updating the queue limits during a table swap, when updating > an > immutable request-based dm device (dm-multipath) during a noflush > suspend. It is userspace's responsibility to make sure that the new > table uses the same limits as the existing table if it asks for a > noflush suspend. > > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> > --- > drivers/md/dm-table.c | 4 ++++ > drivers/md/dm-thin.c | 7 ++----- > drivers/md/dm.c | 35 +++++++++++++++++++++++------------ > 3 files changed, 29 insertions(+), 17 deletions(-) > > diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c > index ad0a60a07b93..0522cd700e0e 100644 > --- a/drivers/md/dm-table.c > +++ b/drivers/md/dm-table.c > @@ -2043,6 +2043,10 @@ bool dm_table_supports_size_change(struct > dm_table *t, sector_t old_size, > return true; > } > > +/* > + * This function will be skipped by noflush reloads of immutable > request > + * based devices (dm-mpath). > + */ > int dm_table_set_restrictions(struct dm_table *t, struct > request_queue *q, > struct queue_limits *limits) > { > diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c > index c84149ba4e38..6f98936f0e05 100644 > --- a/drivers/md/dm-thin.c > +++ b/drivers/md/dm-thin.c > @@ -4383,11 +4383,8 @@ static void thin_postsuspend(struct dm_target > *ti) > { > struct thin_c *tc = ti->private; > > - /* > - * The dm_noflush_suspending flag has been cleared by now, > so > - * unfortunately we must always run this. > - */ > - noflush_work(tc, do_noflush_stop); > + if (dm_noflush_suspending(ti)) > + noflush_work(tc, do_noflush_stop); > } > > static int thin_preresume(struct dm_target *ti) > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > index 3ede5ba4cf7e..87e65c48dd04 100644 > --- a/drivers/md/dm.c > +++ b/drivers/md/dm.c > @@ -2439,7 +2439,6 @@ static struct dm_table *__bind(struct > mapped_device *md, struct dm_table *t, > { > struct dm_table *old_map; > sector_t size, old_size; > - int ret; > > lockdep_assert_held(&md->suspend_lock); > > @@ -2454,11 +2453,13 @@ static struct dm_table *__bind(struct > mapped_device *md, struct dm_table *t, > > set_capacity(md->disk, size); > > - ret = dm_table_set_restrictions(t, md->queue, limits); > - if (ret) { > - set_capacity(md->disk, old_size); > - old_map = ERR_PTR(ret); > - goto out; > + if (limits) { > + int ret = dm_table_set_restrictions(t, md->queue, > limits); > + if (ret) { > + set_capacity(md->disk, old_size); > + old_map = ERR_PTR(ret); > + goto out; > + } > } > > /* > @@ -2836,6 +2837,7 @@ static void dm_wq_work(struct work_struct > *work) > > static void dm_queue_flush(struct mapped_device *md) > { > + clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags); > smp_mb__after_atomic(); > queue_work(md->wq, &md->work); > @@ -2848,6 +2850,7 @@ struct dm_table *dm_swap_table(struct > mapped_device *md, struct dm_table *table) > { > struct dm_table *live_map = NULL, *map = ERR_PTR(-EINVAL); > struct queue_limits limits; > + bool update_limits = true; > int r; > > mutex_lock(&md->suspend_lock); > @@ -2856,20 +2859,31 @@ struct dm_table *dm_swap_table(struct > mapped_device *md, struct dm_table *table) > if (!dm_suspended_md(md)) > goto out; > > + /* > + * To avoid a potential deadlock locking the queue limits, > disallow > + * updating the queue limits during a table swap, when > updating an > + * immutable request-based dm device (dm-multipath) during a > noflush > + * suspend. It is userspace's responsibility to make sure > that the new > + * table uses the same limits as the existing table, if it > asks for a > + * noflush suspend. > + */ > + if (dm_request_based(md) && md->immutable_target && > + __noflush_suspending(md)) > + update_limits = false; > /* > * If the new table has no data devices, retain the existing > limits. > * This helps multipath with queue_if_no_path if all paths > disappear, > * then new I/O is queued based on these limits, and then > some paths > * reappear. > */ > - if (dm_table_has_no_data_devices(table)) { > + else if (dm_table_has_no_data_devices(table)) { > live_map = dm_get_live_table_fast(md); > if (live_map) > limits = md->queue->limits; > dm_put_live_table_fast(md); > } > > - if (!live_map) { > + if (update_limits && !live_map) { > r = dm_calculate_queue_limits(table, &limits); > if (r) { > map = ERR_PTR(r); > @@ -2877,7 +2891,7 @@ struct dm_table *dm_swap_table(struct > mapped_device *md, struct dm_table *table) > } > } > > - map = __bind(md, table, &limits); > + map = __bind(md, table, update_limits ? &limits : NULL); > dm_issue_global_event(); > > out: > @@ -2930,7 +2944,6 @@ static int __dm_suspend(struct mapped_device > *md, struct dm_table *map, > > /* > * DMF_NOFLUSH_SUSPENDING must be set before presuspend. > - * This flag is cleared before dm_suspend returns. > */ > if (noflush) > set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > @@ -2993,8 +3006,6 @@ static int __dm_suspend(struct mapped_device > *md, struct dm_table *map, > if (!r) > set_bit(dmf_suspended_flag, &md->flags); > > - if (noflush) > - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > if (map) > synchronize_srcu(&md->io_barrier); This moves the clear_bit() behind synchronize_rcu(). Is that safe? In general, I'm wondering whether we need a more generic solution to this problem. Therefore I've added linux-block to cc. The way I see it, if a device has queued IO without any means to perform the IO, it can't be frozen. We'd either need to fail all queued IO in this case, or refuse attempts to freeze the queue. Thanks, Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-09 9:57 ` [PATCH] dm: Fix deadlock when reloading a multipath table Martin Wilck @ 2025-10-09 22:25 ` Benjamin Marzinski 2025-10-10 10:19 ` Martin Wilck 2025-10-09 23:29 ` Bart Van Assche 1 sibling, 1 reply; 10+ messages in thread From: Benjamin Marzinski @ 2025-10-09 22:25 UTC (permalink / raw) To: Martin Wilck; +Cc: Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Thu, Oct 09, 2025 at 11:57:08AM +0200, Martin Wilck wrote: > On Wed, 2025-10-08 at 23:04 -0400, Benjamin Marzinski wrote: > > Request-based devices (dm-multipath) queue I/O in blk-mq on noflush > > suspends. Any queued IO will make it impossible to freeze the queue. > > If > > a process attempts to update the queue limits while there is queued > > IO, > > it can be get stuck holding the limits lock, while unable to freeze > > the > > queue. If device-mapper then attempts to update the limits during a > > table swap, it will deadlock trying to grab the limits lock while > > making > > it impossible to flush the IO. > > > > Disallow updating the queue limits during a table swap, when updating > > an > > immutable request-based dm device (dm-multipath) during a noflush > > suspend. It is userspace's responsibility to make sure that the new > > table uses the same limits as the existing table if it asks for a > > noflush suspend. > > > > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> > > --- > > drivers/md/dm-table.c | 4 ++++ > > drivers/md/dm-thin.c | 7 ++----- > > drivers/md/dm.c | 35 +++++++++++++++++++++++------------ > > 3 files changed, 29 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c > > index ad0a60a07b93..0522cd700e0e 100644 > > --- a/drivers/md/dm-table.c > > +++ b/drivers/md/dm-table.c > > @@ -2043,6 +2043,10 @@ bool dm_table_supports_size_change(struct > > dm_table *t, sector_t old_size, > > return true; > > } > > > > +/* > > + * This function will be skipped by noflush reloads of immutable > > request > > + * based devices (dm-mpath). > > + */ > > int dm_table_set_restrictions(struct dm_table *t, struct > > request_queue *q, > > struct queue_limits *limits) > > { > > diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c > > index c84149ba4e38..6f98936f0e05 100644 > > --- a/drivers/md/dm-thin.c > > +++ b/drivers/md/dm-thin.c > > @@ -4383,11 +4383,8 @@ static void thin_postsuspend(struct dm_target > > *ti) > > { > > struct thin_c *tc = ti->private; > > > > - /* > > - * The dm_noflush_suspending flag has been cleared by now, > > so > > - * unfortunately we must always run this. > > - */ > > - noflush_work(tc, do_noflush_stop); > > + if (dm_noflush_suspending(ti)) > > + noflush_work(tc, do_noflush_stop); > > } > > > > static int thin_preresume(struct dm_target *ti) > > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > > index 3ede5ba4cf7e..87e65c48dd04 100644 > > --- a/drivers/md/dm.c > > +++ b/drivers/md/dm.c > > @@ -2439,7 +2439,6 @@ static struct dm_table *__bind(struct > > mapped_device *md, struct dm_table *t, > > { > > struct dm_table *old_map; > > sector_t size, old_size; > > - int ret; > > > > lockdep_assert_held(&md->suspend_lock); > > > > @@ -2454,11 +2453,13 @@ static struct dm_table *__bind(struct > > mapped_device *md, struct dm_table *t, > > > > set_capacity(md->disk, size); > > > > - ret = dm_table_set_restrictions(t, md->queue, limits); > > - if (ret) { > > - set_capacity(md->disk, old_size); > > - old_map = ERR_PTR(ret); > > - goto out; > > + if (limits) { > > + int ret = dm_table_set_restrictions(t, md->queue, > > limits); > > + if (ret) { > > + set_capacity(md->disk, old_size); > > + old_map = ERR_PTR(ret); > > + goto out; > > + } > > } > > > > /* > > @@ -2836,6 +2837,7 @@ static void dm_wq_work(struct work_struct > > *work) > > > > static void dm_queue_flush(struct mapped_device *md) > > { > > + clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags); > > smp_mb__after_atomic(); > > queue_work(md->wq, &md->work); > > @@ -2848,6 +2850,7 @@ struct dm_table *dm_swap_table(struct > > mapped_device *md, struct dm_table *table) > > { > > struct dm_table *live_map = NULL, *map = ERR_PTR(-EINVAL); > > struct queue_limits limits; > > + bool update_limits = true; > > int r; > > > > mutex_lock(&md->suspend_lock); > > @@ -2856,20 +2859,31 @@ struct dm_table *dm_swap_table(struct > > mapped_device *md, struct dm_table *table) > > if (!dm_suspended_md(md)) > > goto out; > > > > + /* > > + * To avoid a potential deadlock locking the queue limits, > > disallow > > + * updating the queue limits during a table swap, when > > updating an > > + * immutable request-based dm device (dm-multipath) during a > > noflush > > + * suspend. It is userspace's responsibility to make sure > > that the new > > + * table uses the same limits as the existing table, if it > > asks for a > > + * noflush suspend. > > + */ > > + if (dm_request_based(md) && md->immutable_target && > > + __noflush_suspending(md)) > > + update_limits = false; > > /* > > * If the new table has no data devices, retain the existing > > limits. > > * This helps multipath with queue_if_no_path if all paths > > disappear, > > * then new I/O is queued based on these limits, and then > > some paths > > * reappear. > > */ > > - if (dm_table_has_no_data_devices(table)) { > > + else if (dm_table_has_no_data_devices(table)) { > > live_map = dm_get_live_table_fast(md); > > if (live_map) > > limits = md->queue->limits; > > dm_put_live_table_fast(md); > > } > > > > - if (!live_map) { > > + if (update_limits && !live_map) { > > r = dm_calculate_queue_limits(table, &limits); > > if (r) { > > map = ERR_PTR(r); > > @@ -2877,7 +2891,7 @@ struct dm_table *dm_swap_table(struct > > mapped_device *md, struct dm_table *table) > > } > > } > > > > - map = __bind(md, table, &limits); > > + map = __bind(md, table, update_limits ? &limits : NULL); > > dm_issue_global_event(); > > > > out: > > @@ -2930,7 +2944,6 @@ static int __dm_suspend(struct mapped_device > > *md, struct dm_table *map, > > > > /* > > * DMF_NOFLUSH_SUSPENDING must be set before presuspend. > > - * This flag is cleared before dm_suspend returns. > > */ > > if (noflush) > > set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > @@ -2993,8 +3006,6 @@ static int __dm_suspend(struct mapped_device > > *md, struct dm_table *map, > > if (!r) > > set_bit(dmf_suspended_flag, &md->flags); > > > > - if (noflush) > > - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > if (map) > > synchronize_srcu(&md->io_barrier); > > This moves the clear_bit() behind synchronize_rcu(). Is that safe? It's not just moved behind the synchronize_rcu(). DMF_NOFLUSH_SUSPENDING is now set for the entire time the device is suspended. If people would like, I'll update the patch to rename it to DMF_NOFLUSH_SUSPEND. I did check to see if holding it for the entire suspend would cause issues, but I didn't see any case where it would. If I missed a case where __noflush_suspending() should only return true if we are actually in the process of suspending, I can easily update that function to do that. > In general, I'm wondering whether we need a more generic solution to > this problem. Therefore I've added linux-block to cc. > > The way I see it, if a device has queued IO without any means to > perform the IO, it can't be frozen. We'd either need to fail all queued > IO in this case, or refuse attempts to freeze the queue. In general, it's perfectly normal to start freezing the queue while there are still outstanding requests. I'm not sure that there is a good way to distinguish between multipath's queued requests and other cases. I'd be happy to be proved wrong, however. -Ben > Thanks, > Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-09 22:25 ` Benjamin Marzinski @ 2025-10-10 10:19 ` Martin Wilck 2025-10-21 19:16 ` Benjamin Marzinski 0 siblings, 1 reply; 10+ messages in thread From: Martin Wilck @ 2025-10-10 10:19 UTC (permalink / raw) To: Benjamin Marzinski, Bart Van Assche Cc: Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Thu, 2025-10-09 at 18:25 -0400, Benjamin Marzinski wrote: > On Thu, Oct 09, 2025 at 11:57:08AM +0200, Martin Wilck wrote: > > On Wed, 2025-10-08 at 23:04 -0400, Benjamin Marzinski wrote: > > > Request-based devices (dm-multipath) queue I/O in blk-mq on > > > noflush > > > suspends. Any queued IO will make it impossible to freeze the > > > queue. > > > If > > > a process attempts to update the queue limits while there is > > > queued > > > IO, > > > it can be get stuck holding the limits lock, while unable to > > > freeze > > > the > > > queue. If device-mapper then attempts to update the limits during > > > a > > > table swap, it will deadlock trying to grab the limits lock while > > > making > > > it impossible to flush the IO. > > > > > > Disallow updating the queue limits during a table swap, when > > > updating > > > an > > > immutable request-based dm device (dm-multipath) during a noflush > > > suspend. It is userspace's responsibility to make sure that the > > > new > > > table uses the same limits as the existing table if it asks for a > > > noflush suspend. > > > > > > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> > > > --- > > > drivers/md/dm-table.c | 4 ++++ > > > drivers/md/dm-thin.c | 7 ++----- > > > drivers/md/dm.c | 35 +++++++++++++++++++++++------------ > > > 3 files changed, 29 insertions(+), 17 deletions(-) > > > > > > diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c > > > index ad0a60a07b93..0522cd700e0e 100644 > > > --- a/drivers/md/dm-table.c > > > +++ b/drivers/md/dm-table.c > > > @@ -2043,6 +2043,10 @@ bool dm_table_supports_size_change(struct > > > dm_table *t, sector_t old_size, > > > return true; > > > } > > > > > > +/* > > > + * This function will be skipped by noflush reloads of immutable > > > request > > > + * based devices (dm-mpath). > > > + */ > > > int dm_table_set_restrictions(struct dm_table *t, struct > > > request_queue *q, > > > struct queue_limits *limits) > > > { > > > diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c > > > index c84149ba4e38..6f98936f0e05 100644 > > > --- a/drivers/md/dm-thin.c > > > +++ b/drivers/md/dm-thin.c > > > @@ -4383,11 +4383,8 @@ static void thin_postsuspend(struct > > > dm_target > > > *ti) > > > { > > > struct thin_c *tc = ti->private; > > > > > > - /* > > > - * The dm_noflush_suspending flag has been cleared by > > > now, > > > so > > > - * unfortunately we must always run this. > > > - */ > > > - noflush_work(tc, do_noflush_stop); > > > + if (dm_noflush_suspending(ti)) > > > + noflush_work(tc, do_noflush_stop); > > > } > > > > > > static int thin_preresume(struct dm_target *ti) > > > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > > > index 3ede5ba4cf7e..87e65c48dd04 100644 > > > --- a/drivers/md/dm.c > > > +++ b/drivers/md/dm.c > > > @@ -2439,7 +2439,6 @@ static struct dm_table *__bind(struct > > > mapped_device *md, struct dm_table *t, > > > { > > > struct dm_table *old_map; > > > sector_t size, old_size; > > > - int ret; > > > > > > lockdep_assert_held(&md->suspend_lock); > > > > > > @@ -2454,11 +2453,13 @@ static struct dm_table *__bind(struct > > > mapped_device *md, struct dm_table *t, > > > > > > set_capacity(md->disk, size); > > > > > > - ret = dm_table_set_restrictions(t, md->queue, limits); > > > - if (ret) { > > > - set_capacity(md->disk, old_size); > > > - old_map = ERR_PTR(ret); > > > - goto out; > > > + if (limits) { > > > + int ret = dm_table_set_restrictions(t, md- > > > >queue, > > > limits); > > > + if (ret) { > > > + set_capacity(md->disk, old_size); > > > + old_map = ERR_PTR(ret); > > > + goto out; > > > + } > > > } > > > > > > /* > > > @@ -2836,6 +2837,7 @@ static void dm_wq_work(struct work_struct > > > *work) > > > > > > static void dm_queue_flush(struct mapped_device *md) > > > { > > > + clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags); > > > smp_mb__after_atomic(); > > > queue_work(md->wq, &md->work); > > > @@ -2848,6 +2850,7 @@ struct dm_table *dm_swap_table(struct > > > mapped_device *md, struct dm_table *table) > > > { > > > struct dm_table *live_map = NULL, *map = ERR_PTR(- > > > EINVAL); > > > struct queue_limits limits; > > > + bool update_limits = true; > > > int r; > > > > > > mutex_lock(&md->suspend_lock); > > > @@ -2856,20 +2859,31 @@ struct dm_table *dm_swap_table(struct > > > mapped_device *md, struct dm_table *table) > > > if (!dm_suspended_md(md)) > > > goto out; > > > > > > + /* > > > + * To avoid a potential deadlock locking the queue > > > limits, > > > disallow > > > + * updating the queue limits during a table swap, when > > > updating an > > > + * immutable request-based dm device (dm-multipath) > > > during a > > > noflush > > > + * suspend. It is userspace's responsibility to make > > > sure > > > that the new > > > + * table uses the same limits as the existing table, if > > > it > > > asks for a > > > + * noflush suspend. > > > + */ > > > + if (dm_request_based(md) && md->immutable_target && > > > + __noflush_suspending(md)) > > > + update_limits = false; > > > /* > > > * If the new table has no data devices, retain the > > > existing > > > limits. > > > * This helps multipath with queue_if_no_path if all > > > paths > > > disappear, > > > * then new I/O is queued based on these limits, and > > > then > > > some paths > > > * reappear. > > > */ > > > - if (dm_table_has_no_data_devices(table)) { > > > + else if (dm_table_has_no_data_devices(table)) { > > > live_map = dm_get_live_table_fast(md); > > > if (live_map) > > > limits = md->queue->limits; > > > dm_put_live_table_fast(md); > > > } > > > > > > - if (!live_map) { > > > + if (update_limits && !live_map) { > > > r = dm_calculate_queue_limits(table, &limits); > > > if (r) { > > > map = ERR_PTR(r); > > > @@ -2877,7 +2891,7 @@ struct dm_table *dm_swap_table(struct > > > mapped_device *md, struct dm_table *table) > > > } > > > } > > > > > > - map = __bind(md, table, &limits); > > > + map = __bind(md, table, update_limits ? &limits : NULL); > > > dm_issue_global_event(); > > > > > > out: > > > @@ -2930,7 +2944,6 @@ static int __dm_suspend(struct > > > mapped_device > > > *md, struct dm_table *map, > > > > > > /* > > > * DMF_NOFLUSH_SUSPENDING must be set before presuspend. > > > - * This flag is cleared before dm_suspend returns. > > > */ > > > if (noflush) > > > set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > @@ -2993,8 +3006,6 @@ static int __dm_suspend(struct > > > mapped_device > > > *md, struct dm_table *map, > > > if (!r) > > > set_bit(dmf_suspended_flag, &md->flags); > > > > > > - if (noflush) > > > - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > if (map) > > > synchronize_srcu(&md->io_barrier); > > > > This moves the clear_bit() behind synchronize_rcu(). Is that safe? > > It's not just moved behind the synchronize_rcu(). > DMF_NOFLUSH_SUSPENDING > is now set for the entire time the device is suspended. If people > would > like, I'll update the patch to rename it to DMF_NOFLUSH_SUSPEND. Right. I realize now that there's a smp_mb__after_atomic() in dm_queue_flush(). > I did check to see if holding it for the entire suspend would cause > issues, but I didn't see any case where it would. If I missed a > case where __noflush_suspending() should only return true if we are > actually in the process of suspending, I can easily update that > function to do that. If this is necessary, I agree that the flag an related function should be renamed. But there are already generic DM flags to indicate that a queue is suspend*ed*. Perhaps, instead of changing the semantics of DMF_NOFLUSH_SUSPENDING, it would make more sense to test (__noflush_suspending || test_bit(DMF_BLOCK_IO_FOR_SUSPEND) in dm_swap_table()? Anyway, I am still not convinced that we want to have this specific exception for multipath only. > > In general, I'm wondering whether we need a more generic solution > > to > > this problem. Therefore I've added linux-block to cc. > > > > The way I see it, if a device has queued IO without any means to > > perform the IO, it can't be frozen. We'd either need to fail all > > queued > > IO in this case, or refuse attempts to freeze the queue. > > In general, it's perfectly normal to start freezing the queue while > there are still outstanding requests. Sure, but my point was "without any means to perform the IO". As you pointed out yourself, a freeze attempt in this situation would get stuck. I find Bart's approach very attractive; freezing might not be necessary at all in that case. We'dd just need to avoid a race where paths get reinstated while the operation that would normally have required a freeze is ongoing. Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-10 10:19 ` Martin Wilck @ 2025-10-21 19:16 ` Benjamin Marzinski 2025-10-22 14:11 ` Martin Wilck 0 siblings, 1 reply; 10+ messages in thread From: Benjamin Marzinski @ 2025-10-21 19:16 UTC (permalink / raw) To: Martin Wilck Cc: Bart Van Assche, Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Fri, Oct 10, 2025 at 12:19:51PM +0200, Martin Wilck wrote: > On Thu, 2025-10-09 at 18:25 -0400, Benjamin Marzinski wrote: > > On Thu, Oct 09, 2025 at 11:57:08AM +0200, Martin Wilck wrote: > > > On Wed, 2025-10-08 at 23:04 -0400, Benjamin Marzinski wrote: > > > > Request-based devices (dm-multipath) queue I/O in blk-mq on > > > > noflush > > > > suspends. Any queued IO will make it impossible to freeze the > > > > queue. > > > > If > > > > a process attempts to update the queue limits while there is > > > > queued > > > > IO, > > > > it can be get stuck holding the limits lock, while unable to > > > > freeze > > > > the > > > > queue. If device-mapper then attempts to update the limits during > > > > a > > > > table swap, it will deadlock trying to grab the limits lock while > > > > making > > > > it impossible to flush the IO. > > > > > > > > Disallow updating the queue limits during a table swap, when > > > > updating > > > > an > > > > immutable request-based dm device (dm-multipath) during a noflush > > > > suspend. It is userspace's responsibility to make sure that the > > > > new > > > > table uses the same limits as the existing table if it asks for a > > > > noflush suspend. > > > > > > > > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> > > > > --- > > > > drivers/md/dm-table.c | 4 ++++ > > > > drivers/md/dm-thin.c | 7 ++----- > > > > drivers/md/dm.c | 35 +++++++++++++++++++++++------------ > > > > 3 files changed, 29 insertions(+), 17 deletions(-) > > > > > > > > diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c > > > > index ad0a60a07b93..0522cd700e0e 100644 > > > > --- a/drivers/md/dm-table.c > > > > +++ b/drivers/md/dm-table.c > > > > @@ -2043,6 +2043,10 @@ bool dm_table_supports_size_change(struct > > > > dm_table *t, sector_t old_size, > > > > return true; > > > > } > > > > > > > > +/* > > > > + * This function will be skipped by noflush reloads of immutable > > > > request > > > > + * based devices (dm-mpath). > > > > + */ > > > > int dm_table_set_restrictions(struct dm_table *t, struct > > > > request_queue *q, > > > > struct queue_limits *limits) > > > > { > > > > diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c > > > > index c84149ba4e38..6f98936f0e05 100644 > > > > --- a/drivers/md/dm-thin.c > > > > +++ b/drivers/md/dm-thin.c > > > > @@ -4383,11 +4383,8 @@ static void thin_postsuspend(struct > > > > dm_target > > > > *ti) > > > > { > > > > struct thin_c *tc = ti->private; > > > > > > > > - /* > > > > - * The dm_noflush_suspending flag has been cleared by > > > > now, > > > > so > > > > - * unfortunately we must always run this. > > > > - */ > > > > - noflush_work(tc, do_noflush_stop); > > > > + if (dm_noflush_suspending(ti)) > > > > + noflush_work(tc, do_noflush_stop); > > > > } > > > > > > > > static int thin_preresume(struct dm_target *ti) > > > > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > > > > index 3ede5ba4cf7e..87e65c48dd04 100644 > > > > --- a/drivers/md/dm.c > > > > +++ b/drivers/md/dm.c > > > > @@ -2439,7 +2439,6 @@ static struct dm_table *__bind(struct > > > > mapped_device *md, struct dm_table *t, > > > > { > > > > struct dm_table *old_map; > > > > sector_t size, old_size; > > > > - int ret; > > > > > > > > lockdep_assert_held(&md->suspend_lock); > > > > > > > > @@ -2454,11 +2453,13 @@ static struct dm_table *__bind(struct > > > > mapped_device *md, struct dm_table *t, > > > > > > > > set_capacity(md->disk, size); > > > > > > > > - ret = dm_table_set_restrictions(t, md->queue, limits); > > > > - if (ret) { > > > > - set_capacity(md->disk, old_size); > > > > - old_map = ERR_PTR(ret); > > > > - goto out; > > > > + if (limits) { > > > > + int ret = dm_table_set_restrictions(t, md- > > > > >queue, > > > > limits); > > > > + if (ret) { > > > > + set_capacity(md->disk, old_size); > > > > + old_map = ERR_PTR(ret); > > > > + goto out; > > > > + } > > > > } > > > > > > > > /* > > > > @@ -2836,6 +2837,7 @@ static void dm_wq_work(struct work_struct > > > > *work) > > > > > > > > static void dm_queue_flush(struct mapped_device *md) > > > > { > > > > + clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > > clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags); > > > > smp_mb__after_atomic(); > > > > queue_work(md->wq, &md->work); > > > > @@ -2848,6 +2850,7 @@ struct dm_table *dm_swap_table(struct > > > > mapped_device *md, struct dm_table *table) > > > > { > > > > struct dm_table *live_map = NULL, *map = ERR_PTR(- > > > > EINVAL); > > > > struct queue_limits limits; > > > > + bool update_limits = true; > > > > int r; > > > > > > > > mutex_lock(&md->suspend_lock); > > > > @@ -2856,20 +2859,31 @@ struct dm_table *dm_swap_table(struct > > > > mapped_device *md, struct dm_table *table) > > > > if (!dm_suspended_md(md)) > > > > goto out; > > > > > > > > + /* > > > > + * To avoid a potential deadlock locking the queue > > > > limits, > > > > disallow > > > > + * updating the queue limits during a table swap, when > > > > updating an > > > > + * immutable request-based dm device (dm-multipath) > > > > during a > > > > noflush > > > > + * suspend. It is userspace's responsibility to make > > > > sure > > > > that the new > > > > + * table uses the same limits as the existing table, if > > > > it > > > > asks for a > > > > + * noflush suspend. > > > > + */ > > > > + if (dm_request_based(md) && md->immutable_target && > > > > + __noflush_suspending(md)) > > > > + update_limits = false; > > > > /* > > > > * If the new table has no data devices, retain the > > > > existing > > > > limits. > > > > * This helps multipath with queue_if_no_path if all > > > > paths > > > > disappear, > > > > * then new I/O is queued based on these limits, and > > > > then > > > > some paths > > > > * reappear. > > > > */ > > > > - if (dm_table_has_no_data_devices(table)) { > > > > + else if (dm_table_has_no_data_devices(table)) { > > > > live_map = dm_get_live_table_fast(md); > > > > if (live_map) > > > > limits = md->queue->limits; > > > > dm_put_live_table_fast(md); > > > > } > > > > > > > > - if (!live_map) { > > > > + if (update_limits && !live_map) { > > > > r = dm_calculate_queue_limits(table, &limits); > > > > if (r) { > > > > map = ERR_PTR(r); > > > > @@ -2877,7 +2891,7 @@ struct dm_table *dm_swap_table(struct > > > > mapped_device *md, struct dm_table *table) > > > > } > > > > } > > > > > > > > - map = __bind(md, table, &limits); > > > > + map = __bind(md, table, update_limits ? &limits : NULL); > > > > dm_issue_global_event(); > > > > > > > > out: > > > > @@ -2930,7 +2944,6 @@ static int __dm_suspend(struct > > > > mapped_device > > > > *md, struct dm_table *map, > > > > > > > > /* > > > > * DMF_NOFLUSH_SUSPENDING must be set before presuspend. > > > > - * This flag is cleared before dm_suspend returns. > > > > */ > > > > if (noflush) > > > > set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > > @@ -2993,8 +3006,6 @@ static int __dm_suspend(struct > > > > mapped_device > > > > *md, struct dm_table *map, > > > > if (!r) > > > > set_bit(dmf_suspended_flag, &md->flags); > > > > > > > > - if (noflush) > > > > - clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); > > > > if (map) > > > > synchronize_srcu(&md->io_barrier); > > > > > > This moves the clear_bit() behind synchronize_rcu(). Is that safe? > > > > It's not just moved behind the synchronize_rcu(). > > DMF_NOFLUSH_SUSPENDING > > is now set for the entire time the device is suspended. If people > > would > > like, I'll update the patch to rename it to DMF_NOFLUSH_SUSPEND. > > Right. I realize now that there's a smp_mb__after_atomic() in > dm_queue_flush(). > > > I did check to see if holding it for the entire suspend would cause > > issues, but I didn't see any case where it would. If I missed a > > case where __noflush_suspending() should only return true if we are > > actually in the process of suspending, I can easily update that > > function to do that. > > If this is necessary, I agree that the flag an related function should > be renamed. But there are already generic DM flags to indicate that a > queue is suspend*ed*. Perhaps, instead of changing the semantics of > DMF_NOFLUSH_SUSPENDING, it would make more sense to test > > (__noflush_suspending || test_bit(DMF_BLOCK_IO_FOR_SUSPEND) > > in dm_swap_table()? Won't we ALWAYS be suspended when we are in dm_swap_table()? We do need to refresh the limits in some cases (the cases where multipath-tools currently reloads the table without setting noflush). What we need to know is "is this table swap happening in a noflush suspend, where userspace understands that it can't modify the device table in a way that would change the limits". For multipath, this is almost always the case. > > Anyway, I am still not convinced that we want to have this specific > exception for multipath only. I agree that Bart's solution looks better to me, if it can get in. > > > In general, I'm wondering whether we need a more generic solution > > > to > > > this problem. Therefore I've added linux-block to cc. > > > > > > The way I see it, if a device has queued IO without any means to > > > perform the IO, it can't be frozen. We'd either need to fail all > > > queued > > > IO in this case, or refuse attempts to freeze the queue. > > > > In general, it's perfectly normal to start freezing the queue while > > there are still outstanding requests. > > Sure, but my point was "without any means to perform the IO". As you > pointed out yourself, a freeze attempt in this situation would get > stuck. > > I find Bart's approach very attractive; freezing might not be necessary > at all in that case. We'dd just need to avoid a race where paths get > reinstated while the operation that would normally have required a > freeze is ongoing. I agree. Even just the timing out of freezes, his "[PATCH 2/3] block: Restrict the duration of sysfs attribute changes" would be enough to keep this from deadlocking the system. -Ben > Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-21 19:16 ` Benjamin Marzinski @ 2025-10-22 14:11 ` Martin Wilck 2025-10-23 17:39 ` Benjamin Marzinski 0 siblings, 1 reply; 10+ messages in thread From: Martin Wilck @ 2025-10-22 14:11 UTC (permalink / raw) To: Benjamin Marzinski Cc: Bart Van Assche, Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Tue, 2025-10-21 at 15:16 -0400, Benjamin Marzinski wrote: > On Fri, Oct 10, 2025 at 12:19:51PM +0200, Martin Wilck wrote: > > On Thu, 2025-10-09 at 18:25 -0400, Benjamin Marzinski wrote: > > > > > > > I did check to see if holding it for the entire suspend would > > > cause > > > issues, but I didn't see any case where it would. If I missed a > > > case where __noflush_suspending() should only return true if we > > > are > > > actually in the process of suspending, I can easily update that > > > function to do that. > > > > If this is necessary, I agree that the flag an related function > > should > > be renamed. But there are already generic DM flags to indicate that > > a > > queue is suspend*ed*. Perhaps, instead of changing the semantics of > > DMF_NOFLUSH_SUSPENDING, it would make more sense to test > > > > (__noflush_suspending || test_bit(DMF_BLOCK_IO_FOR_SUSPEND) > > > > in dm_swap_table()? > > Won't we ALWAYS be suspended when we are in dm_swap_table()? We do > need > to refresh the limits in some cases (the cases where multipath-tools > currently reloads the table without setting noflush). What we need to > know is "is this table swap happening in a noflush suspend, where > userspace understands that it can't modify the device table in a way > that would change the limits". For multipath, this is almost always > the > case. Ok, getting it now. The semantics of the flag are changed from "device is noflush-suspending" to "device is either noflush-suspending or noflush-suspended". It isn't easy to express this in a simple flag name. I'm fine with not renaming the flag, if a comment is added that explains the semantics clearly. > > > > I find Bart's approach very attractive; freezing might not be > > necessary > > at all in that case. We'dd just need to avoid a race where paths > > get > > reinstated while the operation that would normally have required a > > freeze is ongoing. > > I agree. Even just the timing out of freezes, his > "[PATCH 2/3] block: Restrict the duration of sysfs attribute changes" > would be enough to keep this from deadlocking the system. > OK, let's see how it goes. Given your explanations, I'm ok with your patch, too. Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-22 14:11 ` Martin Wilck @ 2025-10-23 17:39 ` Benjamin Marzinski 2025-10-23 17:54 ` Bart Van Assche 0 siblings, 1 reply; 10+ messages in thread From: Benjamin Marzinski @ 2025-10-23 17:39 UTC (permalink / raw) To: Martin Wilck Cc: Bart Van Assche, Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Wed, Oct 22, 2025 at 04:11:58PM +0200, Martin Wilck wrote: > On Tue, 2025-10-21 at 15:16 -0400, Benjamin Marzinski wrote: > > On Fri, Oct 10, 2025 at 12:19:51PM +0200, Martin Wilck wrote: > > > On Thu, 2025-10-09 at 18:25 -0400, Benjamin Marzinski wrote: > > > > > > > > > > I did check to see if holding it for the entire suspend would > > > > cause > > > > issues, but I didn't see any case where it would. If I missed a > > > > case where __noflush_suspending() should only return true if we > > > > are > > > > actually in the process of suspending, I can easily update that > > > > function to do that. > > > > > > If this is necessary, I agree that the flag an related function > > > should > > > be renamed. But there are already generic DM flags to indicate that > > > a > > > queue is suspend*ed*. Perhaps, instead of changing the semantics of > > > DMF_NOFLUSH_SUSPENDING, it would make more sense to test > > > > > > (__noflush_suspending || test_bit(DMF_BLOCK_IO_FOR_SUSPEND) > > > > > > in dm_swap_table()? > > > > Won't we ALWAYS be suspended when we are in dm_swap_table()? We do > > need > > to refresh the limits in some cases (the cases where multipath-tools > > currently reloads the table without setting noflush). What we need to > > know is "is this table swap happening in a noflush suspend, where > > userspace understands that it can't modify the device table in a way > > that would change the limits". For multipath, this is almost always > > the > > case. > > Ok, getting it now. The semantics of the flag are changed from "device > is noflush-suspending" to "device is either noflush-suspending or > noflush-suspended". It isn't easy to express this in a simple flag > name. I'm fine with not renaming the flag, if a comment is added that > explains the semantics clearly. > > > > > > > I find Bart's approach very attractive; freezing might not be > > > necessary > > > at all in that case. We'dd just need to avoid a race where paths > > > get > > > reinstated while the operation that would normally have required a > > > freeze is ongoing. > > > > I agree. Even just the timing out of freezes, his > > "[PATCH 2/3] block: Restrict the duration of sysfs attribute changes" > > would be enough to keep this from deadlocking the system. > > > > OK, let's see how it goes. Given your explanations, I'm ok with your > patch, too. I see Mikulas pulled this commit into linux-dm. Bart, does this solve your issue? Looking at your hang, it should. Also, do you have any interest in attempting again to get your fixes upstream? -Ben > > Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-23 17:39 ` Benjamin Marzinski @ 2025-10-23 17:54 ` Bart Van Assche 0 siblings, 0 replies; 10+ messages in thread From: Bart Van Assche @ 2025-10-23 17:54 UTC (permalink / raw) To: Benjamin Marzinski, Martin Wilck Cc: Bart Van Assche, Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On 10/23/25 10:39 AM, Benjamin Marzinski wrote: > On Wed, Oct 22, 2025 at 04:11:58PM +0200, Martin Wilck wrote: >> On Tue, 2025-10-21 at 15:16 -0400, Benjamin Marzinski wrote: >>> On Fri, Oct 10, 2025 at 12:19:51PM +0200, Martin Wilck wrote: >>>> I find Bart's approach very attractive; freezing might not be >>>> necessary >>>> at all in that case. We'dd just need to avoid a race where paths >>>> get >>>> reinstated while the operation that would normally have required a >>>> freeze is ongoing. >>> >>> I agree. Even just the timing out of freezes, his >>> "[PATCH 2/3] block: Restrict the duration of sysfs attribute changes" >>> would be enough to keep this from deadlocking the system. >>> >> >> OK, let's see how it goes. Given your explanations, I'm ok with your >> patch, too. > > I see Mikulas pulled this commit into linux-dm. Bart, does this solve > your issue? Looking at your hang, it should. Also, do you have any > interest in attempting again to get your fixes upstream? I think that I have done what I could to get this regression fixed. As one can see here I reported on June 30 that a regression got introduced in the block layer: https://lore.kernel.org/linux-block/765d62a8-bb5d-4f1d-8996-afc005bc2d1d@acm.org/ Although Linus Torvalds does not tolerate regressions in the Linux kernel, the people who introduced this regression were not impressed by my email, refused my patches, did not revert their own patches that introduced the regression and did not suggest an alternative approach for fixing the regression. Bart. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-09 9:57 ` [PATCH] dm: Fix deadlock when reloading a multipath table Martin Wilck 2025-10-09 22:25 ` Benjamin Marzinski @ 2025-10-09 23:29 ` Bart Van Assche 2025-10-10 0:39 ` Benjamin Marzinski 2025-10-10 9:23 ` Martin Wilck 1 sibling, 2 replies; 10+ messages in thread From: Bart Van Assche @ 2025-10-09 23:29 UTC (permalink / raw) To: Martin Wilck, Benjamin Marzinski, Mikulas Patocka, Mike Snitzer Cc: dm-devel, linux-block On 10/9/25 2:57 AM, Martin Wilck wrote: > In general, I'm wondering whether we need a more generic solution to > this problem. Therefore I've added linux-block to cc. > > The way I see it, if a device has queued IO without any means to > perform the IO, it can't be frozen. We'd either need to fail all queued > IO in this case, or refuse attempts to freeze the queue. If a device has queued I/O and the I/O can't make progress then it isn't necessary to call blk_mq_freeze_queue(), isn't it? See also "[PATCH 0/3] Fix a deadlock related to modifying queue attributes" (https://lore.kernel.org/linux-block/20250702182430.3764163-1-bvanassche@acm.org/). BTW, that patch series is not upstream. I apply it manually every time before I run blktests. Bart. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-09 23:29 ` Bart Van Assche @ 2025-10-10 0:39 ` Benjamin Marzinski 2025-10-10 9:23 ` Martin Wilck 1 sibling, 0 replies; 10+ messages in thread From: Benjamin Marzinski @ 2025-10-10 0:39 UTC (permalink / raw) To: Bart Van Assche Cc: Martin Wilck, Mikulas Patocka, Mike Snitzer, dm-devel, linux-block On Thu, Oct 09, 2025 at 04:29:21PM -0700, Bart Van Assche wrote: > On 10/9/25 2:57 AM, Martin Wilck wrote: > > In general, I'm wondering whether we need a more generic solution to > > this problem. Therefore I've added linux-block to cc. > > > > The way I see it, if a device has queued IO without any means to > > perform the IO, it can't be frozen. We'd either need to fail all queued > > IO in this case, or refuse attempts to freeze the queue. > > If a device has queued I/O and the I/O can't make progress then it isn't > necessary to call blk_mq_freeze_queue(), isn't it? See also "[PATCH 0/3] Fix > a deadlock related to modifying queue attributes" > (https://lore.kernel.org/linux-block/20250702182430.3764163-1-bvanassche@acm.org/). > > BTW, that patch series is not upstream. I apply it manually every time > before I run blktests. Timing out the queue freeze looks like a good solution to me. Also, looking at that thread, I should point out that bio-based multipath does not suffer from this, since it doesn't queue requests. It queues bios. The reason you still got the hang with your blktests patch is that it didn't actually configure bio-based multipath ("queue_mode" is not a valid multipath.conf option). That would look something like this: =================== diff --git a/common/multipath-over-rdma b/common/multipath-over-rdma index e157e0a..1084f80 100644 --- a/common/multipath-over-rdma +++ b/common/multipath-over-rdma @@ -267,9 +267,7 @@ mpath_has_stale_dev() { # Check whether multipath definition $1 includes the queue_if_no_path keyword. is_qinp_def() { case "$1" in - *" 3 queue_if_no_path queue_mode mq "*) - return 0;; - *" 1 queue_if_no_path "*) + *" queue_if_no_path "*) return 0;; *) return 1;; diff --git a/tests/srp/multipath.conf b/tests/srp/multipath.conf index e0da32e..aad8e56 100644 --- a/tests/srp/multipath.conf +++ b/tests/srp/multipath.conf @@ -9,6 +9,7 @@ devices { product ".*" no_path_retry queue path_checker tur + features "2 queue_mode bio" } } blacklist { ================== But you are correct that unless we can get bio-based multipath to something like performance parity with request-based multipath, customers aren't interested it in. -Ben > > Bart. ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] dm: Fix deadlock when reloading a multipath table 2025-10-09 23:29 ` Bart Van Assche 2025-10-10 0:39 ` Benjamin Marzinski @ 2025-10-10 9:23 ` Martin Wilck 1 sibling, 0 replies; 10+ messages in thread From: Martin Wilck @ 2025-10-10 9:23 UTC (permalink / raw) To: Bart Van Assche, Benjamin Marzinski, Mikulas Patocka, Mike Snitzer Cc: dm-devel, linux-block Hi Bart, On Thu, 2025-10-09 at 16:29 -0700, Bart Van Assche wrote: > On 10/9/25 2:57 AM, Martin Wilck wrote: > > In general, I'm wondering whether we need a more generic solution > > to > > this problem. Therefore I've added linux-block to cc. > > > > The way I see it, if a device has queued IO without any means to > > perform the IO, it can't be frozen. We'd either need to fail all > > queued > > IO in this case, or refuse attempts to freeze the queue. > > If a device has queued I/O and the I/O can't make progress then it > isn't > necessary to call blk_mq_freeze_queue(), isn't it? Good point. Even if the queue limits were changed while the IO was in the queue, they'd be re-checked in blk_insert_cloned_request(). That might cause IO failures, but if you modify queue limits while IO is in flight, that's part of the risk, I suppose. > See also "[PATCH 0/3] > Fix a deadlock related to modifying queue attributes" > ( > https://lore.kernel.org/linux-block/20250702182430.3764163-1-bvanassche@acm.org > /). > > BTW, that patch series is not upstream. I apply it manually every > time > before I run blktests. Will you make another attempt to get it merged? Martin ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-10-23 17:54 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20251009030431.2895495-1-bmarzins@redhat.com>
2025-10-09 9:57 ` [PATCH] dm: Fix deadlock when reloading a multipath table Martin Wilck
2025-10-09 22:25 ` Benjamin Marzinski
2025-10-10 10:19 ` Martin Wilck
2025-10-21 19:16 ` Benjamin Marzinski
2025-10-22 14:11 ` Martin Wilck
2025-10-23 17:39 ` Benjamin Marzinski
2025-10-23 17:54 ` Bart Van Assche
2025-10-09 23:29 ` Bart Van Assche
2025-10-10 0:39 ` Benjamin Marzinski
2025-10-10 9:23 ` Martin Wilck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).