lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.5 056/257] block, bfq: move forward the getting of an extra ref in bfq_bfqq_move
    Date
    From: Paolo Valente <paolo.valente@linaro.org>

    [ Upstream commit fd1bb3ae54a9a2e0c42709de861c69aa146b8955 ]

    Commit ecedd3d7e199 ("block, bfq: get extra ref to prevent a queue
    from being freed during a group move") gets an extra reference to a
    bfq_queue before possibly deactivating it (temporarily), in
    bfq_bfqq_move(). This prevents the bfq_queue from disappearing before
    being reactivated in its new group.

    Yet, the bfq_queue may also be expired (i.e., its service may be
    stopped) before the bfq_queue is deactivated. And also an expiration
    may lead to a premature freeing. This commit fixes this issue by
    simply moving forward the getting of the extra reference already
    introduced by commit ecedd3d7e199 ("block, bfq: get extra ref to
    prevent a queue from being freed during a group move").

    Reported-by: cki-project@redhat.com
    Tested-by: cki-project@redhat.com
    Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    block/bfq-cgroup.c | 14 +++++++-------
    1 file changed, 7 insertions(+), 7 deletions(-)

    diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
    index 5a64607ce7744..a6d42339fb342 100644
    --- a/block/bfq-cgroup.c
    +++ b/block/bfq-cgroup.c
    @@ -641,6 +641,12 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
    {
    struct bfq_entity *entity = &bfqq->entity;

    + /*
    + * Get extra reference to prevent bfqq from being freed in
    + * next possible expire or deactivate.
    + */
    + bfqq->ref++;
    +
    /* If bfqq is empty, then bfq_bfqq_expire also invokes
    * bfq_del_bfqq_busy, thereby removing bfqq and its entity
    * from data structures related to current group. Otherwise we
    @@ -651,12 +657,6 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
    bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
    false, BFQQE_PREEMPTED);

    - /*
    - * get extra reference to prevent bfqq from being freed in
    - * next possible deactivate
    - */
    - bfqq->ref++;
    -
    if (bfq_bfqq_busy(bfqq))
    bfq_deactivate_bfqq(bfqd, bfqq, false, false);
    else if (entity->on_st)
    @@ -676,7 +676,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,

    if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
    bfq_schedule_dispatch(bfqd);
    - /* release extra ref taken above */
    + /* release extra ref taken above, bfqq may happen to be freed now */
    bfq_put_queue(bfqq);
    }

    --
    2.20.1


    \
     
     \ /
      Last update: 2020-04-16 15:45    [W:4.109 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site