OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox