]> git.baikalelectronics.ru Git - kernel.git/commitdiff
SUNRPC: rpc_wake_up() should wake up tasks in the correct order
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 22 Oct 2020 21:40:33 +0000 (17:40 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 2 Dec 2020 19:05:51 +0000 (14:05 -0500)
Currently, we wake up the tasks by priority queue ordering, which means
that we ignore the batching that is supposed to help with QoS issues.

Fixes: a1ede647f1d8 ("SUNRPC: Remove the bh-safe lock requirement on the rpc_wait_queue->lock")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
net/sunrpc/sched.c

index f06d7c315017cd45b38bec52e0af1ad7638b4599..cf702a5f7fe5de023edf4814a6c326999df254e5 100644 (file)
@@ -675,6 +675,23 @@ struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *queue)
 }
 EXPORT_SYMBOL_GPL(rpc_wake_up_next);
 
+/**
+ * rpc_wake_up_locked - wake up all rpc_tasks
+ * @queue: rpc_wait_queue on which the tasks are sleeping
+ *
+ */
+static void rpc_wake_up_locked(struct rpc_wait_queue *queue)
+{
+       struct rpc_task *task;
+
+       for (;;) {
+               task = __rpc_find_next_queued(queue);
+               if (task == NULL)
+                       break;
+               rpc_wake_up_task_queue_locked(queue, task);
+       }
+}
+
 /**
  * rpc_wake_up - wake up all rpc_tasks
  * @queue: rpc_wait_queue on which the tasks are sleeping
@@ -683,25 +700,28 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next);
  */
 void rpc_wake_up(struct rpc_wait_queue *queue)
 {
-       struct list_head *head;
-
        spin_lock(&queue->lock);
-       head = &queue->tasks[queue->maxpriority];
+       rpc_wake_up_locked(queue);
+       spin_unlock(&queue->lock);
+}
+EXPORT_SYMBOL_GPL(rpc_wake_up);
+
+/**
+ * rpc_wake_up_status_locked - wake up all rpc_tasks and set their status value.
+ * @queue: rpc_wait_queue on which the tasks are sleeping
+ * @status: status value to set
+ */
+static void rpc_wake_up_status_locked(struct rpc_wait_queue *queue, int status)
+{
+       struct rpc_task *task;
+
        for (;;) {
-               while (!list_empty(head)) {
-                       struct rpc_task *task;
-                       task = list_first_entry(head,
-                                       struct rpc_task,
-                                       u.tk_wait.list);
-                       rpc_wake_up_task_queue_locked(queue, task);
-               }
-               if (head == &queue->tasks[0])
+               task = __rpc_find_next_queued(queue);
+               if (task == NULL)
                        break;
-               head--;
+               rpc_wake_up_task_queue_set_status_locked(queue, task, status);
        }
-       spin_unlock(&queue->lock);
 }
-EXPORT_SYMBOL_GPL(rpc_wake_up);
 
 /**
  * rpc_wake_up_status - wake up all rpc_tasks and set their status value.
@@ -712,23 +732,8 @@ EXPORT_SYMBOL_GPL(rpc_wake_up);
  */
 void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
 {
-       struct list_head *head;
-
        spin_lock(&queue->lock);
-       head = &queue->tasks[queue->maxpriority];
-       for (;;) {
-               while (!list_empty(head)) {
-                       struct rpc_task *task;
-                       task = list_first_entry(head,
-                                       struct rpc_task,
-                                       u.tk_wait.list);
-                       task->tk_status = status;
-                       rpc_wake_up_task_queue_locked(queue, task);
-               }
-               if (head == &queue->tasks[0])
-                       break;
-               head--;
-       }
+       rpc_wake_up_status_locked(queue, status);
        spin_unlock(&queue->lock);
 }
 EXPORT_SYMBOL_GPL(rpc_wake_up_status);