All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
Cc: devel@openvz.org
Subject: Re: [Devel] [PATCH hci-8.1 v4 5/6] drivers/md/push_backup: arm deadline timer under pb->lock
Date: Tue, 03 Nov 2026 11:11:03 +0100	[thread overview]
Message-ID: <179370066312.2382033.8474782518776715664.b4-review@b4> (raw)
In-Reply-To: <20261103080358.723186-6-andrey.zhadchenko@virtuozzo.com>

On 11/3/26 11:03, Andrey Zhadchenko wrote:
> When push_backup_write acks last delayed request it sets
> deadline_jiffies = S64_MAX and the next fired timer uses this
> for mod_timer(): expiry is set to some very distant future.
>
> Previously a later push_backup_write() would accidentally
> repair the expiry; since it no longer touches the timer, nothing
> does until stop.

Hi Andrey,

When the callback parks the timer this way, nothing is delayed, and the
next delayed write takes the nr_delayed == 1 branch in
postpone_if_required_for_backup(), which arms the timer itself. So this
case is harmless and "nothing does until stop" does not hold. The real
bug is the race item 5 of your cover letter describes: the callback
reads S64_MAX under the lock, postpone arms a fresh deadline, and the
late mod_timer() of the callback overwrites it while writes are
delayed. Could these two paragraphs describe that instead?

> A callback blocked on pb->lock could thus outlive stop and re-arm the
> timer or queue do_pb_work() after flush_workqueue(), expiring a later
> session.

A small precision: synchronize_rcu() already waited for a callback that
was running, or spinning on pb->lock, when it started, because the
timer softirq is an RCU reader. What escaped is a firing that starts
after the grace period.

> @@ -241,23 +241,24 @@ static void pb_timer_func(struct timer_list *timer)
>  
>  	spin_lock_irqsave(&pb->lock, flags);
>  	deadline = pb->deadline_jiffies;
> -	spin_unlock_irqrestore(&pb->lock, flags);
> -
> +	if (!pb->alive || deadline == S64_MAX)
> +		goto unlock;

pb->alive is not cleared by cleanup_backup() only. pb_message() clears
it for "push_backup_stop" before it takes ctl_rwsem, on purpose since
6cd7e75f682f ("dm/push_backup: Allow to stop push_backup at any
time"):

	spin_lock_irq(&pb->lock);
	pb->alive = false;
	spin_unlock_irq(&pb->lock);
	...
	ret = down_write_killable(&pb->ctl_rwsem);
	...
	if (unlikely(ret))
		goto out;

If the stopping tool gets a fatal signal while the rwsem is held by
another message, push_backup_stop() never runs. alive is false,
nr_delayed is non-zero and the deadline is real. Before this patch the
timer still expired it and do_pb_work() released the guest writes.
With this hunk the callback returns and does not re-arm, read() and
write() on the fd return -ESTALE, and the writes hang until somebody
sends "push_backup_stop" again. dm suspend, "@stats_create" and remove
wait for them meanwhile.

Checking nr_delayed instead keeps what the patch relies on:

	if (!pb->nr_delayed)
		goto unlock;

cleanup_backup() zeroes nr_delayed under the same lock hold that clears
alive, and postpone only delays while alive. So after stop the callback
still neither re-arms nor queues work, and in the state above it expires
the deadline as before. While alive, deadline == S64_MAX is the same as
nr_delayed == 0.

> -	WARN_ON_ONCE(timer_delete_sync_try(&pb->deadline_timer) < 0);
> +	timer_shutdown_sync(&pb->deadline_timer);

This also fixes a use-after-free: removing the target while the
callback ran made pb_destroy() WARN and go on to destroy_workqueue()
and kfree(pb) under it. Both that and the stop race came with the
driver, so please add:

Fixes: 62e07487348e ("dm: Add push backup driver")

-- 
Konstantin Khorenko,
Virtuozzo Linux Kernel Team

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  parent reply	other threads:[~2026-11-03 10:12 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03  8:03 [Devel] [PATCH hci-8.1 v4 0/6] dm/push_backup: event fd interface and fixes Andrey Zhadchenko
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 1/6] drivers/md/push_backup: correct initialization Andrey Zhadchenko
2026-11-03  8:11   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 2/6] drivers/md/push_backup: clear pb->alive under pb->lock Andrey Zhadchenko
2026-11-03  8:11   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 3/6] drivers/md/push_backup: do not re-arm deadline timer in push_backup_write() Andrey Zhadchenko
2026-11-03  8:13   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 4/6] drivers/md/push_backup: fix mod_timer() usage Andrey Zhadchenko
2026-11-03  8:12   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 5/6] drivers/md/push_backup: arm deadline timer under pb->lock Andrey Zhadchenko
2026-11-03  8:14   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko [this message]
2026-11-03  8:03 ` [Devel] [PATCH hci-8.1 v4 6/6] drivers/md/push_backup: add event file descriptor interface Andrey Zhadchenko
2026-11-03  8:17   ` no-reply
2026-11-03 10:11   ` Konstantin Khorenko
2026-11-03 12:38     ` Andrey Zhadchenko
2026-11-03 10:11 ` [Devel] [PATCH hci-8.1 v4 0/6] dm/push_backup: event fd interface and fixes Konstantin Khorenko

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=179370066312.2382033.8474782518776715664.b4-review@b4 \
    --to=khorenko@virtuozzo.com \
    --cc=andrey.zhadchenko@virtuozzo.com \
    --cc=devel@openvz.org \
    /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.