All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/1] t10-pi bio split fix
@ 2021-12-20 13:44 Alexey Lyashkov
  2021-12-20 13:44 ` [PATCH 1/1] t10-pi: fix intergrity iterator Alexey Lyashkov
  2021-12-20 16:29 ` [PATCH 0/1] t10-pi bio split fix Martin K. Petersen
  0 siblings, 2 replies; 13+ messages in thread
From: Alexey Lyashkov @ 2021-12-20 13:44 UTC (permalink / raw)
  To: Jens Axboe, Bart Van Assche, fio
  Cc: Damien Le Moal, Dmitry Fomichev, Alexey Lyashkov

Hello All,

During HPe testing Lustre team discovered bio incorrectly splits with
integrity info attached.

Some research pointed me to the two fixes related to my problem,
first was 
commit f36ea50ca0043e7b1204feaf1d2ba6bd68c08d36
Author: Wen Xiong <wenxiong@xxxxxxxxxxxxxxxxxx>
Date:   Wed May 10 08:54:11 2017 -0500

    blk-mq: NVMe 512B/4K+T10 DIF/DIX format returns I/O error on dd with split op

    When formatting NVMe to 512B/4K + T10 DIf/DIX, dd with split op returns
    "Input/output error". Looks block layer split the bio after calling
    bio_integrity_prep(bio). This patch fixes the issue.

and second was
commit e4dc9a4c31fe10d1751c542702afc85be8a5c56a
Author: Israel Rukshin <israelr@xxxxxxxxxxxx>
Date:   Wed Dec 11 17:36:02 2019 +0200

    scsi: target/iblock: Fix protection error with blocks greater than 512B

…
Block io trace pointed me to the three functions called in my case, it is
t10_pi_generate, bio_integrity_advance, t10_pi_type1_prepare.

Looking in code - t10_pi_generate generate a ref_tag based on “virtual” block 
number (512b base), and t10_pi_type1_prepare - converts this data to the the 
real ref_tag (aka device block number), but sometimes it’s don’t mapped.
Looking to the 
void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
{
        struct bio_integrity_payload *bip = bio_integrity(bio);
        struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
        unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
        bip->bip_iter.bi_sector += bytes_done >> 9;
        bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
}

it have shit an iterator in the 512b block size base it looks right, but wait… 
static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter,
                csum_fn *fn, enum t10_dif_type type)
{
        unsigned int i;

        for (i = 0 ; i < iter->data_size ; i += iter->interval) {
                struct t10_pi_tuple *pi = iter->prot_buf;


                iter->seed++; <<<
        }

        return BLK_STS_OK;
}

t10_pi_generate / t10_pi_type1_prepare have just a increment by “1” for 
the integrity internal which is 4k in my case,
so any bio_integrity_advance call will be move an iterator outside of
generated sequence and t10_pi_type1_prepare can’t be found a good virtual
sector for the mapping.
Changing an increment by “1” to be related to the real integrity size 
solve a problem completely.
Attached patch passed my own testing on raid0 with 4k block size. 

Alexey Lyashkov (1):
  t10-pi: fix intergrity iterator

 block/t10-pi.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: [PATCH 0/1] t10-pi bio split fix
@ 2022-02-02 17:42 Ivanov, Dmitry (HPC)
  2022-02-04  3:44 ` Martin K. Petersen
  0 siblings, 1 reply; 13+ messages in thread
From: Ivanov, Dmitry (HPC) @ 2022-02-02 17:42 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: Damien Le Moal, Jens Axboe, Bart Van Assche, Lyashkov, Alexey,
	Dmitry Fomichev, linux-block, linux-scsi

On 14/01/2022, 12:25 +0000, "Martin K. Petersen" <martin.petersen@xxxxxxxxxx> wrote:

> Can you please try the following patch?
> 
> Martin K. Petersen	Oracle Linux Engineering
> 
> diff --git a/block/bio-integrity.c b/block/bio-integrity.c
> index c0eb901315f9..fa5bc5b13c6a 100644
> --- a/block/bio-integrity.c
> +++ b/block/bio-integrity.c
> @@ -387,7 +387,7 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
> 	struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
> 	unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
> 
> -	bip->bip_iter.bi_sector += bytes_done >> 9;
> +	bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9);
> 	bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
> }

I encountered the same issue as Alexey did when writing to DPS Type 2 formatted, 8 bytes metadata NVME device(s) from a stacked driver if bio was split in md layer.
Virtual ref_tags were improperly converted to ref_tags by the block integrity prepare_fn().
The Martin's patch has resolved this issue.

Martin, could you please advance with this patch?

My only concern is dm_crypt target which operates on bip_iter directly with the code copy-pasted from bio_integrity_advance:

static int dm_crypt_integrity_io_alloc(struct dm_crypt_io *io, struct bio *bio)
{
	struct bio_integrity_payload *bip;
	unsigned int tag_len;
	int ret;

	if (!bio_sectors(bio) || !io->cc->on_disk_tag_size)
		return 0;

	bip = bio_integrity_alloc(bio, GFP_NOIO, 1);
	if (IS_ERR(bip))
		return PTR_ERR(bip);

	tag_len = io->cc->on_disk_tag_size * (bio_sectors(bio) >> io->cc->sector_shift);

	bip->bip_iter.bi_size = tag_len;
	bip->bip_iter.bi_sector = io->cc->start + io->sector;
               ^^^

	ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata),
				     tag_len, offset_in_page(io->integrity_metadata));
...
}
Not sure if there is another place in drivers where bip iterator is advanced explicitly, i.e. without calling bio_integrity_advance/bio_advance.

--
Dmitry Ivanov
Hewlett Packard Enterprise - HPC AI Labs

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-02-05  3:03 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-20 13:44 [PATCH 0/1] t10-pi bio split fix Alexey Lyashkov
2021-12-20 13:44 ` [PATCH 1/1] t10-pi: fix intergrity iterator Alexey Lyashkov
2021-12-20 16:29 ` [PATCH 0/1] t10-pi bio split fix Martin K. Petersen
2021-12-24 12:16   ` Lyashkov, Alexey
2021-12-30  2:23     ` Damien Le Moal
2022-01-13 11:13       ` Lyashkov, Alexey
2022-01-13 19:59         ` Martin K. Petersen
2022-01-14 12:25           ` Lyashkov, Alexey
2022-02-02 17:42 Ivanov, Dmitry (HPC)
2022-02-04  3:44 ` Martin K. Petersen
2022-02-04  7:43   ` Milan Broz
2022-02-04  7:58     ` Lyashkov, Alexey
2022-02-05  3:03     ` Ivanov, Dmitry (HPC)

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.