Patch "block: only update parent bi_status when bio fail" has been added to the 5.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    block: only update parent bi_status when bio fail

to the 5.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     block-only-update-parent-bi_status-when-bio-fail.patch
and it can be found in the queue-5.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit b99daf06da51973f9a86bea2e7a6a483d8edf9d0
Author: Yufen Yu <yuyufen@xxxxxxxxxx>
Date:   Wed Mar 31 07:53:59 2021 -0400

    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@xxxxxxxxxx>
    Signed-off-by: Yufen Yu <yuyufen@xxxxxxxxxx>
    Reviewed-by: Ming Lei <ming.lei@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20210331115359.1125679-1-yuyufen@xxxxxxxxxx
    Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/block/bio.c b/block/bio.c
index 1f2cc1fbe283..3209d865828a 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -313,7 +313,7 @@ static struct bio *__bio_chain_endio(struct bio *bio)
 {
 	struct bio *parent = bio->bi_private;
 
-	if (!parent->bi_status)
+	if (bio->bi_status && !parent->bi_status)
 		parent->bi_status = bio->bi_status;
 	bio_put(bio);
 	return parent;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux