diff options
Diffstat (limited to 'net/sunrpc/sched.c')
| -rw-r--r-- | net/sunrpc/sched.c | 73 | 
1 files changed, 57 insertions, 16 deletions
| diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 3341d8962786..994cfea2bad6 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -28,6 +28,9 @@  #define RPCDBG_FACILITY		RPCDBG_SCHED  #endif +#define CREATE_TRACE_POINTS +#include <trace/events/sunrpc.h> +  /*   * RPC slabs and memory pools   */ @@ -205,9 +208,7 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c  	queue->qlen = 0;  	setup_timer(&queue->timer_list.timer, __rpc_queue_timer_fn, (unsigned long)queue);  	INIT_LIST_HEAD(&queue->timer_list.list); -#ifdef RPC_DEBUG -	queue->name = qname; -#endif +	rpc_assign_waitqueue_name(queue, qname);  }  void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname) @@ -251,6 +252,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task)  static void rpc_set_active(struct rpc_task *task)  { +	trace_rpc_task_begin(task->tk_client, task, NULL); +  	rpc_task_set_debuginfo(task);  	set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);  } @@ -267,6 +270,8 @@ static int rpc_complete_task(struct rpc_task *task)  	unsigned long flags;  	int ret; +	trace_rpc_task_complete(task->tk_client, task, NULL); +  	spin_lock_irqsave(&wq->lock, flags);  	clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate);  	ret = atomic_dec_and_test(&task->tk_count); @@ -324,6 +329,8 @@ static void __rpc_sleep_on_priority(struct rpc_wait_queue *q,  	dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",  			task->tk_pid, rpc_qname(q), jiffies); +	trace_rpc_task_sleep(task->tk_client, task, q); +  	__rpc_add_wait_queue(q, task, queue_priority);  	BUG_ON(task->tk_callback != NULL); @@ -378,6 +385,8 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task  		return;  	} +	trace_rpc_task_wakeup(task->tk_client, task, queue); +  	__rpc_remove_wait_queue(queue, task);  	rpc_make_runnable(task); @@ -422,7 +431,7 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task);  /*   * Wake up the next task on a priority queue.   */ -static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue) +static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *queue)  {  	struct list_head *q;  	struct rpc_task *task; @@ -467,30 +476,54 @@ new_queue:  new_owner:  	rpc_set_waitqueue_owner(queue, task->tk_owner);  out: -	rpc_wake_up_task_queue_locked(queue, task);  	return task;  } +static struct rpc_task *__rpc_find_next_queued(struct rpc_wait_queue *queue) +{ +	if (RPC_IS_PRIORITY(queue)) +		return __rpc_find_next_queued_priority(queue); +	if (!list_empty(&queue->tasks[0])) +		return list_first_entry(&queue->tasks[0], struct rpc_task, u.tk_wait.list); +	return NULL; +} +  /* - * Wake up the next task on the wait queue. + * Wake up the first task on the wait queue.   */ -struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) +struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *queue, +		bool (*func)(struct rpc_task *, void *), void *data)  {  	struct rpc_task	*task = NULL; -	dprintk("RPC:       wake_up_next(%p \"%s\")\n", +	dprintk("RPC:       wake_up_first(%p \"%s\")\n",  			queue, rpc_qname(queue));  	spin_lock_bh(&queue->lock); -	if (RPC_IS_PRIORITY(queue)) -		task = __rpc_wake_up_next_priority(queue); -	else { -		task_for_first(task, &queue->tasks[0]) +	task = __rpc_find_next_queued(queue); +	if (task != NULL) { +		if (func(task, data))  			rpc_wake_up_task_queue_locked(queue, task); +		else +			task = NULL;  	}  	spin_unlock_bh(&queue->lock);  	return task;  } +EXPORT_SYMBOL_GPL(rpc_wake_up_first); + +static bool rpc_wake_up_next_func(struct rpc_task *task, void *data) +{ +	return true; +} + +/* + * Wake up the next task on the wait queue. +*/ +struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *queue) +{ +	return rpc_wake_up_first(queue, rpc_wake_up_next_func, NULL); +}  EXPORT_SYMBOL_GPL(rpc_wake_up_next);  /** @@ -501,14 +534,18 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next);   */  void rpc_wake_up(struct rpc_wait_queue *queue)  { -	struct rpc_task *task, *next;  	struct list_head *head;  	spin_lock_bh(&queue->lock);  	head = &queue->tasks[queue->maxpriority];  	for (;;) { -		list_for_each_entry_safe(task, next, head, u.tk_wait.list) +		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])  			break;  		head--; @@ -526,13 +563,16 @@ EXPORT_SYMBOL_GPL(rpc_wake_up);   */  void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)  { -	struct rpc_task *task, *next;  	struct list_head *head;  	spin_lock_bh(&queue->lock);  	head = &queue->tasks[queue->maxpriority];  	for (;;) { -		list_for_each_entry_safe(task, next, head, u.tk_wait.list) { +		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);  		} @@ -677,6 +717,7 @@ static void __rpc_execute(struct rpc_task *task)  			if (do_action == NULL)  				break;  		} +		trace_rpc_task_run_action(task->tk_client, task, task->tk_action);  		do_action(task);  		/* | 
