* [PATCH v2] t10-pi: reduce ref tag code duplication
From: Caleb Sander Mateos @ 2026-04-15 21:08 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, linux-kernel, Christoph Hellwig, Caleb Sander Mateos,
Anuj Gupta
t10_pi_ref_tag() and ext_pi_ref_tag() are identical except for the final
truncation of the ref tag to 32 or 48 bits. Factor out a helper
full_pi_ref_tag() to return the untruncated ref tag and use it in
t10_pi_ref_tag() and ext_pi_ref_tag().
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
---
v2:
- Move full_pi_ref_tag() earlier (Christoph)
- Use lower_32_bits() (Christoph)
include/linux/t10-pi.h | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h
index 2c59fe3efcd4..b6c2496866ea 100644
--- a/include/linux/t10-pi.h
+++ b/include/linux/t10-pi.h
@@ -2,10 +2,11 @@
#ifndef _LINUX_T10_PI_H
#define _LINUX_T10_PI_H
#include <linux/types.h>
#include <linux/blk-mq.h>
+#include <linux/wordpart.h>
/*
* A T10 PI-capable target device can be formatted with different
* protection schemes. Currently 0 through 3 are defined:
*
@@ -23,10 +24,20 @@ enum t10_dif_type {
T10_PI_TYPE1_PROTECTION = 0x1,
T10_PI_TYPE2_PROTECTION = 0x2,
T10_PI_TYPE3_PROTECTION = 0x3,
};
+static inline u64 full_pi_ref_tag(const struct request *rq)
+{
+ unsigned int shift = ilog2(queue_logical_block_size(rq->q));
+
+ if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
+ rq->q->limits.integrity.interval_exp)
+ shift = rq->q->limits.integrity.interval_exp;
+ return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT);
+}
+
/*
* T10 Protection Information tuple.
*/
struct t10_pi_tuple {
__be16 guard_tag; /* Checksum */
@@ -37,16 +48,11 @@ struct t10_pi_tuple {
#define T10_PI_APP_ESCAPE cpu_to_be16(0xffff)
#define T10_PI_REF_ESCAPE cpu_to_be32(0xffffffff)
static inline u32 t10_pi_ref_tag(struct request *rq)
{
- unsigned int shift = ilog2(queue_logical_block_size(rq->q));
-
- if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
- rq->q->limits.integrity.interval_exp)
- shift = rq->q->limits.integrity.interval_exp;
- return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
+ return lower_32_bits(full_pi_ref_tag(rq));
}
struct crc64_pi_tuple {
__be64 guard_tag;
__be16 app_tag;
@@ -62,14 +68,9 @@ static inline u64 lower_48_bits(u64 n)
return n & ((1ull << 48) - 1);
}
static inline u64 ext_pi_ref_tag(struct request *rq)
{
- unsigned int shift = ilog2(queue_logical_block_size(rq->q));
-
- if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
- rq->q->limits.integrity.interval_exp)
- shift = rq->q->limits.integrity.interval_exp;
- return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT));
+ return lower_48_bits(full_pi_ref_tag(rq));
}
#endif
--
2.45.2
^ permalink raw reply related
* Re: [REGRESSION][BISECTED] Spurious raid1 device failure triggered by qemu direct IO on 6.18+
From: Keith Busch @ 2026-04-15 22:59 UTC (permalink / raw)
To: Tomás Trnka; +Cc: Jens Axboe, linux-kernel, regressions, linux-block
In-Reply-To: <ad-0LIubzaT8M2_O@kbusch-mbp>
On Wed, Apr 15, 2026 at 09:52:12AM -0600, Keith Busch wrote:
> Suggest the stacking layers shouldn't consider BLK_STS_INVAL to be a
> device error or retryable.
I was able to recreate the reported issue (the key is you have to use
dm-raid, not md-raid), and the below diff tests successfully for me.
I'll send a formal patch tomorrow.
> ---
> diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
> index c33099925f230..cf1c25f290f36 100644
> --- a/drivers/md/raid1-10.c
> +++ b/drivers/md/raid1-10.c
> @@ -293,8 +293,16 @@ static inline bool raid1_should_read_first(struct mddev *mddev,
> * bio with REQ_RAHEAD or REQ_NOWAIT can fail at anytime, before such IO is
> * submitted to the underlying disks, hence don't record badblocks or retry
> * in this case.
> + *
> + * BLK_STS_INVAL means the request itself is malformed (e.g. unaligned
> + * buffers that violate DMA constraints). Retrying on another mirror will
> + * fail the same way, and counting it against the device is wrong.
> */
> static inline bool raid1_should_handle_error(struct bio *bio)
> {
> - return !(bio->bi_opf & (REQ_RAHEAD | REQ_NOWAIT));
> + if (bio->bi_opf & (REQ_RAHEAD | REQ_NOWAIT))
> + return false;
> + if (bio->bi_status == BLK_STS_INVAL)
> + return false;
> + return true;
> }
> --
>
^ permalink raw reply
* [PATCH V3] ublk: use unchecked copy helpers for bio page data
From: Ming Lei @ 2026-04-15 23:02 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Caleb Sander Mateos, Ming Lei
From: Ming Lei <ming.lei@redhat.com>
Bio pages may originate from slab caches that lack a usercopy region
(e.g. jbd2 frozen metadata buffers allocated via jbd2_alloc()).
When CONFIG_HARDENED_USERCOPY is enabled, copy_to_iter() calls
check_copy_size() which rejects these slab pages, triggering a
kernel BUG in usercopy_abort().
This is a false positive: the data is ordinary block I/O content —
the same data the loop driver writes to its backing file via
vfs_iter_write(). The bvec length is always trusted, so the size
check in check_copy_size() is not needed either.
Switch to _copy_to_iter()/_copy_from_iter() which skip the
check_copy_size() wrapper while the underlying copy_to_user()
remains unchanged.
Acked-by: Caleb Sander Mateos <csander@purestorage.com>
Fixes: 2299ceec364e ("ublk: use copy_{to,from}_iter() for user copy")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
V3:
- rebase & add acked-by tag
V2:
- update commit log (Caleb Sander Mateos)
drivers/block/ublk_drv.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 603a98a30989..ef8a0705e68b 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1319,10 +1319,18 @@ static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
len = bv->bv_len - *offset;
bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
+ /*
+ * Bio pages may originate from slab caches without a usercopy region
+ * (e.g. jbd2 frozen metadata buffers). This is the same data that
+ * the loop driver writes to its backing file — no exposure risk.
+ * The bvec length is always trusted, so the size check in
+ * check_copy_size() is not needed either. Use the unchecked
+ * helpers to avoid false positives on slab pages.
+ */
if (dir == ITER_DEST)
- copied = copy_to_iter(bv_buf, len, uiter);
+ copied = _copy_to_iter(bv_buf, len, uiter);
else
- copied = copy_from_iter(bv_buf, len, uiter);
+ copied = _copy_from_iter(bv_buf, len, uiter);
kunmap_local(bv_buf);
--
2.53.0
^ permalink raw reply related
* [PATCH] nvmet-tcp: Ensure old keys are freed before replacing new ones
From: alistair23 @ 2026-04-15 23:02 UTC (permalink / raw)
To: hare, hch, sagi, kch, kbusch, linux-nvme, linux-kernel, yi.zhang,
mlombard, linux-block
Cc: alistair23, shinichiro.kawasaki, Alistair Francis
From: Alistair Francis <alistair.francis@wdc.com>
Previously after the host sends a REPLACETLSPSK we freed the TLS keys as
part of calling nvmet_auth_sq_free() on success. A recent change ensured
we don't free the keys, allowing REPLACETLSPSK to work.
But that fix results in a kernel memory leak when running
```
nvme_trtype=loop ./check nvme/041 nvme/042 nvme/043 nvme/044 nvme/045 nvme/051 nvme/052
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
```
We can't free the keys on a successful DHCHAP operation, otherwise the
next REPLACETLSPSK will fail, so instead let's free them before we
replace them as part of nvmet_auth_challenge().
This ensures that REPLACETLSPSK works, while also avoiding any memory
leaks.
Fixes: 2e6eb6b277f59 ("nvmet-tcp: Don't free SQ on authentication success")
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
drivers/nvme/target/fabrics-cmd-auth.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c
index b9ab80c7a6941..58185184478a4 100644
--- a/drivers/nvme/target/fabrics-cmd-auth.c
+++ b/drivers/nvme/target/fabrics-cmd-auth.c
@@ -412,6 +412,13 @@ static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al)
int hash_len = nvme_auth_hmac_hash_len(ctrl->shash_id);
int data_size = sizeof(*d) + hash_len;
+ /*
+ * If replacing the keys then we have previous successful keys
+ * that might be leaked, so we need to free them here.
+ */
+ if (req->sq->dhchap_c1)
+ nvmet_auth_sq_free(req->sq);
+
if (ctrl->dh_tfm)
data_size += ctrl->dh_keysize;
if (al < data_size) {
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/6] block: use integrity interval instead of sector as seed
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
bio_integrity_setup_default() and blk_integrity_iterate() set the
integrity seed (initial reference tag) to the absolute address in the
block device in units of 512-byte sectors. The seed is correctly
incremented/decremented in units of integrity intervals in
bio_integrity_map_iter(), bio_integrity_advance(), and
blk_integrity_interval(). As a result, the ref tag written or read to a
particular integrity interval on a block device with integrity interval
size > 512 bytes varies with the starting offset of the read/write.
Convert the initial seed to units of integrity intervals so a consistent
ref tag is used for each integrity interval.
Fixes: 3be91c4a3d09 ("block: Deprecate the use of the term sector in the context of block integrity")
Fixes: 63573e359d05 ("bio-integrity: Restore original iterator on verify stage")
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
---
block/bio-integrity.c | 3 ++-
block/t10-pi.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index e79eaf047794..3ad6a6799f17 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -103,12 +103,13 @@ void bio_integrity_free_buf(struct bio_integrity_payload *bip)
void bio_integrity_setup_default(struct bio *bio)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
+ u64 seed = bio->bi_iter.bi_sector >> (bi->interval_exp - SECTOR_SHIFT);
- bip_set_seed(bip, bio->bi_iter.bi_sector);
+ bip_set_seed(bip, seed);
if (bi->csum_type) {
bip->bip_flags |= BIP_CHECK_GUARD;
if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
bip->bip_flags |= BIP_IP_CHECKSUM;
diff --git a/block/t10-pi.c b/block/t10-pi.c
index a19b4e102a83..e58d5eb6cefb 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -308,18 +308,19 @@ static blk_status_t blk_integrity_iterate(struct bio *bio,
struct bvec_iter *data_iter,
bool verify)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
+ u64 seed = data_iter->bi_sector >> (bi->interval_exp - SECTOR_SHIFT);
struct blk_integrity_iter iter = {
.bio = bio,
.bip = bip,
.bi = bi,
.data_iter = *data_iter,
.prot_iter = bip->bip_iter,
.interval_remaining = 1 << bi->interval_exp,
- .seed = data_iter->bi_sector,
+ .seed = seed,
.csum = 0,
};
blk_status_t ret = BLK_STS_OK;
while (iter.data_iter.bi_size && ret == BLK_STS_OK) {
--
2.45.2
^ permalink raw reply related
* [PATCH v2 0/6] block: fix integrity offset/length conversions
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
The block layer's integrity code currently sets the seed (initial
reference tag) in units of 512-byte sectors but increments it in units
of integrity intervals. Not only do the T10 DIF formats require ref tags
to be the lower bits of the logical block address, but mixing the two
units means the ref tags used for a particular logical block vary based
on its offset within a read/write request. This looks to be a
longstanding bug affecting block devices that support integrity with
block sizes > 512 bytes; I'm surprised it wasn't noticed before.
Also fix the newly added fs_bio_integrity_verify() to pass
bio_integrity_verify() a struct bdev_iter representing the data instead
of the integrity. Most of the integrity data is currently being skipped.
v2:
- Reorder fixes before refactoring commits
- Use u64, SECTOR_SHIFT (Christoph)
- Don't take sector_t in bip_set_seed() (Christoph)
Caleb Sander Mateos (6):
block: use integrity interval instead of sector as seed
bio-integrity-fs: pass data iter to bio_integrity_verify()
blk-integrity: take u64 in bio_integrity_intervals()
bio-integrity-fs: use integrity interval instead of sector as seed
t10-pi: use bio_integrity_intervals() helper
blk-integrity: avoid sector_t in bip_{get,set}_seed()
block/bio-integrity-fs.c | 5 +++--
block/bio-integrity.c | 4 ++--
block/t10-pi.c | 7 ++++---
drivers/nvme/target/io-cmd-bdev.c | 3 +--
drivers/target/target_core_iblock.c | 3 +--
include/linux/bio-integrity.h | 11 -----------
include/linux/blk-integrity.h | 28 +++++++++++++++++++++-------
include/linux/bvec.h | 1 +
8 files changed, 33 insertions(+), 29 deletions(-)
--
2.45.2
^ permalink raw reply
* [PATCH v2 2/6] bio-integrity-fs: pass data iter to bio_integrity_verify()
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
bio_integrity_verify() expects the passed struct bvec_iter to be an
iterator over bio data, not integrity. So construct a separate data
bvec_iter without the bio_integrity_bytes() conversion and pass it to
bio_integrity_verify() instead of bip_iter.
Fixes: 0bde8a12b554 ("block: add fs_bio_integrity helpers")
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
block/bio-integrity-fs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
index acb1e5f270d2..389372803b38 100644
--- a/block/bio-integrity-fs.c
+++ b/block/bio-integrity-fs.c
@@ -53,21 +53,22 @@ EXPORT_SYMBOL_GPL(fs_bio_integrity_generate);
int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
+ struct bvec_iter data_iter = {.bi_sector = sector, .bi_size = size};
/*
* Reinitialize bip->bip_iter.
*
* This is for use in the submitter after the driver is done with the
* bio. Requires the submitter to remember the sector and the size.
*/
memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
bip->bip_iter.bi_sector = sector;
bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
- return blk_status_to_errno(bio_integrity_verify(bio, &bip->bip_iter));
+ return blk_status_to_errno(bio_integrity_verify(bio, &data_iter));
}
static int __init fs_bio_integrity_init(void)
{
fs_bio_integrity_cache = kmem_cache_create("fs_bio_integrity",
--
2.45.2
^ permalink raw reply related
* [PATCH v2 3/6] blk-integrity: take u64 in bio_integrity_intervals()
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
To allow bio_integrity_intervals() to convert an absolute sector to an
absolute integrity interval, use u64 for its argument and return types.
Also use SECTOR_SHIFT instead of the magic constant 9.
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
---
include/linux/blk-integrity.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index b1b530613c34..825d777c078b 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -64,23 +64,23 @@ queue_max_integrity_segments(const struct request_queue *q)
{
return q->limits.max_integrity_segments;
}
/**
- * bio_integrity_intervals - Return number of integrity intervals for a bio
+ * bio_integrity_intervals - Convert sectors to integrity intervals
* @bi: blk_integrity profile for device
- * @sectors: Size of the bio in 512-byte sectors
+ * @sectors: Number of 512-byte sectors
*
* Description: The block layer calculates everything in 512 byte
* sectors but integrity metadata is done in terms of the data integrity
* interval size of the storage device. Convert the block layer sectors
* to the appropriate number of integrity intervals.
*/
-static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi,
- unsigned int sectors)
+static inline u64 bio_integrity_intervals(const struct blk_integrity *bi,
+ u64 sectors)
{
- return sectors >> (bi->interval_exp - 9);
+ return sectors >> (bi->interval_exp - SECTOR_SHIFT);
}
static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
unsigned int sectors)
{
@@ -151,12 +151,12 @@ static inline unsigned short
queue_max_integrity_segments(const struct request_queue *q)
{
return 0;
}
-static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi,
- unsigned int sectors)
+static inline u64 bio_integrity_intervals(const struct blk_integrity *bi,
+ u64 sectors)
{
return 0;
}
static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
--
2.45.2
^ permalink raw reply related
* [PATCH v2 5/6] t10-pi: use bio_integrity_intervals() helper
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
Use bio_integrity_intervals() to convert blk_rq_pos(rq) to integrity
intervals to reduce code duplication.
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
block/t10-pi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/t10-pi.c b/block/t10-pi.c
index e58d5eb6cefb..787950dec50a 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -541,11 +541,11 @@ static void __blk_reftag_remap(struct bio *bio, struct blk_integrity *bi,
static void blk_integrity_remap(struct request *rq, unsigned int nr_bytes,
bool prep)
{
struct blk_integrity *bi = &rq->q->limits.integrity;
- u64 ref = blk_rq_pos(rq) >> (bi->interval_exp - SECTOR_SHIFT);
+ u64 ref = bio_integrity_intervals(bi, blk_rq_pos(rq));
unsigned intervals = nr_bytes >> bi->interval_exp;
struct bio *bio;
if (!(bi->flags & BLK_INTEGRITY_REF_TAG))
return;
--
2.45.2
^ permalink raw reply related
* [PATCH v2 4/6] bio-integrity-fs: use integrity interval instead of sector as seed
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
bip_iter.bi_sector is meant to be in units of integrity intervals rather
than 512-byte sectors. bio_integrity_verify() doesn't actually use it
currently (it uses the passed in struct bvec_iter's bi_sector instead).
But let's set it to the expected value for consistency.
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
block/bio-integrity-fs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
index 389372803b38..5d1b0e33fc5f 100644
--- a/block/bio-integrity-fs.c
+++ b/block/bio-integrity-fs.c
@@ -62,11 +62,11 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
*
* This is for use in the submitter after the driver is done with the
* bio. Requires the submitter to remember the sector and the size.
*/
memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
- bip->bip_iter.bi_sector = sector;
+ bip->bip_iter.bi_sector = bio_integrity_intervals(bi, sector);
bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
return blk_status_to_errno(bio_integrity_verify(bio, &data_iter));
}
static int __init fs_bio_integrity_init(void)
--
2.45.2
^ permalink raw reply related
* [PATCH v2 6/6] blk-integrity: avoid sector_t in bip_{get,set}_seed()
From: Caleb Sander Mateos @ 2026-04-16 0:22 UTC (permalink / raw)
To: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen
Cc: Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel, Caleb Sander Mateos, Christoph Hellwig
In-Reply-To: <20260416002214.2048150-1-csander@purestorage.com>
bip_set_seed() and big_get_seed() take/return a sector_t value that's
actually an integrity interval number. This is confusing, so pass
struct blk_integrity and struct bio instead to bip_set_seed() and
convert the bio's device address to integrity intervals.
Open-code the access to bip->bip_iter.bi_sector in the one caller of
bip_set_seed() that doesn't use the bio device address for the seed.
Open-code bip_get_seed() in its one caller.
Add a comment to struct bvec_iter's bi_sector field explaining its
alternate use for bip_iter.
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Suggested-by: Christoph Hellwig <hch@infradead.org>
---
block/bio-integrity.c | 5 ++---
block/t10-pi.c | 2 +-
drivers/nvme/target/io-cmd-bdev.c | 3 +--
drivers/target/target_core_iblock.c | 3 +--
include/linux/bio-integrity.h | 11 -----------
include/linux/blk-integrity.h | 14 ++++++++++++++
include/linux/bvec.h | 1 +
7 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 3ad6a6799f17..e9ae5db99f64 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -103,13 +103,12 @@ void bio_integrity_free_buf(struct bio_integrity_payload *bip)
void bio_integrity_setup_default(struct bio *bio)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
- u64 seed = bio->bi_iter.bi_sector >> (bi->interval_exp - SECTOR_SHIFT);
- bip_set_seed(bip, seed);
+ bip_set_seed(bip, bi, bio);
if (bi->csum_type) {
bip->bip_flags |= BIP_CHECK_GUARD;
if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
bip->bip_flags |= BIP_IP_CHECKSUM;
@@ -472,11 +471,11 @@ int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta)
it.count = integrity_bytes;
ret = bio_integrity_map_user(bio, &it);
if (!ret) {
bio_uio_meta_to_bip(bio, meta);
- bip_set_seed(bio_integrity(bio), meta->seed);
+ bio_integrity(bio)->bip_iter.bi_sector = meta->seed;
iov_iter_advance(&meta->iter, integrity_bytes);
meta->seed += bio_integrity_intervals(bi, bio_sectors(bio));
}
return ret;
}
diff --git a/block/t10-pi.c b/block/t10-pi.c
index 787950dec50a..71367fd082bd 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -510,11 +510,11 @@ static void blk_reftag_remap_prepare(struct blk_integrity *bi,
static void __blk_reftag_remap(struct bio *bio, struct blk_integrity *bi,
unsigned *intervals, u64 *ref, bool prep)
{
struct bio_integrity_payload *bip = bio_integrity(bio);
struct bvec_iter iter = bip->bip_iter;
- u64 virt = bip_get_seed(bip);
+ u64 virt = bip->bip_iter.bi_sector;
union pi_tuple *ptuple;
union pi_tuple tuple;
if (prep && bip->bip_flags & BIP_MAPPED_INTEGRITY) {
*ref += bio->bi_iter.bi_size >> bi->interval_exp;
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index f2d9e8901df4..2c4b312f2f55 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -218,12 +218,11 @@ static int nvmet_bdev_alloc_bip(struct nvmet_req *req, struct bio *bio,
pr_err("Unable to allocate bio_integrity_payload\n");
return PTR_ERR(bip);
}
/* virtual start sector must be in integrity interval units */
- bip_set_seed(bip, bio->bi_iter.bi_sector >>
- (bi->interval_exp - SECTOR_SHIFT));
+ bip_set_seed(bip, bi, bio);
resid = bio_integrity_bytes(bi, bio_sectors(bio));
while (resid > 0 && sg_miter_next(miter)) {
len = min_t(size_t, miter->length, resid);
rc = bio_integrity_add_page(bio, miter->page, len,
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 1087d1d17c36..4e0fa91a08fd 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -706,12 +706,11 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio,
pr_err("Unable to allocate bio_integrity_payload\n");
return PTR_ERR(bip);
}
/* virtual start sector must be in integrity interval units */
- bip_set_seed(bip, bio->bi_iter.bi_sector >>
- (bi->interval_exp - SECTOR_SHIFT));
+ bip_set_seed(bip, bi, bio);
pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size,
(unsigned long long)bip->bip_iter.bi_sector);
resid = bio_integrity_bytes(bi, bio_sectors(bio));
diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
index af5178434ec6..edcd0855abba 100644
--- a/include/linux/bio-integrity.h
+++ b/include/linux/bio-integrity.h
@@ -56,21 +56,10 @@ static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag)
return bip->bip_flags & flag;
return false;
}
-static inline sector_t bip_get_seed(struct bio_integrity_payload *bip)
-{
- return bip->bip_iter.bi_sector;
-}
-
-static inline void bip_set_seed(struct bio_integrity_payload *bip,
- sector_t seed)
-{
- bip->bip_iter.bi_sector = seed;
-}
-
void bio_integrity_init(struct bio *bio, struct bio_integrity_payload *bip,
struct bio_vec *bvecs, unsigned int nr_vecs);
struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
unsigned int nr);
int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len,
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index 825d777c078b..3a2e55e809c5 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -85,10 +85,24 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
unsigned int sectors)
{
return bio_integrity_intervals(bi, sectors) * bi->metadata_size;
}
+/**
+ * bip_set_seed - Set bip reference tag seed from bio device address
+ * @bip: struct bio_integrity_payload whose ref tag seed to set
+ * @bi: struct blk_integrity profile for device
+ * @bio: struct bio whose device address to use for the ref tag seed
+ */
+static inline void bip_set_seed(struct bio_integrity_payload *bip,
+ const struct blk_integrity *bi,
+ const struct bio *bio)
+{
+ bip->bip_iter.bi_sector =
+ bio_integrity_intervals(bi, bio->bi_iter.bi_sector);
+}
+
static inline bool blk_integrity_rq(const struct request *rq)
{
return rq->cmd_flags & REQ_INTEGRITY;
}
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index d36dd476feda..3dc88f5cd367 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -76,10 +76,11 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr,
struct bvec_iter {
/*
* Current device address in 512 byte sectors. Only updated by the bio
* iter wrappers and not the bvec iterator helpers themselves.
+ * For bip_iter, this is overloaded to represent the integrity interval.
*/
sector_t bi_sector;
/*
* Remaining size in bytes.
--
2.45.2
^ permalink raw reply related
* Re: [PATCH v10 13/13] docs: add io_queue flag to isolcpus
From: Ming Lei @ 2026-04-16 0:48 UTC (permalink / raw)
To: Aaron Tomlin
Cc: Ming Lei, axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, steve, sean, chjohnst, neelx,
mproche, linux-block, linux-kernel, virtualization, linux-nvme,
linux-scsi, megaraidlinux.pdl, mpi3mr-linuxdrv.pdl,
MPT-FusionLinux.pdl
In-Reply-To: <fouvg7qn7g4yah7jsvzkdmweesbp4aqmhx37gf3ow5medzvuyk@5n3ddkijosr6>
On Wed, Apr 15, 2026 at 10:56:37AM -0400, Aaron Tomlin wrote:
> On Mon, Apr 13, 2026 at 11:11:15PM +0800, Ming Lei wrote:
> > But typical applications aren't supposed to submit IOs from these
> > isolated CPUs, so in reality, it isn't a big deal.
>
> Hi Ming,
>
> While that may be true for general-purpose workloads, it is a fundamentally
> incorrect assumption for the highly specialised environments that actually
> rely on strict CPU isolation, such as High-Frequency Trading (HFT).
>
> The requirement in these strict environments is not that the isolated CPU
> performs zero I/O. Rather, the requirement is that the isolated CPU must be
> shielded from the unpredictable latency of the hardware completion
> interrupt.
Again it is just your opinion, not a bug report, may not be a fact, right?
Which kind of HFT application submits IO from isolated CPU?
However, as I mentioned, I don't object this patchset, but you have to fix all
wrong comment & document & bug found in review first.
Thanks,
Ming
^ permalink raw reply
* Re: [PATCH] nvmet-tcp: Ensure old keys are freed before replacing new ones
From: Christoph Hellwig @ 2026-04-16 5:15 UTC (permalink / raw)
To: alistair23
Cc: hare, hch, sagi, kch, kbusch, linux-nvme, linux-kernel, yi.zhang,
mlombard, linux-block, shinichiro.kawasaki, Alistair Francis
In-Reply-To: <20260415230250.2783414-1-alistair.francis@wdc.com>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2] t10-pi: reduce ref tag code duplication
From: Christoph Hellwig @ 2026-04-16 5:18 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, linux-block, linux-kernel, Christoph Hellwig,
Anuj Gupta
In-Reply-To: <20260415210847.1730016-1-csander@purestorage.com>
On Wed, Apr 15, 2026 at 03:08:47PM -0600, Caleb Sander Mateos wrote:
> #ifndef _LINUX_T10_PI_H
> #define _LINUX_T10_PI_H
>
> #include <linux/types.h>
> #include <linux/blk-mq.h>
> +#include <linux/wordpart.h>
We must have already gotten this implicitly given that the code
already uses lower_48_bits.
Otherwise looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2 1/6] block: use integrity interval instead of sector as seed
From: Christoph Hellwig @ 2026-04-16 5:19 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Sagi Grimberg, Chaitanya Kulkarni, Martin K. Petersen,
Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel
In-Reply-To: <20260416002214.2048150-2-csander@purestorage.com>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2 2/6] bio-integrity-fs: pass data iter to bio_integrity_verify()
From: Christoph Hellwig @ 2026-04-16 5:21 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen, Anuj Gupta, linux-block, linux-nvme,
linux-scsi, target-devel, linux-kernel
In-Reply-To: <20260416002214.2048150-3-csander@purestorage.com>
On Wed, Apr 15, 2026 at 06:22:10PM -0600, Caleb Sander Mateos wrote:
> bio_integrity_verify() expects the passed struct bvec_iter to be an
> iterator over bio data, not integrity. So construct a separate data
> bvec_iter without the bio_integrity_bytes() conversion and pass it to
> bio_integrity_verify() instead of bip_iter.
>
> Fixes: 0bde8a12b554 ("block: add fs_bio_integrity helpers")
> Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
> Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> ---
> block/bio-integrity-fs.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
> index acb1e5f270d2..389372803b38 100644
> --- a/block/bio-integrity-fs.c
> +++ b/block/bio-integrity-fs.c
> @@ -53,21 +53,22 @@ EXPORT_SYMBOL_GPL(fs_bio_integrity_generate);
>
> int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
> {
> struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
> struct bio_integrity_payload *bip = bio_integrity(bio);
> + struct bvec_iter data_iter = {.bi_sector = sector, .bi_size = size};
Missing spaces and too condensed. We normally use one line per field in
struct initializers:
struct bvec_iter data_iter = {
.bi_sector = sector,
.bi_size = size,
};
Otherwise looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2 3/6] blk-integrity: take u64 in bio_integrity_intervals()
From: Christoph Hellwig @ 2026-04-16 5:21 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Sagi Grimberg, Chaitanya Kulkarni, Martin K. Petersen,
Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel
In-Reply-To: <20260416002214.2048150-4-csander@purestorage.com>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2 4/6] bio-integrity-fs: use integrity interval instead of sector as seed
From: Christoph Hellwig @ 2026-04-16 5:21 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Sagi Grimberg, Chaitanya Kulkarni, Martin K. Petersen,
Anuj Gupta, linux-block, linux-nvme, linux-scsi, target-devel,
linux-kernel
In-Reply-To: <20260416002214.2048150-5-csander@purestorage.com>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v2 6/6] blk-integrity: avoid sector_t in bip_{get,set}_seed()
From: Christoph Hellwig @ 2026-04-16 5:23 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Martin K. Petersen, Anuj Gupta, linux-block, linux-nvme,
linux-scsi, target-devel, linux-kernel, Christoph Hellwig
In-Reply-To: <20260416002214.2048150-7-csander@purestorage.com>
On Wed, Apr 15, 2026 at 06:22:14PM -0600, Caleb Sander Mateos wrote:
> bip_set_seed() and big_get_seed() take/return a sector_t value that's
> actually an integrity interval number. This is confusing, so pass
> struct blk_integrity and struct bio instead to bip_set_seed() and
> convert the bio's device address to integrity intervals.
>
> Open-code the access to bip->bip_iter.bi_sector in the one caller of
> bip_set_seed() that doesn't use the bio device address for the seed.
> Open-code bip_get_seed() in its one caller.
>
> Add a comment to struct bvec_iter's bi_sector field explaining its
> alternate use for bip_iter.
>
> Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
> Suggested-by: Christoph Hellwig <hch@infradead.org>
> ---
> block/bio-integrity.c | 5 ++---
> block/t10-pi.c | 2 +-
> drivers/nvme/target/io-cmd-bdev.c | 3 +--
> drivers/target/target_core_iblock.c | 3 +--
> include/linux/bio-integrity.h | 11 -----------
> include/linux/blk-integrity.h | 14 ++++++++++++++
> include/linux/bvec.h | 1 +
> 7 files changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/block/bio-integrity.c b/block/bio-integrity.c
> index 3ad6a6799f17..e9ae5db99f64 100644
> --- a/block/bio-integrity.c
> +++ b/block/bio-integrity.c
> @@ -103,13 +103,12 @@ void bio_integrity_free_buf(struct bio_integrity_payload *bip)
>
> void bio_integrity_setup_default(struct bio *bio)
> {
> struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
> struct bio_integrity_payload *bip = bio_integrity(bio);
> - u64 seed = bio->bi_iter.bi_sector >> (bi->interval_exp - SECTOR_SHIFT);
>
> - bip_set_seed(bip, seed);
> + bip_set_seed(bip, bi, bio);
>
> if (bi->csum_type) {
> bip->bip_flags |= BIP_CHECK_GUARD;
> if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
> bip->bip_flags |= BIP_IP_CHECKSUM;
> @@ -472,11 +471,11 @@ int bio_integrity_map_iter(struct bio *bio, struct uio_meta *meta)
>
> it.count = integrity_bytes;
> ret = bio_integrity_map_user(bio, &it);
> if (!ret) {
> bio_uio_meta_to_bip(bio, meta);
> - bip_set_seed(bio_integrity(bio), meta->seed);
> + bio_integrity(bio)->bip_iter.bi_sector = meta->seed;
> iov_iter_advance(&meta->iter, integrity_bytes);
> meta->seed += bio_integrity_intervals(bi, bio_sectors(bio));
> }
> return ret;
> }
> diff --git a/block/t10-pi.c b/block/t10-pi.c
> index 787950dec50a..71367fd082bd 100644
> --- a/block/t10-pi.c
> +++ b/block/t10-pi.c
> @@ -510,11 +510,11 @@ static void blk_reftag_remap_prepare(struct blk_integrity *bi,
> static void __blk_reftag_remap(struct bio *bio, struct blk_integrity *bi,
> unsigned *intervals, u64 *ref, bool prep)
> {
> struct bio_integrity_payload *bip = bio_integrity(bio);
> struct bvec_iter iter = bip->bip_iter;
> - u64 virt = bip_get_seed(bip);
> + u64 virt = bip->bip_iter.bi_sector;
> union pi_tuple *ptuple;
> union pi_tuple tuple;
>
> if (prep && bip->bip_flags & BIP_MAPPED_INTEGRITY) {
> *ref += bio->bi_iter.bi_size >> bi->interval_exp;
> diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
> index f2d9e8901df4..2c4b312f2f55 100644
> --- a/drivers/nvme/target/io-cmd-bdev.c
> +++ b/drivers/nvme/target/io-cmd-bdev.c
> @@ -218,12 +218,11 @@ static int nvmet_bdev_alloc_bip(struct nvmet_req *req, struct bio *bio,
> pr_err("Unable to allocate bio_integrity_payload\n");
> return PTR_ERR(bip);
> }
>
> /* virtual start sector must be in integrity interval units */
> - bip_set_seed(bip, bio->bi_iter.bi_sector >>
> - (bi->interval_exp - SECTOR_SHIFT));
> + bip_set_seed(bip, bi, bio);
>
> resid = bio_integrity_bytes(bi, bio_sectors(bio));
> while (resid > 0 && sg_miter_next(miter)) {
> len = min_t(size_t, miter->length, resid);
> rc = bio_integrity_add_page(bio, miter->page, len,
> diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
> index 1087d1d17c36..4e0fa91a08fd 100644
> --- a/drivers/target/target_core_iblock.c
> +++ b/drivers/target/target_core_iblock.c
> @@ -706,12 +706,11 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio,
> pr_err("Unable to allocate bio_integrity_payload\n");
> return PTR_ERR(bip);
> }
>
> /* virtual start sector must be in integrity interval units */
> - bip_set_seed(bip, bio->bi_iter.bi_sector >>
> - (bi->interval_exp - SECTOR_SHIFT));
> + bip_set_seed(bip, bi, bio);
>
> pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size,
> (unsigned long long)bip->bip_iter.bi_sector);
>
> resid = bio_integrity_bytes(bi, bio_sectors(bio));
> diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
> index af5178434ec6..edcd0855abba 100644
> --- a/include/linux/bio-integrity.h
> +++ b/include/linux/bio-integrity.h
> @@ -56,21 +56,10 @@ static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag)
> return bip->bip_flags & flag;
>
> return false;
> }
>
> -static inline sector_t bip_get_seed(struct bio_integrity_payload *bip)
> -{
> - return bip->bip_iter.bi_sector;
> -}
> -
> -static inline void bip_set_seed(struct bio_integrity_payload *bip,
> - sector_t seed)
> -{
> - bip->bip_iter.bi_sector = seed;
> -}
> -
> void bio_integrity_init(struct bio *bio, struct bio_integrity_payload *bip,
> struct bio_vec *bvecs, unsigned int nr_vecs);
> struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
> unsigned int nr);
> int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len,
> diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
> index 825d777c078b..3a2e55e809c5 100644
> --- a/include/linux/blk-integrity.h
> +++ b/include/linux/blk-integrity.h
> @@ -85,10 +85,24 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
> unsigned int sectors)
> {
> return bio_integrity_intervals(bi, sectors) * bi->metadata_size;
> }
>
> +/**
> + * bip_set_seed - Set bip reference tag seed from bio device address
> + * @bip: struct bio_integrity_payload whose ref tag seed to set
> + * @bi: struct blk_integrity profile for device
> + * @bio: struct bio whose device address to use for the ref tag seed
> + */
> +static inline void bip_set_seed(struct bio_integrity_payload *bip,
> + const struct blk_integrity *bi,
> + const struct bio *bio)
> +{
> + bip->bip_iter.bi_sector =
> + bio_integrity_intervals(bi, bio->bi_iter.bi_sector);
The bip is pointed to by the bio, so we don't need to pass it separately.
Same for struct blk_integrity.
^ permalink raw reply
* Re: [PATCH] nvmet-tcp: Ensure old keys are freed before replacing new ones
From: Hannes Reinecke @ 2026-04-16 6:16 UTC (permalink / raw)
To: alistair23, hch, sagi, kch, kbusch, linux-nvme, linux-kernel,
yi.zhang, mlombard, linux-block
Cc: shinichiro.kawasaki, Alistair Francis
In-Reply-To: <20260415230250.2783414-1-alistair.francis@wdc.com>
On 4/16/26 01:02, alistair23@gmail.com wrote:
> From: Alistair Francis <alistair.francis@wdc.com>
>
> Previously after the host sends a REPLACETLSPSK we freed the TLS keys as
> part of calling nvmet_auth_sq_free() on success. A recent change ensured
> we don't free the keys, allowing REPLACETLSPSK to work.
>
> But that fix results in a kernel memory leak when running
>
> ```
> nvme_trtype=loop ./check nvme/041 nvme/042 nvme/043 nvme/044 nvme/045 nvme/051 nvme/052
> echo scan > /sys/kernel/debug/kmemleak
> cat /sys/kernel/debug/kmemleak
> ```
>
> We can't free the keys on a successful DHCHAP operation, otherwise the
> next REPLACETLSPSK will fail, so instead let's free them before we
> replace them as part of nvmet_auth_challenge().
>
> This ensures that REPLACETLSPSK works, while also avoiding any memory
> leaks.
>
> Fixes: 2e6eb6b277f59 ("nvmet-tcp: Don't free SQ on authentication success")
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> drivers/nvme/target/fabrics-cmd-auth.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c
> index b9ab80c7a6941..58185184478a4 100644
> --- a/drivers/nvme/target/fabrics-cmd-auth.c
> +++ b/drivers/nvme/target/fabrics-cmd-auth.c
> @@ -412,6 +412,13 @@ static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al)
> int hash_len = nvme_auth_hmac_hash_len(ctrl->shash_id);
> int data_size = sizeof(*d) + hash_len;
>
> + /*
> + * If replacing the keys then we have previous successful keys
> + * that might be leaked, so we need to free them here.
> + */
> + if (req->sq->dhchap_c1)
> + nvmet_auth_sq_free(req->sq);
> +
> if (ctrl->dh_tfm)
> data_size += ctrl->dh_keysize;
> if (al < data_size) {
I am not sure.
The authentication variables should be freed as soon as the
authentication completes; the session key is ephemeral and
should not be stored longer than necessary and will _never_
be used again once authentication completes.
The TLS key, OTOH, is used throughout the session and needs
to be present while the session is active
As such, both sets have vastly different lifetimes, and
I would argue that this
void nvmet_auth_sq_free(struct nvmet_sq *sq)
{
cancel_delayed_work(&sq->auth_expired_work);
#ifdef CONFIG_NVME_TARGET_TCP_TLS
sq->tls_key = NULL;
#endif
kfree(sq->dhchap_c1);
sq->dhchap_c1 = NULL;
is actually wrong as we should not modify 'tls_key' here.
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply
* Re: [PATCH 1/2] sg: don't use GFP_ATOMIC in sg_start_req
From: Hannes Reinecke @ 2026-04-16 6:25 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Doug Gilbert, Martin K. Petersen
Cc: Shin'ichiro Kawasaki, linux-block, linux-scsi
In-Reply-To: <20260415060813.807659-2-hch@lst.de>
On 4/15/26 08:08, Christoph Hellwig wrote:
> sg_start_req is called from normal user context and can sleep when
> waiting for memory. Switch it to use GFP_KERNEL, which fixes allocation
> failures seend with the bio_alloc rework.
>
> Fixes: b520c4eef83d ("block: split bio_alloc_bioset more clearly into a fast and slowpath")
> Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> ---
> drivers/scsi/sg.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
> index 37bac49f30f0..43265f012ce9 100644
> --- a/drivers/scsi/sg.c
> +++ b/drivers/scsi/sg.c
> @@ -1811,7 +1811,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
> }
>
> res = blk_rq_map_user_io(rq, md, hp->dxferp, hp->dxfer_len,
> - GFP_ATOMIC, iov_count, iov_count, 1, rw);
> + GFP_KERNEL, iov_count, iov_count, 1, rw);
> if (!res) {
> srp->bio = rq->bio;
>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply
* Re: [PATCH 2/2] block: only restrict bio allocation gfp mask asked to block
From: Hannes Reinecke @ 2026-04-16 6:26 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe, Doug Gilbert, Martin K. Petersen
Cc: Shin'ichiro Kawasaki, linux-block, linux-scsi
In-Reply-To: <20260415060813.807659-3-hch@lst.de>
On 4/15/26 08:08, Christoph Hellwig wrote:
> If the caller is asking for a non-blocking allocation, we should not
> further restrict the gfp mask, which just increases the likelihood
> of failures.
>
> Fixes: b520c4eef83d ("block: split bio_alloc_bioset more clearly into a fast and slowpath")
> Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> block/bio.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/block/bio.c b/block/bio.c
> index 641ef0928d73..12341f760b9a 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -544,7 +544,8 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
> if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
> return NULL;
>
> - gfp = try_alloc_gfp(gfp);
> + if (saved_gfp & __GFP_DIRECT_RECLAIM)
> + gfp = try_alloc_gfp(gfp);
> if (bs->cache && nr_vecs <= BIO_INLINE_VECS) {
> /*
> * Set REQ_ALLOC_CACHE even if no cached bio is available to
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply
* blktests failures with v7.0 kernel
From: Shinichiro Kawasaki @ 2026-04-16 6:39 UTC (permalink / raw)
To: linux-block@vger.kernel.org, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org, nbd@other.debian.org,
linux-rdma@vger.kernel.org
Hi all,
I ran the latest blktests (git hash: 255189f0c4e5) with the v7.0 kernel. I
observed 6 failures listed below. Comparing with the previous report for the
v7.0-rc1 kernel [1], 2 failure were resolved (blktrace/002, zbd/009) and the
hangs at nvme/058 and nvme/061 are no longer observed. Thank you very much for
the fixes.
[1] https://lore.kernel.org/linux-block/aZ_-cH8euZLySxdD@shinmob/
List of failures
================
#1: nvme/005,063 (tcp transport)
#2: nvme/058 (fc transport)(kmemleak)
#3: nvme/060
#4: nvme/061 (rdma transport, siw driver)(kmemleak)
#5: nvme/061 (fc transport)
#6: nbd/002
Failure description
===================
#1: nvme/005,063 (tcp transport)
The test case nvme/005 and 063 fail for tcp transport due to the lockdep
WARN related to the three locks q->q_usage_counter, q->elevator_lock and
set->srcu. Refer to the nvme/063 failure report for v6.16-rc1 kernel [2].
[2] https://lore.kernel.org/linux-block/4fdm37so3o4xricdgfosgmohn63aa7wj3ua4e5vpihoamwg3ui@fq42f5q5t5ic/
#2: nvme/058 (fc transport)(kmemleak)
When the test case nvme/058 is repeated for fc transport several times on
the kernel with CONFIG_DEBUG_KMEMLEAK enabled, it fails with kmemleak
messages. Refer to the report for v7.0-rc1 [1]. This test case had hanged
with v7.0-rc1 kernel. The hang is no longer observed, but still kmemleak is
observed.
#3: nvme/060 (rdma transport)
When the test case is repeated for rdma transports around 50 times, the test
case fails. There are two failure symptoms. Both symptoms does not look
kernel side problems, but blktests side problems. I will allocate time to
look into them.
[symptom 1]
nvme/060 (tr=rdma) (test nvme fabrics target reset) [failed]
runtime ... 87.444s
--- tests/nvme/060.out 2026-02-20 12:15:11.066947841 +0000
+++ /home/fedora/blktests/results/nodev_tr_rdma/nvme/060.out.bad 2026-02-20 15:06:44.552705787 +0000
@@ -1,2 +1,3 @@
Running nvme/060
+FAIL: nvme connect return error code
Test complete
[symptom 2]
nvme/060 (tr=rdma) (test nvme fabrics target reset) [failed]
runtime ... 22.545s
--- tests/nvme/060.out 2025-08-26 21:28:52.798847739 +0900
+++ /home/shin/Blktests/blktests/results/nodev_tr_rdma/nvme/060.out.bad 2026-02-26 15:20:36.973686247 +0900
@@ -1,2 +1,3 @@
Running nvme/060
+_: line 1: /sys/kernel/debug/nvmet/blktests-subsystem-1/ctrl1/state: No such file or directory
Test complete
#4: nvme/061 (rdma transport, siw driver)(kmemleak)
When the test case nvme/061 is repeated twice for the rdma transport and the
siw driver on the kernel v6.19 with CONFIG_DEBUG_KMEMLEAK enabled, it fails
with a kmemleak message. Refer to the nvme/061 failure report for v6.19
kernel [3].
[3] https://lore.kernel.org/linux-block/aY7ZBfMjVIhe_wh3@shinmob/
#5: nvme/061 (fc transport)
When the test case nvme/061 is repeated around 50 times for the fc
transport, the test process fails after Oops and KASAN null-ptr-deref. It
had hanged with v7.0-rc1 kernel, but it does not hang with v7.0 kernel :)
Further debug is required for the Oops and KASAN. Refer to the kernel
report for v6.19 kernel [1].
#6: nbd/002
The test case nbd/002 fails due to the lockdep WARN related to
mm->mmap_lock, sk_lock-AF_INET6 and fs_reclaim. Refer to the nbd/002 failure
report for v6.18-rc1 kernel [4].
[4] https://lore.kernel.org/linux-block/ynmi72x5wt5ooljjafebhcarit3pvu6axkslqenikb2p5txe57@ldytqa2t4i2x/
^ permalink raw reply
* Re: [PATCH] zram: add accounting for incompressible pages
From: Sergey Senozhatsky @ 2026-04-16 7:07 UTC (permalink / raw)
To: qiwu.chen; +Cc: senozhatsky, axboe, linux-block, qiwu.chen
In-Reply-To: <20260415104356.82248-1-qiwu.chen@transsion.com>
On (26/04/15 18:43), qiwu.chen wrote:
> 1. Rename write_incompressible_page to write_huge_page since huge page
> could be recompressed with secondary algorithms.
Please no. "huge_page" is the most confusing term that zram uses.
> 2. Similar to huge page, add incompressible_pages accounting for current
> incompressible pages, and incompressible_pages_since accounting for
> incompressible pages since zram set up. The accounting value can be showed
> by mm_stat.
What for?
^ permalink raw reply
* Re: [RFC PATCH] zram: support asynchronous GC for lazy slot freeing
From: Sergey Senozhatsky @ 2026-04-16 7:41 UTC (permalink / raw)
To: Xueyuan Chen
Cc: ryncsn, baohua, minchan, senozhatsky, akpm, linux-mm, axboe,
linux-block, linux-kernel, kasong, chrisl, justinjiang,
liulei.rjpt
In-Reply-To: <20260414054930.225853-1-xueyuan.chen21@gmail.com>
On (26/04/14 13:49), Xueyuan Chen wrote:
> On Sun, Apr 12, 2026 at 07:48:48PM +0800, Kairui Song wrote:
> [...]
> >What is making this slot_free so costly? zs_free?
>
> Yes, I've captured some perf data on RK3588 cpu2:
>
> - 3.79% 0.42% zram [zram] [k] slot_free
> - 89.04% slot_free
> - 65.40% zs_free
> + 77.29% free_zspage
> + 21.75% kmem_cache_free
> 0.68% __kern_my_cpu_offset
> + 13.19% _raw_spin_unlock
> + 4.86% _raw_read_unlock
> 4.75% obj_free
> + 4.72% _raw_read_lock
> 3.64% fix_fullness_group
> + 2.02% _raw_spin_lock
> + 1.31% kmem_cache_free
>
> It's clear that zs_free is the primary hotspot, accounting for ~65.40%
> of the total slot_free cycles. Beyond that, have some read and spin lock
> in slot_free.
Just a random thought, if zs_free() is costly then it likely also affects
zswap, which makes me wonder if doing something on the zsmalloc side is a
"batter" way forward.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox