lkml.org 
[lkml]   [2020]   [Mar]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.5 022/119] io-wq: fix IO_WQ_WORK_NO_CANCEL cancellation
    Date
    From: Pavel Begunkov <asml.silence@gmail.com>

    [ Upstream commit fc04c39bae01a607454f7619665309870c60937a ]

    To cancel a work, io-wq sets IO_WQ_WORK_CANCEL and executes the
    callback. However, IO_WQ_WORK_NO_CANCEL works will just execute and may
    return next work, which will be ignored and lost.

    Cancel the whole link.

    Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/io-wq.c | 20 ++++++++++++++------
    1 file changed, 14 insertions(+), 6 deletions(-)

    diff --git a/fs/io-wq.c b/fs/io-wq.c
    index 25ffb6685baea..1f46fe663b287 100644
    --- a/fs/io-wq.c
    +++ b/fs/io-wq.c
    @@ -733,6 +733,17 @@ static bool io_wq_can_queue(struct io_wqe *wqe, struct io_wqe_acct *acct,
    return true;
    }

    +static void io_run_cancel(struct io_wq_work *work)
    +{
    + do {
    + struct io_wq_work *old_work = work;
    +
    + work->flags |= IO_WQ_WORK_CANCEL;
    + work->func(&work);
    + work = (work == old_work) ? NULL : work;
    + } while (work);
    +}
    +
    static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work)
    {
    struct io_wqe_acct *acct = io_work_get_acct(wqe, work);
    @@ -745,8 +756,7 @@ static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work)
    * It's close enough to not be an issue, fork() has the same delay.
    */
    if (unlikely(!io_wq_can_queue(wqe, acct, work))) {
    - work->flags |= IO_WQ_WORK_CANCEL;
    - work->func(&work);
    + io_run_cancel(work);
    return;
    }

    @@ -882,8 +892,7 @@ static enum io_wq_cancel io_wqe_cancel_cb_work(struct io_wqe *wqe,
    spin_unlock_irqrestore(&wqe->lock, flags);

    if (found) {
    - work->flags |= IO_WQ_WORK_CANCEL;
    - work->func(&work);
    + io_run_cancel(work);
    return IO_WQ_CANCEL_OK;
    }

    @@ -957,8 +966,7 @@ static enum io_wq_cancel io_wqe_cancel_work(struct io_wqe *wqe,
    spin_unlock_irqrestore(&wqe->lock, flags);

    if (found) {
    - work->flags |= IO_WQ_WORK_CANCEL;
    - work->func(&work);
    + io_run_cancel(work);
    return IO_WQ_CANCEL_OK;
    }

    --
    2.20.1


    \
     
     \ /
      Last update: 2020-03-24 14:22    [W:4.336 / U:0.348 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site