Merge tag 'amd-drm-fixes-5.6-2020-03-11' of git://people.freedesktop.org/~agd5f/linux...
[linux-2.6-microblaze.git] / fs / io-wq.c
index bf8ed1b..5cef075 100644 (file)
@@ -502,7 +502,7 @@ next:
                if (worker->mm)
                        work->flags |= IO_WQ_WORK_HAS_MM;
 
-               if (wq->get_work && !(work->flags & IO_WQ_WORK_INTERNAL)) {
+               if (wq->get_work) {
                        put_work = work;
                        wq->get_work(work);
                }
@@ -747,6 +747,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);
@@ -760,8 +771,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;
        }
 
@@ -900,8 +910,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;
        }
 
@@ -976,8 +985,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;
        }
 
@@ -1049,42 +1057,6 @@ enum io_wq_cancel io_wq_cancel_pid(struct io_wq *wq, pid_t pid)
        return ret;
 }
 
-struct io_wq_flush_data {
-       struct io_wq_work work;
-       struct completion done;
-};
-
-static void io_wq_flush_func(struct io_wq_work **workptr)
-{
-       struct io_wq_work *work = *workptr;
-       struct io_wq_flush_data *data;
-
-       data = container_of(work, struct io_wq_flush_data, work);
-       complete(&data->done);
-}
-
-/*
- * Doesn't wait for previously queued work to finish. When this completes,
- * it just means that previously queued work was started.
- */
-void io_wq_flush(struct io_wq *wq)
-{
-       struct io_wq_flush_data data;
-       int node;
-
-       for_each_node(node) {
-               struct io_wqe *wqe = wq->wqes[node];
-
-               if (!node_online(node))
-                       continue;
-               init_completion(&data.done);
-               INIT_IO_WORK(&data.work, io_wq_flush_func);
-               data.work.flags |= IO_WQ_WORK_INTERNAL;
-               io_wqe_enqueue(wqe, &data.work);
-               wait_for_completion(&data.done);
-       }
-}
-
 struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
 {
        int ret = -ENOMEM, node;