• Xiaoguang Wang's avatar
    io_uring: fix io_wqe->work_list corruption · 0020ef04
    Xiaoguang Wang authored
    For the first time a req punted to io-wq, we'll initialize io_wq_work's
    list to be NULL, then insert req to io_wqe->work_list. If this req is not
    inserted into tail of io_wqe->work_list, this req's io_wq_work list will
    point to another req's io_wq_work. For splitted bio case, this req maybe
    inserted to io_wqe->work_list repeatedly, once we insert it to tail of
    io_wqe->work_list for the second time, now io_wq_work->list->next will be
    invalid pointer, which then result in many strang error, panic, kernel
    soft-lockup, rcu stall, etc.
    
    In my vm, kernel doest not have commit cc29e1bf ("block: disable
    iopoll for split bio"), below fio job can reproduce this bug steadily:
    [global]
    name=iouring-sqpoll-iopoll-1
    ioengine=io_uring
    iodepth=128
    numjobs=1
    thread
    rw=randread
    direct=1
    registerfiles=1
    hipri=1
    bs=4m
    size=100M
    runtime=120
    time_based
    group_reporting
    randrepeat=0
    
    [device]
    directory=/home/feiman.wxg/mntpoint/  # an ext4 mount point
    
    If we have commit cc29e1bf ("block: disable iopoll for split bio"),
    there will no splitted bio case for polled io, but I think we still to need
    to fix this list corruption, it also should maybe go to stable branchs.
    
    To fix this corruption, if a req is inserted into tail of io_wqe->work_list,
    initialize req->io_wq_work->list->next to bu NULL.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
    Reviewed-by: default avatarPavel Begunkov <asml.silence@gmail.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    0020ef04
io-wq.h 3.61 KB