|
@@ -97,14 +97,16 @@ __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
|
|
|
/*
|
|
|
* Add new request to a priority queue.
|
|
|
*/
|
|
|
-static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct rpc_task *task)
|
|
|
+static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue,
|
|
|
+ struct rpc_task *task,
|
|
|
+ unsigned char queue_priority)
|
|
|
{
|
|
|
struct list_head *q;
|
|
|
struct rpc_task *t;
|
|
|
|
|
|
INIT_LIST_HEAD(&task->u.tk_wait.links);
|
|
|
- q = &queue->tasks[task->tk_priority];
|
|
|
- if (unlikely(task->tk_priority > queue->maxpriority))
|
|
|
+ q = &queue->tasks[queue_priority];
|
|
|
+ if (unlikely(queue_priority > queue->maxpriority))
|
|
|
q = &queue->tasks[queue->maxpriority];
|
|
|
list_for_each_entry(t, q, u.tk_wait.list) {
|
|
|
if (t->tk_owner == task->tk_owner) {
|
|
@@ -123,12 +125,14 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct r
|
|
|
* improve overall performance.
|
|
|
* Everyone else gets appended to the queue to ensure proper FIFO behavior.
|
|
|
*/
|
|
|
-static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task)
|
|
|
+static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
|
|
|
+ struct rpc_task *task,
|
|
|
+ unsigned char queue_priority)
|
|
|
{
|
|
|
BUG_ON (RPC_IS_QUEUED(task));
|
|
|
|
|
|
if (RPC_IS_PRIORITY(queue))
|
|
|
- __rpc_add_wait_queue_priority(queue, task);
|
|
|
+ __rpc_add_wait_queue_priority(queue, task, queue_priority);
|
|
|
else if (RPC_IS_SWAPPER(task))
|
|
|
list_add(&task->u.tk_wait.list, &queue->tasks[0]);
|
|
|
else
|
|
@@ -311,13 +315,15 @@ static void rpc_make_runnable(struct rpc_task *task)
|
|
|
* NB: An RPC task will only receive interrupt-driven events as long
|
|
|
* as it's on a wait queue.
|
|
|
*/
|
|
|
-static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
|
|
- rpc_action action)
|
|
|
+static void __rpc_sleep_on_priority(struct rpc_wait_queue *q,
|
|
|
+ struct rpc_task *task,
|
|
|
+ rpc_action action,
|
|
|
+ unsigned char queue_priority)
|
|
|
{
|
|
|
dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
|
|
|
task->tk_pid, rpc_qname(q), jiffies);
|
|
|
|
|
|
- __rpc_add_wait_queue(q, task);
|
|
|
+ __rpc_add_wait_queue(q, task, queue_priority);
|
|
|
|
|
|
BUG_ON(task->tk_callback != NULL);
|
|
|
task->tk_callback = action;
|
|
@@ -334,11 +340,25 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
|
|
* Protect the queue operations.
|
|
|
*/
|
|
|
spin_lock_bh(&q->lock);
|
|
|
- __rpc_sleep_on(q, task, action);
|
|
|
+ __rpc_sleep_on_priority(q, task, action, task->tk_priority);
|
|
|
spin_unlock_bh(&q->lock);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rpc_sleep_on);
|
|
|
|
|
|
+void rpc_sleep_on_priority(struct rpc_wait_queue *q, struct rpc_task *task,
|
|
|
+ rpc_action action, int priority)
|
|
|
+{
|
|
|
+ /* We shouldn't ever put an inactive task to sleep */
|
|
|
+ BUG_ON(!RPC_IS_ACTIVATED(task));
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Protect the queue operations.
|
|
|
+ */
|
|
|
+ spin_lock_bh(&q->lock);
|
|
|
+ __rpc_sleep_on_priority(q, task, action, priority - RPC_PRIORITY_LOW);
|
|
|
+ spin_unlock_bh(&q->lock);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* __rpc_do_wake_up_task - wake up a single rpc_task
|
|
|
* @queue: wait queue
|