lkml.org 
[lkml]   [2022]   [Dec]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH -next 1/4] block/rq_qos: protect 'q->rq_qos' with queue_lock in rq_qos_exit()
    Date
    From: Yu Kuai <yukuai3@huawei.com>

    queue_lock is held to protect 'q->rqos' in rq_qos_add() and
    rq_qos_del(), however, it's not held in rq_qos_exit(), while they
    can operate the list concurrently:

    t1 t2
    // configure iocost //remove device
    blk_iocost_init del_gendisk
    rq_qos_add rq_qos_exit

    'rqos->ops->exit' can't be called under spinlock because it might
    be scheduled out, hence fix the problem by holding queue_lock to
    fetch the list and reset q->rq_qos first.

    Signed-off-by: Yu Kuai <yukuai3@huawei.com>
    ---
    block/blk-rq-qos.c | 17 ++++++++++++-----
    1 file changed, 12 insertions(+), 5 deletions(-)

    diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
    index 88f0fe7dcf54..efffc6fa55db 100644
    --- a/block/blk-rq-qos.c
    +++ b/block/blk-rq-qos.c
    @@ -288,9 +288,16 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,

    void rq_qos_exit(struct request_queue *q)
    {
    - while (q->rq_qos) {
    - struct rq_qos *rqos = q->rq_qos;
    - q->rq_qos = rqos->next;
    - rqos->ops->exit(rqos);
    - }
    + struct rq_qos *rqos;
    +
    + spin_lock_irq(&q->queue_lock);
    + rqos = q->rq_qos;
    + q->rq_qos = NULL;
    + spin_unlock_irq(&q->queue_lock);
    +
    + do {
    + if (rqos->ops->exit)
    + rqos->ops->exit(rqos);
    + rqos = rqos->next;
    + } while (rqos);
    }
    --
    2.31.1
    \
     
     \ /
      Last update: 2022-12-17 03:49    [W:5.143 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site