linux_dsm_epyc7002/block
Yufen Yu 1d2310d95f block: only update parent bi_status when bio fail
[ Upstream commit 3edf5346e4f2ce2fa0c94651a90a8dda169565ee ]

For multiple split bios, if one of the bio is fail, the whole
should return error to application. But we found there is a race
between bio_integrity_verify_fn and bio complete, which return
io success to application after one of the bio fail. The race as
following:

split bio(READ)          kworker

nvme_complete_rq
blk_update_request //split error=0
  bio_endio
    bio_integrity_endio
      queue_work(kintegrityd_wq, &bip->bip_work);

                         bio_integrity_verify_fn
                         bio_endio //split bio
                          __bio_chain_endio
                             if (!parent->bi_status)

                               <interrupt entry>
                               nvme_irq
                                 blk_update_request //parent error=7
                                 req_bio_endio
                                    bio->bi_status = 7 //parent bio
                               <interrupt exit>

                               parent->bi_status = 0
                        parent->bi_end_io() // return bi_status=0

The bio has been split as two: split and parent. When split
bio completed, it depends on kworker to do endio, while
bio_integrity_verify_fn have been interrupted by parent bio
complete irq handler. Then, parent bio->bi_status which have
been set in irq handler will overwrite by kworker.

In fact, even without the above race, we also need to conside
the concurrency beteen mulitple split bio complete and update
the same parent bi_status. Normally, multiple split bios will
be issued to the same hctx and complete from the same irq
vector. But if we have updated queue map between multiple split
bios, these bios may complete on different hw queue and different
irq vector. Then the concurrency update parent bi_status may
cause the final status error.

Suggested-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20210331115359.1125679-1-yuyufen@huawei.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-04-16 11:43:21 +02:00
..
partitions
badblocks.c
bfq-cgroup.c
bfq-iosched.c bfq: Avoid false bfq queue merging 2021-03-04 11:37:18 +01:00
bfq-iosched.h
bfq-wf2q.c
bio-integrity.c
bio.c block: only update parent bi_status when bio fail 2021-04-16 11:43:21 +02:00
blk-cgroup-rwstat.c blk-cgroup: Fix the recursive blkg rwstat 2021-03-30 14:31:48 +02:00
blk-cgroup-rwstat.h
blk-cgroup.c blk-cgroup: Use cond_resched() when destroy blkgs 2021-02-13 13:55:13 +01:00
blk-core.c scsi: block: Do not accept any requests while suspended 2021-01-12 20:18:17 +01:00
blk-crypto-fallback.c
blk-crypto-internal.h
blk-crypto.c
blk-exec.c
blk-flush.c
blk-integrity.c
blk-ioc.c
blk-iocost.c blk-iocost: fix NULL iocg deref from racing against initialization 2021-01-12 20:18:23 +01:00
blk-iolatency.c
blk-lib.c
blk-map.c
blk-merge.c block: recalculate segment count for multi-segment discards correctly 2021-03-30 14:32:06 +02:00
blk-mq-cpumap.c
blk-mq-debugfs-zoned.c
blk-mq-debugfs.c blk-mq-debugfs: Add decode for BLK_MQ_F_TAG_HCTX_SHARED 2021-01-19 18:27:29 +01:00
blk-mq-debugfs.h
blk-mq-pci.c
blk-mq-rdma.c
blk-mq-sched.c
blk-mq-sched.h
blk-mq-sysfs.c
blk-mq-tag.c
blk-mq-tag.h
blk-mq-virtio.c
blk-mq.c scsi: block: Remove RQF_PREEMPT and BLK_MQ_REQ_PREEMPT 2021-01-12 20:18:17 +01:00
blk-mq.h blk-mq: test QUEUE_FLAG_HCTX_ACTIVE for sbitmap_shared in hctx_may_queue 2021-02-03 23:28:44 +01:00
blk-pm.c scsi: block: Fix a race in the runtime power management code 2021-01-06 14:56:50 +01:00
blk-pm.h scsi: block: Do not accept any requests while suspended 2021-01-12 20:18:17 +01:00
blk-rq-qos.c
blk-rq-qos.h
blk-settings.c blk-settings: align max_sectors on "logical_block_size" boundary 2021-03-04 11:38:22 +01:00
blk-stat.c
blk-stat.h
blk-sysfs.c
blk-throttle.c
blk-timeout.c
blk-wbt.c
blk-wbt.h
blk-zoned.c block: Fix REQ_OP_ZONE_RESET_ALL handling 2021-03-30 14:31:51 +02:00
blk.h
bounce.c
bsg-lib.c
bsg.c bsg: free the request before return error code 2021-03-04 11:37:42 +01:00
cmdline-parser.c
elevator.c
genhd.c block: Suppress uevent for hidden device when removed 2021-03-30 14:31:52 +02:00
ioctl.c block: reopen the device in blkdev_reread_part 2021-03-04 11:38:21 +01:00
ioprio.c
Kconfig
Kconfig.iosched
keyslot-manager.c
kyber-iosched.c
Makefile
mq-deadline.c
opal_proto.h
scsi_ioctl.c
sed-opal.c
t10-pi.c