diff options
Diffstat (limited to 'net/sunrpc/sched.c')
| -rw-r--r-- | net/sunrpc/sched.c | 38 | 
1 files changed, 29 insertions, 9 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 4814e246a87..d12ffa54581 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -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  |