diff options
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r-- | net/sunrpc/sched.c | 50 |
1 files changed, 15 insertions, 35 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 35acdc39bfcb..caf12fd6b6af 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -56,29 +56,18 @@ struct workqueue_struct *rpciod_workqueue; | |||
56 | * queue->lock and bh_disabled in order to avoid races within | 56 | * queue->lock and bh_disabled in order to avoid races within |
57 | * rpc_run_timer(). | 57 | * rpc_run_timer(). |
58 | */ | 58 | */ |
59 | static inline void | 59 | static void |
60 | __rpc_disable_timer(struct rpc_task *task) | 60 | __rpc_disable_timer(struct rpc_task *task) |
61 | { | 61 | { |
62 | dprintk("RPC: %5u disabling timer\n", task->tk_pid); | 62 | dprintk("RPC: %5u disabling timer\n", task->tk_pid); |
63 | task->tk_timeout_fn = NULL; | ||
64 | task->tk_timeout = 0; | 63 | task->tk_timeout = 0; |
65 | } | 64 | } |
66 | 65 | ||
67 | /* | 66 | /* |
68 | * Default timeout handler if none specified by user | ||
69 | */ | ||
70 | static void | ||
71 | __rpc_default_timer(struct rpc_task *task) | ||
72 | { | ||
73 | dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid); | ||
74 | task->tk_status = -ETIMEDOUT; | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Set up a timer for the current task. | 67 | * Set up a timer for the current task. |
79 | */ | 68 | */ |
80 | static inline void | 69 | static void |
81 | __rpc_add_timer(struct rpc_task *task, rpc_action timer) | 70 | __rpc_add_timer(struct rpc_task *task) |
82 | { | 71 | { |
83 | if (!task->tk_timeout) | 72 | if (!task->tk_timeout) |
84 | return; | 73 | return; |
@@ -86,10 +75,6 @@ __rpc_add_timer(struct rpc_task *task, rpc_action timer) | |||
86 | dprintk("RPC: %5u setting alarm for %lu ms\n", | 75 | dprintk("RPC: %5u setting alarm for %lu ms\n", |
87 | task->tk_pid, task->tk_timeout * 1000 / HZ); | 76 | task->tk_pid, task->tk_timeout * 1000 / HZ); |
88 | 77 | ||
89 | if (timer) | ||
90 | task->tk_timeout_fn = timer; | ||
91 | else | ||
92 | task->tk_timeout_fn = __rpc_default_timer; | ||
93 | set_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | 78 | set_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); |
94 | mod_timer(&task->tk_timer, jiffies + task->tk_timeout); | 79 | mod_timer(&task->tk_timer, jiffies + task->tk_timeout); |
95 | } | 80 | } |
@@ -297,7 +282,6 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); | |||
297 | */ | 282 | */ |
298 | static void rpc_make_runnable(struct rpc_task *task) | 283 | static void rpc_make_runnable(struct rpc_task *task) |
299 | { | 284 | { |
300 | BUG_ON(task->tk_timeout_fn); | ||
301 | rpc_clear_queued(task); | 285 | rpc_clear_queued(task); |
302 | if (rpc_test_and_set_running(task)) | 286 | if (rpc_test_and_set_running(task)) |
303 | return; | 287 | return; |
@@ -327,7 +311,7 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
327 | * as it's on a wait queue. | 311 | * as it's on a wait queue. |
328 | */ | 312 | */ |
329 | static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 313 | static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
330 | rpc_action action, rpc_action timer) | 314 | rpc_action action) |
331 | { | 315 | { |
332 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", | 316 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", |
333 | task->tk_pid, rpc_qname(q), jiffies); | 317 | task->tk_pid, rpc_qname(q), jiffies); |
@@ -341,11 +325,11 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
341 | 325 | ||
342 | BUG_ON(task->tk_callback != NULL); | 326 | BUG_ON(task->tk_callback != NULL); |
343 | task->tk_callback = action; | 327 | task->tk_callback = action; |
344 | __rpc_add_timer(task, timer); | 328 | __rpc_add_timer(task); |
345 | } | 329 | } |
346 | 330 | ||
347 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 331 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
348 | rpc_action action, rpc_action timer) | 332 | rpc_action action) |
349 | { | 333 | { |
350 | /* Mark the task as being activated if so needed */ | 334 | /* Mark the task as being activated if so needed */ |
351 | rpc_set_active(task); | 335 | rpc_set_active(task); |
@@ -354,7 +338,7 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
354 | * Protect the queue operations. | 338 | * Protect the queue operations. |
355 | */ | 339 | */ |
356 | spin_lock_bh(&q->lock); | 340 | spin_lock_bh(&q->lock); |
357 | __rpc_sleep_on(q, task, action, timer); | 341 | __rpc_sleep_on(q, task, action); |
358 | spin_unlock_bh(&q->lock); | 342 | spin_unlock_bh(&q->lock); |
359 | } | 343 | } |
360 | EXPORT_SYMBOL_GPL(rpc_sleep_on); | 344 | EXPORT_SYMBOL_GPL(rpc_sleep_on); |
@@ -559,20 +543,15 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_status); | |||
559 | static void rpc_run_timer(unsigned long ptr) | 543 | static void rpc_run_timer(unsigned long ptr) |
560 | { | 544 | { |
561 | struct rpc_task *task = (struct rpc_task *)ptr; | 545 | struct rpc_task *task = (struct rpc_task *)ptr; |
562 | void (*callback)(struct rpc_task *); | 546 | struct rpc_wait_queue *queue = task->tk_waitqueue; |
563 | 547 | ||
564 | if (RPC_IS_QUEUED(task)) { | 548 | spin_lock(&queue->lock); |
565 | struct rpc_wait_queue *queue = task->tk_waitqueue; | 549 | if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue) { |
566 | callback = task->tk_timeout_fn; | 550 | dprintk("RPC: %5u timeout\n", task->tk_pid); |
567 | 551 | task->tk_status = -ETIMEDOUT; | |
568 | dprintk("RPC: %5u running timer\n", task->tk_pid); | ||
569 | if (callback != NULL) | ||
570 | callback(task); | ||
571 | /* Note: we're already in a bh-safe context */ | ||
572 | spin_lock(&queue->lock); | ||
573 | rpc_wake_up_task_queue_locked(queue, task); | 552 | rpc_wake_up_task_queue_locked(queue, task); |
574 | spin_unlock(&queue->lock); | ||
575 | } | 553 | } |
554 | spin_unlock(&queue->lock); | ||
576 | smp_mb__before_clear_bit(); | 555 | smp_mb__before_clear_bit(); |
577 | clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | 556 | clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); |
578 | smp_mb__after_clear_bit(); | 557 | smp_mb__after_clear_bit(); |
@@ -580,6 +559,7 @@ static void rpc_run_timer(unsigned long ptr) | |||
580 | 559 | ||
581 | static void __rpc_atrun(struct rpc_task *task) | 560 | static void __rpc_atrun(struct rpc_task *task) |
582 | { | 561 | { |
562 | task->tk_status = 0; | ||
583 | } | 563 | } |
584 | 564 | ||
585 | /* | 565 | /* |
@@ -588,7 +568,7 @@ static void __rpc_atrun(struct rpc_task *task) | |||
588 | void rpc_delay(struct rpc_task *task, unsigned long delay) | 568 | void rpc_delay(struct rpc_task *task, unsigned long delay) |
589 | { | 569 | { |
590 | task->tk_timeout = delay; | 570 | task->tk_timeout = delay; |
591 | rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun); | 571 | rpc_sleep_on(&delay_queue, task, __rpc_atrun); |
592 | } | 572 | } |
593 | EXPORT_SYMBOL_GPL(rpc_delay); | 573 | EXPORT_SYMBOL_GPL(rpc_delay); |
594 | 574 | ||