Skip to content

Commit

Permalink
SUNRPC: rpc_wake_up() should wake up tasks in the correct order
Browse files Browse the repository at this point in the history
[ Upstream commit e4c7220 ]

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: c049f8e ("SUNRPC: Remove the bh-safe lock requirement on the rpc_wait_queue->lock")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Trond Myklebust authored and gregkh committed Dec 30, 2020
1 parent a3ac7dd commit 04e9c16
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions net/sunrpc/sched.c
Expand Up @@ -699,6 +699,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
Expand All @@ -707,25 +724,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.
Expand All @@ -736,23 +756,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);
Expand Down

0 comments on commit 04e9c16

Please sign in to comment.