diff options
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r-- | net/sunrpc/sched.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 3e0b22382a3b..9433a113862c 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -38,7 +38,6 @@ static struct kmem_cache *rpc_buffer_slabp __read_mostly; | |||
38 | static mempool_t *rpc_task_mempool __read_mostly; | 38 | static mempool_t *rpc_task_mempool __read_mostly; |
39 | static mempool_t *rpc_buffer_mempool __read_mostly; | 39 | static mempool_t *rpc_buffer_mempool __read_mostly; |
40 | 40 | ||
41 | static void __rpc_default_timer(struct rpc_task *task); | ||
42 | static void rpc_async_schedule(struct work_struct *); | 41 | static void rpc_async_schedule(struct work_struct *); |
43 | static void rpc_release_task(struct rpc_task *task); | 42 | static void rpc_release_task(struct rpc_task *task); |
44 | 43 | ||
@@ -66,25 +65,13 @@ __rpc_disable_timer(struct rpc_task *task) | |||
66 | } | 65 | } |
67 | 66 | ||
68 | /* | 67 | /* |
69 | * Run a timeout function. | 68 | * Default timeout handler if none specified by user |
70 | * We use the callback in order to allow __rpc_wake_up_task() | ||
71 | * and friends to disable the timer synchronously on SMP systems | ||
72 | * without calling del_timer_sync(). The latter could cause a | ||
73 | * deadlock if called while we're holding spinlocks... | ||
74 | */ | 69 | */ |
75 | static void rpc_run_timer(struct rpc_task *task) | 70 | static void |
71 | __rpc_default_timer(struct rpc_task *task) | ||
76 | { | 72 | { |
77 | void (*callback)(struct rpc_task *); | 73 | dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid); |
78 | 74 | task->tk_status = -ETIMEDOUT; | |
79 | callback = task->tk_timeout_fn; | ||
80 | task->tk_timeout_fn = NULL; | ||
81 | if (callback && RPC_IS_QUEUED(task)) { | ||
82 | dprintk("RPC: %5u running timer\n", task->tk_pid); | ||
83 | callback(task); | ||
84 | } | ||
85 | smp_mb__before_clear_bit(); | ||
86 | clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | ||
87 | smp_mb__after_clear_bit(); | ||
88 | } | 75 | } |
89 | 76 | ||
90 | /* | 77 | /* |
@@ -416,17 +403,6 @@ static void __rpc_wake_up_task(struct rpc_task *task) | |||
416 | } | 403 | } |
417 | 404 | ||
418 | /* | 405 | /* |
419 | * Default timeout handler if none specified by user | ||
420 | */ | ||
421 | static void | ||
422 | __rpc_default_timer(struct rpc_task *task) | ||
423 | { | ||
424 | dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid); | ||
425 | task->tk_status = -ETIMEDOUT; | ||
426 | rpc_wake_up_task(task); | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Wake up the specified task | 406 | * Wake up the specified task |
431 | */ | 407 | */ |
432 | void rpc_wake_up_task(struct rpc_task *task) | 408 | void rpc_wake_up_task(struct rpc_task *task) |
@@ -578,9 +554,37 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) | |||
578 | } | 554 | } |
579 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); | 555 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); |
580 | 556 | ||
557 | /* | ||
558 | * Run a timeout function. | ||
559 | */ | ||
560 | static void rpc_run_timer(unsigned long ptr) | ||
561 | { | ||
562 | struct rpc_task *task = (struct rpc_task *)ptr; | ||
563 | void (*callback)(struct rpc_task *); | ||
564 | |||
565 | if (!rpc_start_wakeup(task)) | ||
566 | goto out; | ||
567 | if (RPC_IS_QUEUED(task)) { | ||
568 | struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq; | ||
569 | callback = task->tk_timeout_fn; | ||
570 | |||
571 | dprintk("RPC: %5u running timer\n", task->tk_pid); | ||
572 | if (callback != NULL) | ||
573 | callback(task); | ||
574 | /* Note: we're already in a bh-safe context */ | ||
575 | spin_lock(&queue->lock); | ||
576 | __rpc_do_wake_up_task(task); | ||
577 | spin_unlock(&queue->lock); | ||
578 | } | ||
579 | rpc_finish_wakeup(task); | ||
580 | out: | ||
581 | smp_mb__before_clear_bit(); | ||
582 | clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | ||
583 | smp_mb__after_clear_bit(); | ||
584 | } | ||
585 | |||
581 | static void __rpc_atrun(struct rpc_task *task) | 586 | static void __rpc_atrun(struct rpc_task *task) |
582 | { | 587 | { |
583 | rpc_wake_up_task(task); | ||
584 | } | 588 | } |
585 | 589 | ||
586 | /* | 590 | /* |
@@ -816,8 +820,7 @@ EXPORT_SYMBOL_GPL(rpc_free); | |||
816 | static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) | 820 | static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) |
817 | { | 821 | { |
818 | memset(task, 0, sizeof(*task)); | 822 | memset(task, 0, sizeof(*task)); |
819 | setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer, | 823 | setup_timer(&task->tk_timer, rpc_run_timer, (unsigned long)task); |
820 | (unsigned long)task); | ||
821 | atomic_set(&task->tk_count, 1); | 824 | atomic_set(&task->tk_count, 1); |
822 | task->tk_flags = task_setup_data->flags; | 825 | task->tk_flags = task_setup_data->flags; |
823 | task->tk_ops = task_setup_data->callback_ops; | 826 | task->tk_ops = task_setup_data->callback_ops; |