From: Christoph Hellwig <hch@lst.de>
To: Jens Axboe <axboe@kernel.dk>
Cc: Caleb Sander Mateos <csander@purestorage.com>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
linux-block@vger.kernel.org
Subject: [PATCH 1/2] block: fix GFP_ flags confusion in bio_integrity_alloc_buf
Date: Tue, 23 Jun 2026 16:29:48 +0200 [thread overview]
Message-ID: <20260623142957.1839474-2-hch@lst.de> (raw)
In-Reply-To: <20260623142957.1839474-1-hch@lst.de>
bio_integrity_alloc_buf usage of GFP_ flags is messed up. For one it
mixes GFP_NOFS and GFP_NOIO for neighbouring allocations, but it also
makes the allocations fail more often than needed. That code was copied
from bio_alloc_bioset which needs to do that so that it can punt to the
rescuer workqueue, but none of that is needed for the integrity
allocations that either sits in the file system or at the very bottom
of the I/O stack. Failing early means we'll do a fully waiting
allocation from the mempool ->alloc callback which is usually much
larger than required.
Fix this by passing a gfp_t so that the file system path can pass
GFP_NOFS and the auto-integrity code can pass GFP_NOIO, and don't
modify the allocation type except for disabling warnings.
Fixes: ec7f31b2a2d3 ("block: make bio auto-integrity deadlock safe")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio-integrity-auto.c | 2 +-
block/bio-integrity-fs.c | 4 ++--
block/bio-integrity.c | 8 +++-----
include/linux/bio-integrity.h | 2 +-
4 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c
index 353eed632fcc..b1c733ecfd2e 100644
--- a/block/bio-integrity-auto.c
+++ b/block/bio-integrity-auto.c
@@ -94,7 +94,7 @@ void bio_integrity_prep(struct bio *bio, unsigned int action)
bio_integrity_init(bio, &bid->bip, &bid->bvec, 1);
bid->bio = bio;
bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY;
- bio_integrity_alloc_buf(bio, action & BI_ACT_ZERO);
+ bio_integrity_alloc_buf(bio, GFP_NOIO, action & BI_ACT_ZERO);
if (action & BI_ACT_CHECK)
bio_integrity_setup_default(bio);
diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
index 0daa42d9ead7..9c5fe5fa8f0d 100644
--- a/block/bio-integrity-fs.c
+++ b/block/bio-integrity-fs.c
@@ -23,10 +23,10 @@ unsigned int fs_bio_integrity_alloc(struct bio *bio)
if (!action)
return 0;
- iib = mempool_alloc(&fs_bio_integrity_pool, GFP_NOIO);
+ iib = mempool_alloc(&fs_bio_integrity_pool, GFP_NOFS);
bio_integrity_init(bio, &iib->bip, &iib->bvec, 1);
- bio_integrity_alloc_buf(bio, action & BI_ACT_ZERO);
+ bio_integrity_alloc_buf(bio, GFP_NOFS, action & BI_ACT_ZERO);
if (action & BI_ACT_CHECK)
bio_integrity_setup_default(bio);
return action;
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index e796de1a749e..488eba228c6e 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -64,20 +64,18 @@ unsigned int __bio_integrity_action(struct bio *bio)
}
EXPORT_SYMBOL_GPL(__bio_integrity_action);
-void bio_integrity_alloc_buf(struct bio *bio, bool zero_buffer)
+void bio_integrity_alloc_buf(struct bio *bio, gfp_t gfp, bool zero_buffer)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
unsigned int len = bio_integrity_bytes(bi, bio_sectors(bio));
- gfp_t gfp = GFP_NOIO | (zero_buffer ? __GFP_ZERO : 0);
void *buf;
- buf = kmalloc(len, (gfp & ~__GFP_DIRECT_RECLAIM) |
- __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN);
+ buf = kmalloc(len, gfp | __GFP_NOWARN | zero_buffer ? __GFP_ZERO : 0);
if (unlikely(!buf)) {
struct page *page;
- page = mempool_alloc(&integrity_buf_pool, GFP_NOFS);
+ page = mempool_alloc(&integrity_buf_pool, gfp);
if (zero_buffer)
memset(page_address(page), 0, len);
bvec_set_page(&bip->bip_vec[0], page, len, 0);
diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
index af5178434ec6..c3dda32fd803 100644
--- a/include/linux/bio-integrity.h
+++ b/include/linux/bio-integrity.h
@@ -141,7 +141,7 @@ static inline int bio_integrity_add_page(struct bio *bio, struct page *page,
}
#endif /* CONFIG_BLK_DEV_INTEGRITY */
-void bio_integrity_alloc_buf(struct bio *bio, bool zero_buffer);
+void bio_integrity_alloc_buf(struct bio *bio, gfp_t gfp, bool zero_buffer);
void bio_integrity_free_buf(struct bio_integrity_payload *bip);
void bio_integrity_setup_default(struct bio *bio);
--
2.53.0
next prev parent reply other threads:[~2026-06-23 14:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-23 14:29 PI fixes Christoph Hellwig
2026-06-23 14:29 ` Christoph Hellwig [this message]
2026-06-23 14:29 ` [PATCH 2/2] block: handle REQ_OP_ZONE_APPEND in __bio_integrity_action Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2026-06-24 8:00 PI fixes v2 Christoph Hellwig
2026-06-24 8:00 ` [PATCH 1/2] block: fix GFP_ flags confusion in bio_integrity_alloc_buf Christoph Hellwig
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=20260623142957.1839474-2-hch@lst.de \
--to=hch@lst.de \
--cc=axboe@kernel.dk \
--cc=csander@purestorage.com \
--cc=linux-block@vger.kernel.org \
--cc=martin.petersen@oracle.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