OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>,
	alexander.ivanov@virtuozzo.com
Cc: devel@openvz.org
Subject: Re: [Devel] [PATCH hci-8.1 v2 5/6] drivers/md/push_backup: arm deadline timer under pb->lock
Date: Tue, 3 Nov 2026 00:45:10 +0000	[thread overview]
Message-ID: <010701a19eddfd03-932afd84-2433-4230-8b72-0006eefac554-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261103003246.712239-6-andrey.zhadchenko@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] dm-push-backup: pb_timer_func() can re-arm timer or queue work after stop/destroy
- [Medium] dm-push-backup: pb_destroy() uses non-waiting timer_delete_sync_try() instead of timer_shutdown_sync()
- [Medium] dm-push-backup: cleanup_backup() leaves deadline_jiffies stale, so a racing timer callback can re-arm or queue_work()
--

commit f322079c9ebbcb0d0c2a4b8257ff8a52b4e79a15
Author: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>

drivers/md/push_backup: arm deadline timer under pb->lock

This patch moves the mod_timer() calls in pb_timer_func() and
postpone_if_required_for_backup() under pb->lock. It also makes the timer
callback idle when deadline_jiffies is S64_MAX. It drops the
rcu_read_lock()/synchronize_rcu() pairing between
postpone_if_required_for_backup() and push_backup_stop().

Link: https://virtuozzo.atlassian.net/browse/VSTOR-152912

> diff --git a/drivers/md/dm-push-backup.c b/drivers/md/dm-push-backup.c
> --- a/drivers/md/dm-push-backup.c
> +++ b/drivers/md/dm-push-backup.c

[ ... ]

> @@ -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 (deadline == S64_MAX)
> +		goto unlock; /* Nothing is delayed, let the timer idle */
>  	if (unlikely(time_before64(now, deadline)))
>  		mod_timer(timer, jiffies + (deadline - now) + 1);
>  	else
>  		queue_work(pb->wq, &pb->worker);
> +unlock:
> +	spin_unlock_irqrestore(&pb->lock, flags);
>  }

[Severity: Medium]
Can pb_timer_func() re-arm the timer or queue work after push_backup_stop()
has returned?

The callback does not check pb->alive. It only tests deadline_jiffies
against S64_MAX. cleanup_backup() sets pb->alive = false and drains
nr_delayed to 0, but it leaves deadline_jiffies at its old finite value.
Only setup_pb() and push_backup_write() write S64_MAX.

Consider this sequence:

CPU1
pb_timer_func()
    blocks on spin_lock_irqsave(&pb->lock)

CPU0
push_backup_stop()
    cleanup_backup()
        pb->alive = false;
        (deadline_jiffies still finite)
    timer_delete_sync_try()   <- returns -1, callback is running

CPU1 then takes pb->lock, sees a finite deadline, and calls mod_timer()
or queue_work(pb->wq, &pb->worker). If push_backup_start() has already run
for a new session, the stale do_pb_work() could call cleanup_backup() and
expire that session early.

Should cleanup_backup() set pb->deadline_jiffies = S64_MAX under pb->lock,
or should pb_timer_func() check pb->alive?

> @@ -272,16 +273,13 @@ static int postpone_if_required_for_backup(struct push_backup *pb,

[ ... ]

> @@ -400,8 +398,6 @@ static int push_backup_stop(struct push_backup *pb,
>  		return -EBADF;
>  	cleanup_backup(pb);
>  
> -	/* Wait postpone_if_required_for_backup() starts timer */
> -	synchronize_rcu();
>  	WARN_ON_ONCE(timer_delete_sync_try(&pb->deadline_timer) < 0);
>  	flush_workqueue(pb->wq);

[Severity: Medium]
The commit message says "the callback re-arming itself is handled by
timer_delete_sync_try()". Is that accurate?

timer_delete_sync_try() calls __try_to_del_timer_sync(timer, false). That
returns -1 without waiting when base->running_timer == timer, and it does
not prevent re-arming. Here the -1 result only triggers WARN_ON_ONCE().

The removed synchronize_rcu() only covered
postpone_if_required_for_backup() arming the timer. It never covered the
callback re-arming itself.

So after this change, can the callback still call mod_timer() or
queue_work() after flush_workqueue() has returned? Would
timer_shutdown_sync(), or a loop that waits for the running callback,
be more appropriate here?

The same WARN_ON_ONCE(timer_delete_sync_try(&pb->deadline_timer) < 0)
pattern in pb_destroy() is not touched by this patch. It runs before
destroy_workqueue(pb->wq) and pb_put(pb).

If pb_timer_func() is running on another CPU and blocked on pb->lock, can
it call queue_work() on a destroyed workqueue? Can it also touch pb after
it has been freed? When pb_destroy() runs without a prior push_backup_stop(),
pb->alive is still true and a finite deadline can still exist. Would
timer_shutdown_sync() be the right call in pb_destroy()?

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261103003246.712239-1-andrey.zhadchenko@virtuozzo.com?part=5

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

  reply	other threads:[~2026-11-03  0:46 UTC|newest]

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

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=010701a19eddfd03-932afd84-2433-4230-8b72-0006eefac554-000000@eu-central-1.amazonses.com \
    --to=no-reply@sashiko.virtuozzo.com \
    --cc=alexander.ivanov@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox