Oleg noticed that our checking of data.got_token is unsafe in the
cleanup case, and should really use a memory barrier.  Use the
READ_ONCE/WRITE_ONCE helpers on got_token so we can be sure we're always
safe.

Signed-off-by: Josef Bacik <[email protected]>
---
 block/blk-rq-qos.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
index 67a0a4c07060..f4aa7b818cf5 100644
--- a/block/blk-rq-qos.c
+++ b/block/blk-rq-qos.c
@@ -201,7 +201,7 @@ static int rq_qos_wake_function(struct wait_queue_entry 
*curr,
        if (!data->cb(data->rqw, data->private_data))
                return -1;
 
-       data->got_token = true;
+       WRITE_ONCE(data->got_token, true);
        list_del_init(&curr->entry);
        wake_up_process(data->task);
        return 1;
@@ -246,7 +246,7 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
        prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
        has_sleeper = !wq_has_single_sleeper(&rqw->wait);
        do {
-               if (data.got_token)
+               if (READ_ONCE(data.got_token))
                        break;
                if (!has_sleeper && acquire_inflight_cb(rqw, private_data)) {
                        finish_wait(&rqw->wait, &data.wq);
@@ -256,7 +256,7 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
                         * which means we now have two. Put our local token
                         * and wake anyone else potentially waiting for one.
                         */
-                       if (data.got_token)
+                       if (READ_ONCE(data.got_token))
                                cleanup_cb(rqw, private_data);
                        break;
                }
-- 
2.17.1

Reply via email to