All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>,
	Konstantin Khorenko <khorenko@virtuozzo.com>
Cc: devel@openvz.org
Subject: Re: [Devel] [PATCH hci-8.1] block/blk-cbt: account a write request also when dm starts it
Date: Fri, 16 Oct 2026 14:41:42 +0000	[thread overview]
Message-ID: <010701a145296351-ade7da64-7c3b-4c0f-a16c-fce44a18603f-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261016-ptikhomirov-vstor-149268-cbt-account-at-rq-start-v1-1-1f20b151431d@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] block: cbt_page_alloc() GFP_ATOMIC failure sets CBT_ERROR on dm dispatch path
--

commit 07126a82d2afc4a47285774d1cb334f3398a6e89
Author: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

block/blk-cbt: account a write request also when dm starts it

This patch adds blk_cbt_rq_start(), called from dm_start_request(), so a
write is accounted in CBT a second time when request based dm starts it.
A missing bitmap page is allocated with GFP_ATOMIC in this path, and
CBT_ERROR is set if that allocation fails.

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

> diff --git a/block/blk-cbt.c b/block/blk-cbt.c
> --- a/block/blk-cbt.c
> +++ b/block/blk-cbt.c

[ ... ]

> @@ -129,11 +137,15 @@ static int cbt_page_alloc(struct cbt_info  **cbt_pp, unsigned long idx,
>  		}
>  	}
>  	spin_unlock_irq(&cbt->lock);
> -	if (in_rcu)
> -		rcu_read_unlock();
> -	page = alloc_page(GFP_NOIO|__GFP_ZERO);
> -	if (in_rcu)
> -		rcu_read_lock();
> +	if (alloc == CBT_ALLOC_ATOMIC) {
> +		page = alloc_page(GFP_ATOMIC | __GFP_ZERO | __GFP_NOWARN);

[Severity: Medium]
Can this GFP_ATOMIC allocation fail often enough to matter?

Under memory pressure alloc_page(GFP_ATOMIC) has no direct reclaim and
can fail.  When it does, a few lines further down in cbt_page_alloc():

	if (unlikely(!page)) {
		set_bit(CBT_ERROR, &cbt->flags);
		spin_unlock_irq(&cbt->lock);
		return -ENOMEM;
	}

CBT_ERROR is a sticky flag, and __GFP_NOWARN makes the failure silent.
The call chain is:

dm_mq_queue_rq()
  dm_start_request()
    blk_cbt_rq_start()
      blk_cbt_add(..., CBT_ALLOC_ATOMIC)
        __blk_cbt_set()
          cbt_page_alloc()

Neither blk_cbt_rq_start() nor blk_cbt_add() checks the return value.

After the failure, blk_cbt_add() returns early for this CBT on every
later write:

	if (unlikely(test_bit(CBT_ERROR, &cbt->flags)))
		return;

cbt_ioc_get() and cbt_ioc_set() then return -EIO.

So a transient atomic allocation failure permanently invalidates the CBT,
and with it the incremental backup chain, until the CBT is re-created.
The old submission time path used GFP_NOIO with the RCU lock dropped,
which does not fail in practice.

Is there a reason not to retry from a sleepable context, or to avoid
setting CBT_ERROR in the atomic case?

[ ... ]

> @@ -248,7 +261,7 @@ static void blk_cbt_add(struct cbt_info *cbt, blkcnt_t start, blkcnt_t len,
>  	put_cpu_ptr(cbt->cache);
>  
>  	if (likely(old.len))
> -		__blk_cbt_set(cbt, old.start, old.len, 1, 1, NULL, NULL);
> +		__blk_cbt_set(cbt, old.start, old.len, alloc, 1, NULL, NULL);

[Severity: Medium]
Is the commit message claim correct that a page can be missing here only
for requests submitted before BLKCBTSTART?

The commit message says:

  "This only happens for requests submitted before BLKCBTSTART: any later
  write has its page allocated already by its submission time accounting."

On the normal (cached) path, blk_cbt_add() only records the extent in the
per-CPU cache.  It calls __blk_cbt_set(), and so allocates pages, only
for the evicted old extent.

That means a write submitted after BLKCBTSTART can still have no bitmap
page when dm_start_request() runs.

In blk_cbt_rq_start(), re-adding a range that is not contiguous with the
cached extent evicts the previous cached extent, which is often an
unrelated earlier write.  That extent is flushed with CBT_ALLOC_ATOMIC.

So GFP_ATOMIC page allocation looks possible on ordinary write-heavy
workloads, not only in the narrow pre-BLKCBTSTART window.

Also, re-adding the same range from blk_cbt_rq_start() never coalesces,
since ex->start + ex->len != start for it.  Each started request
therefore causes an extra __blk_cbt_set() call and bitmap page lock.

Could the commit message and the allocation strategy be revisited in
light of this?

[ ... ]

> +void blk_cbt_rq_start(struct request *rq)
> +{

[ ... ]

> +			blk_cbt_add(cbt, bio->bi_iter.bi_sector << 9,
> +				    bio->bi_iter.bi_size, CBT_ALLOC_ATOMIC);

[Severity: Medium]
This is the same issue as above, seen from the caller.  Errors from
blk_cbt_add() are dropped here, so a CBT_ERROR set by a failed
GFP_ATOMIC allocation in blk_cbt_rq_start() is not reported to the dm
dispatch path.  Is that intended?

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261016-ptikhomirov-vstor-149268-cbt-account-at-rq-start-v1-1-1f20b151431d@virtuozzo.com?part=1

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

      reply	other threads:[~2026-10-16 14:43 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 14:34 Pavel Tikhomirov
2026-10-16 14:41 ` no-reply [this message]

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=010701a145296351-ade7da64-7c3b-4c0f-a16c-fce44a18603f-000000@eu-central-1.amazonses.com \
    --to=no-reply@sashiko.virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=khorenko@virtuozzo.com \
    --cc=ptikhomirov@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.