All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
To: no-reply@sashiko.virtuozzo.com, den@openvz.org
Cc: devel@openvz.org
Subject: Re: [Devel] [PATCH hci-8.1 v6 11/12] dm-ploop: reload metadata on resume
Date: Tue, 13 Oct 2026 14:46:25 +0200	[thread overview]
Message-ID: <797d8cba-d64c-453b-9711-2287223f4d11@virtuozzo.com> (raw)
In-Reply-To: <010701a1350c284d-137ccce0-774e-492c-ab3b-2a320c743e99-000000@eu-central-1.amazonses.com>


On 10/13/26 13:35, no-reply@sashiko.virtuozzo.com wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [Medium] dm-ploop: postsuspend waits unkillably on inflight_md even in standby
> - [Medium] dm-ploop: killed wait in postsuspend() leaves prealloc pending after device is marked suspended
> --
>
> commit 881f9bc269db1bbaa88bf766f12f3d91d98c7d92
> Author: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
>
> dm-ploop: reload metadata on resume
>
> This patch reloads the top delta header, the BAT of every delta and the
> delta file sizes in ploop_preresume(), and rebuilds the BAT tree and
> holes_bitmap. It also moves preallocation to after the reload and makes
> postsuspend wait for pending preallocation and for inflight_md. Standby
> state is now tracked per ploop instead of through the queue bit.
>
> Link: https://virtuozzo.atlassian.net/browse/VSTOR-148171
>
>> diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
>> --- a/drivers/md/dm-ploop-map.c
>> +++ b/drivers/md/dm-ploop-map.c
> [ ... ]
>
>> @@ -1259,6 +1259,12 @@ static int ploop_no_pending_prealloc(struct ploop *ploop)
>>   	return ret;
>>   }
>>   
>> +void ploop_wait_prealloc(struct ploop *ploop)
>> +{
>> +	wait_event_killable(ploop->dispatcher_wq_prealloc,
>> +			    ploop_no_pending_prealloc(ploop));
>> +}
>> +
> [Severity: Medium]
> The return value of wait_event_killable() is discarded here, so a killed
> wait looks the same as a completed one to the caller.
>
> Can this leave a prealloc pending after the device is marked suspended?
>
> Suppose the dmsetup task gets a fatal signal while ploop_postsuspend() is
> in ploop_wait_prealloc(), and prealloc_size or prealloc_in_progress is
> still non-zero. Then:
>
> ploop_postsuspend()
>      ploop_wait_prealloc()          /* returns -ERESTARTSYS, ignored */
>      wait_event(ploop->inflight_md_wq, ...);
>      ploop_set_suspended(ti, true);
>
> The postsuspend callback returns void, so dm_suspend() cannot abort. The
> old allocator thread keeps running and can still extend or truncate the top
> delta.
>
> The new ploop's ploop_preresume() checks only its own prealloc state, which
> is zero:
>
> ploop_preresume()
>      } else if (!ploop_is_standby(ploop) &&
>                 ploop_no_pending_prealloc(ploop)) {
>          reload = true;
>          ...
>          ret = ploop_reload_metadata(ploop);
>
> It therefore reloads and caches a file size that the old allocator is still
> changing. Can the old allocator's later truncate then cut off clusters that
> the new ploop has already written?
>
> The new comment in ploop_postsuspend() says "a ploop of a reloaded table may
> see a stale size, and a late truncate of our allocator may shrink the file
> under it", but nothing in the code prevents that outcome. Is there a way to
> detect the killed wait, for example by checking the return value and
> refusing to proceed?
Known and documented: it needs a reload plus a fatal signal exactly 
during this wait. Postsuspend can't fail, so there's no way to refuse, 
and having no wait at all was strictly worse.
>> diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
>> --- a/drivers/md/dm-ploop-target.c
>> +++ b/drivers/md/dm-ploop-target.c
> [ ... ]
>
>>   static void ploop_postsuspend(struct dm_target *ti)
>>   {
>> +	struct ploop *ploop = ti->private;
>> +
>> +	/*
>> +	 * Let the next resumed ploop (maybe of reloaded table)
>> +	 * see final size of the top delta. Don't wait in standby
>> +	 * mode: the allocator may be stuck on the dead file, while
>> +	 * dm_replace() of libploop must be able to suspend the device
>> +	 * to recover it. The wait is killable for the same reason.
>> +	 * If the wait is skipped or killed, a ploop of a reloaded
>> +	 * table may see a stale size, and a late truncate of our
>> +	 * allocator may shrink the file under it.
>> +	 */
>> +	if (!ploop_is_standby(ploop))
>> +		ploop_wait_prealloc(ploop);
>> +	/*
>> +	 * Data bios are completed before BAT writeback is finished
>> +	 * (see ploop_put_piwb()), so wait for it explicitly to make
>> +	 * md pages clean for ploop_reload_metadata().
>> +	 */
>> +	wait_event(ploop->inflight_md_wq, !atomic_read(&ploop->inflight_md));
> [Severity: Medium]
> The prealloc wait above is skipped in standby and is killable, because the
> comment says the allocator may be stuck on a dead file. The inflight_md
> wait here is neither.
>
> Can this wait_event() hang suspend in uninterruptible sleep on a failing
> device?
>
> inflight_md only drops when the BAT write pio completes:
>
> ploop_index_wb_submit()
>      ploop_runners_add_work(ploop, pio);   /* file IO on the top delta */
> ...
> ploop_put_piwb()
>      ploop_dec_inflight_md()
>          if (atomic_dec_and_test(&ploop->inflight_md))
>              wake_up_locked(&ploop->inflight_md_wq);
>
> If the device is in standby because of a hung backing file and a BAT write
> is in flight on that same file, inflight_md never reaches zero.
> ploop_presuspend() only waits for kt_worker->inflight_pios, so it does not
> drain this.
>
> Before this patch postsuspend never waited on inflight_md, so dm_replace()
> could suspend such a device. Should this wait also be skipped in standby
> and made killable, like ploop_wait_prealloc()?
>
> A follow-up patch in the series, 'dm-ploop: truncate unused tail of top
> delta on suspend', keeps this wait_event() unchanged and moves the call
> under ctl_rwsem, so a hang there would hold ctl_rwsem for write while
> waiting.
Skipping the wait or making it killable just moves the hang to resume or 
dtr, which must wait for in-flight BAT writes anyway. Unlike the 
allocator, a BAT write is a plain pio, so it completes, with an error if 
need be. If the file is dead enough for it to hang, data IO hangs too 
and suspend never gets this far.
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-10-13 12:48 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 11:15 [Devel] [PATCH hci-8.1 v6 00/12] dm-ploop: give back unused tail of top delta on suspend Alexander Ivanov
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 01/12] dm-ploop: fix u32 overflow of the delta BAT byte size Alexander Ivanov
2026-10-13 11:23   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 02/12] dm-ploop: fix lost wakeup in ploop_allocator() Alexander Ivanov
2026-10-13 11:21   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 03/12] dm-ploop: reject a delta header whose BAT does not cover the target Alexander Ivanov
2026-10-13 11:22   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 04/12] dm-ploop: reject empty deltas Alexander Ivanov
2026-10-13 11:24   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 05/12] dm-ploop: set delta is_raw before applying its mappings Alexander Ivanov
2026-10-13 11:24   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 06/12] dm-ploop: factor out ploop_read_delta() from ploop_add_delta() Alexander Ivanov
2026-10-13 11:25   ` no-reply
2026-10-13 11:15 ` [Devel] [PATCH hci-8.1 v6 07/12] dm-ploop: take bat_lock around md page lookup in ploop_llseek_hole() Alexander Ivanov
2026-10-13 11:26   ` no-reply
2026-10-13 11:16 ` [Devel] [PATCH hci-8.1 v6 08/12] dm-ploop: use wake_up() for inflight_md_wq and dispatcher_wq_prealloc Alexander Ivanov
2026-10-13 11:26   ` no-reply
2026-10-13 11:16 ` [Devel] [PATCH hci-8.1 v6 09/12] dm-ploop: fix use-after-free on the last inflight_md decrement Alexander Ivanov
2026-10-13 11:30   ` no-reply
2026-10-13 11:16 ` [Devel] [PATCH hci-8.1 v6 10/12] dm-ploop: fix flip_upper_deltas racing with resume Alexander Ivanov
2026-10-13 11:28   ` no-reply
2026-10-13 11:16 ` [Devel] [PATCH hci-8.1 v6 11/12] dm-ploop: reload metadata on resume Alexander Ivanov
2026-10-13 11:35   ` no-reply
2026-10-13 12:46     ` Alexander Ivanov [this message]
2026-10-13 11:16 ` [Devel] [PATCH hci-8.1 v6 12/12] dm-ploop: truncate unused tail of top delta on suspend Alexander Ivanov
2026-10-13 11:38   ` no-reply
2026-10-13 12:53     ` Alexander Ivanov

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=797d8cba-d64c-453b-9711-2287223f4d11@virtuozzo.com \
    --to=alexander.ivanov@virtuozzo.com \
    --cc=den@openvz.org \
    --cc=devel@openvz.org \
    --cc=no-reply@sashiko.virtuozzo.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.