| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: Wen Xiong <wenxiong@linux.vnet.ibm.com> |
| Date: Wed, 10 May 2017 08:54:11 -0500 |
| Subject: blk-mq: NVMe 512B/4K+T10 DIF/DIX format returns I/O error on dd with split op |
| |
| From: Wen Xiong <wenxiong@linux.vnet.ibm.com> |
| |
| |
| [ Upstream commit f36ea50ca0043e7b1204feaf1d2ba6bd68c08d36 ] |
| |
| 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. |
| |
| Below is how we debug this issue: |
| (1)format nvme to 4K block # size with type 2 DIF |
| (2)dd with block size bigger than 1024k. |
| oflag=direct |
| dd: error writing '/dev/nvme0n1': Input/output error |
| |
| We added some debug code in nvme device driver. It showed us the first |
| op and the second op have the same bi and pi address. This is not |
| correct. |
| |
| 1st op: nvme0n1 Op:Wr slba 0x505 length 0x100, PI ctrl=0x1400, |
| dsmgmt=0x0, AT=0x0 & RT=0x505 |
| Guard 0x00b1, AT 0x0000, RT physical 0x00000505 RT virtual 0x00002828 |
| |
| 2nd op: nvme0n1 Op:Wr slba 0x605 length 0x1, PI ctrl=0x1400, dsmgmt=0x0, |
| AT=0x0 & RT=0x605 ==> This op fails and subsequent 5 retires.. |
| Guard 0x00b1, AT 0x0000, RT physical 0x00000605 RT virtual 0x00002828 |
| |
| With the fix, It showed us both of the first op and the second op have |
| correct bi and pi address. |
| |
| 1st op: nvme2n1 Op:Wr slba 0x505 length 0x100, PI ctrl=0x1400, |
| dsmgmt=0x0, AT=0x0 & RT=0x505 |
| Guard 0x5ccb, AT 0x0000, RT physical 0x00000505 RT virtual |
| 0x00002828 |
| 2nd op: nvme2n1 Op:Wr slba 0x605 length 0x1, PI ctrl=0x1400, dsmgmt=0x0, |
| AT=0x0 & RT=0x605 |
| Guard 0xab4c, AT 0x0000, RT physical 0x00000605 RT virtual |
| 0x00003028 |
| |
| Signed-off-by: Wen Xiong <wenxiong@linux.vnet.ibm.com> |
| Signed-off-by: Jens Axboe <axboe@fb.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| block/blk-mq.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/block/blk-mq.c |
| +++ b/block/blk-mq.c |
| @@ -1265,13 +1265,13 @@ static blk_qc_t blk_mq_make_request(stru |
| |
| blk_queue_bounce(q, &bio); |
| |
| + blk_queue_split(q, &bio, q->bio_split); |
| + |
| if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { |
| bio_io_error(bio); |
| return BLK_QC_T_NONE; |
| } |
| |
| - blk_queue_split(q, &bio, q->bio_split); |
| - |
| if (!is_flush_fua && !blk_queue_nomerges(q) && |
| blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq)) |
| return BLK_QC_T_NONE; |