Commit e4c72201 authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: rpc_wake_up() should wake up tasks in the correct order

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: c049f8ea ("SUNRPC: Remove the bh-safe lock requirement on the rpc_wait_queue->lock")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 76998ebb
...@@ -675,6 +675,23 @@ struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *queue) ...@@ -675,6 +675,23 @@ struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *queue)
} }
EXPORT_SYMBOL_GPL(rpc_wake_up_next); 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 * rpc_wake_up - wake up all rpc_tasks
* @queue: rpc_wait_queue on which the tasks are sleeping * @queue: rpc_wait_queue on which the tasks are sleeping
...@@ -683,25 +700,28 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next); ...@@ -683,25 +700,28 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next);
*/ */
void rpc_wake_up(struct rpc_wait_queue *queue) void rpc_wake_up(struct rpc_wait_queue *queue)
{ {
struct list_head *head;
spin_lock(&queue->lock); 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 (;;) { for (;;) {
while (!list_empty(head)) { task = __rpc_find_next_queued(queue);
struct rpc_task *task; if (task == NULL)
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])
break; 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. * rpc_wake_up_status - wake up all rpc_tasks and set their status value.
...@@ -712,23 +732,8 @@ EXPORT_SYMBOL_GPL(rpc_wake_up); ...@@ -712,23 +732,8 @@ EXPORT_SYMBOL_GPL(rpc_wake_up);
*/ */
void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
{ {
struct list_head *head;
spin_lock(&queue->lock); spin_lock(&queue->lock);
head = &queue->tasks[queue->maxpriority]; rpc_wake_up_status_locked(queue, status);
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--;
}
spin_unlock(&queue->lock); spin_unlock(&queue->lock);
} }
EXPORT_SYMBOL_GPL(rpc_wake_up_status); EXPORT_SYMBOL_GPL(rpc_wake_up_status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment