SUNRPC: Allow caller of rpc_sleep_on() to select priority levels
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Sun, 17 Jul 2011 22:11:34 +0000 (18:11 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Sun, 17 Jul 2011 22:11:34 +0000 (18:11 -0400)
Currently, the caller has to change the value of task->tk_priority if
it wants to select on which priority level the task will sleep.

This patch allows the caller to select a priority level at sleep time
rather than always using task->tk_priority.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/sunrpc/sched.h
net/sunrpc/sched.c

index fe2d8e6b923b416908220e2ef70bed01dee60897..e7756896f3ca292f4398304f7761b691232df131 100644 (file)
@@ -227,6 +227,10 @@ void               rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
 void           rpc_destroy_wait_queue(struct rpc_wait_queue *);
 void           rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
                                        rpc_action action);
+void           rpc_sleep_on_priority(struct rpc_wait_queue *,
+                                       struct rpc_task *,
+                                       rpc_action action,
+                                       int priority);
 void           rpc_wake_up_queued_task(struct rpc_wait_queue *,
                                        struct rpc_task *);
 void           rpc_wake_up(struct rpc_wait_queue *);
index 4814e246a874ac1c19c51c5c36e7bbcd60b2d373..d12ffa5458115e3912f8b7f22a337963d8d3213c 100644 (file)
@@ -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
This page took 0.030735 seconds and 5 git commands to generate.