diff options
-rw-r--r-- | fs/nfs/read.c | 8 | ||||
-rw-r--r-- | fs/nfs/write.c | 16 | ||||
-rw-r--r-- | include/linux/sunrpc/sched.h | 2 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 37 |
4 files changed, 15 insertions, 48 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 87546cd277d5..be9e8270f4d7 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -58,19 +58,13 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) | |||
58 | return p; | 58 | return p; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void nfs_readdata_rcu_free(struct rcu_head *head) | 61 | static void nfs_readdata_free(struct nfs_read_data *p) |
62 | { | 62 | { |
63 | struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu); | ||
64 | if (p && (p->pagevec != &p->page_array[0])) | 63 | if (p && (p->pagevec != &p->page_array[0])) |
65 | kfree(p->pagevec); | 64 | kfree(p->pagevec); |
66 | mempool_free(p, nfs_rdata_mempool); | 65 | mempool_free(p, nfs_rdata_mempool); |
67 | } | 66 | } |
68 | 67 | ||
69 | static void nfs_readdata_free(struct nfs_read_data *rdata) | ||
70 | { | ||
71 | call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free); | ||
72 | } | ||
73 | |||
74 | void nfs_readdata_release(void *data) | 68 | void nfs_readdata_release(void *data) |
75 | { | 69 | { |
76 | struct nfs_read_data *rdata = data; | 70 | struct nfs_read_data *rdata = data; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 84495ef90728..30513029c00c 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -58,19 +58,13 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
58 | return p; | 58 | return p; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void nfs_commit_rcu_free(struct rcu_head *head) | 61 | void nfs_commit_free(struct nfs_write_data *p) |
62 | { | 62 | { |
63 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
64 | if (p && (p->pagevec != &p->page_array[0])) | 63 | if (p && (p->pagevec != &p->page_array[0])) |
65 | kfree(p->pagevec); | 64 | kfree(p->pagevec); |
66 | mempool_free(p, nfs_commit_mempool); | 65 | mempool_free(p, nfs_commit_mempool); |
67 | } | 66 | } |
68 | 67 | ||
69 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
70 | { | ||
71 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
72 | } | ||
73 | |||
74 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | 68 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
75 | { | 69 | { |
76 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); | 70 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
@@ -92,19 +86,13 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | |||
92 | return p; | 86 | return p; |
93 | } | 87 | } |
94 | 88 | ||
95 | static void nfs_writedata_rcu_free(struct rcu_head *head) | 89 | static void nfs_writedata_free(struct nfs_write_data *p) |
96 | { | 90 | { |
97 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
98 | if (p && (p->pagevec != &p->page_array[0])) | 91 | if (p && (p->pagevec != &p->page_array[0])) |
99 | kfree(p->pagevec); | 92 | kfree(p->pagevec); |
100 | mempool_free(p, nfs_wdata_mempool); | 93 | mempool_free(p, nfs_wdata_mempool); |
101 | } | 94 | } |
102 | 95 | ||
103 | static void nfs_writedata_free(struct nfs_write_data *wdata) | ||
104 | { | ||
105 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | ||
106 | } | ||
107 | |||
108 | void nfs_writedata_release(void *data) | 96 | void nfs_writedata_release(void *data) |
109 | { | 97 | { |
110 | struct nfs_write_data *wdata = data; | 98 | struct nfs_write_data *wdata = data; |
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index bf69fce84ed0..d1a5c8c1a0f1 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/timer.h> | 12 | #include <linux/timer.h> |
13 | #include <linux/sunrpc/types.h> | 13 | #include <linux/sunrpc/types.h> |
14 | #include <linux/rcupdate.h> | ||
15 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
16 | #include <linux/wait.h> | 15 | #include <linux/wait.h> |
17 | #include <linux/workqueue.h> | 16 | #include <linux/workqueue.h> |
@@ -77,7 +76,6 @@ struct rpc_task { | |||
77 | union { | 76 | union { |
78 | struct work_struct tk_work; /* Async task work queue */ | 77 | struct work_struct tk_work; /* Async task work queue */ |
79 | struct rpc_wait tk_wait; /* RPC wait */ | 78 | struct rpc_wait tk_wait; /* RPC wait */ |
80 | struct rcu_head tk_rcu; /* for task deletion */ | ||
81 | } u; | 79 | } u; |
82 | 80 | ||
83 | unsigned short tk_timeouts; /* maj timeouts */ | 81 | unsigned short tk_timeouts; /* maj timeouts */ |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 88a686a8e43e..cae219c8caeb 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -393,11 +393,9 @@ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct r | |||
393 | */ | 393 | */ |
394 | void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) | 394 | void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) |
395 | { | 395 | { |
396 | rcu_read_lock_bh(); | 396 | spin_lock_bh(&queue->lock); |
397 | spin_lock(&queue->lock); | ||
398 | rpc_wake_up_task_queue_locked(queue, task); | 397 | rpc_wake_up_task_queue_locked(queue, task); |
399 | spin_unlock(&queue->lock); | 398 | spin_unlock_bh(&queue->lock); |
400 | rcu_read_unlock_bh(); | ||
401 | } | 399 | } |
402 | EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); | 400 | EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); |
403 | 401 | ||
@@ -470,16 +468,14 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) | |||
470 | 468 | ||
471 | dprintk("RPC: wake_up_next(%p \"%s\")\n", | 469 | dprintk("RPC: wake_up_next(%p \"%s\")\n", |
472 | queue, rpc_qname(queue)); | 470 | queue, rpc_qname(queue)); |
473 | rcu_read_lock_bh(); | 471 | spin_lock_bh(&queue->lock); |
474 | spin_lock(&queue->lock); | ||
475 | if (RPC_IS_PRIORITY(queue)) | 472 | if (RPC_IS_PRIORITY(queue)) |
476 | task = __rpc_wake_up_next_priority(queue); | 473 | task = __rpc_wake_up_next_priority(queue); |
477 | else { | 474 | else { |
478 | task_for_first(task, &queue->tasks[0]) | 475 | task_for_first(task, &queue->tasks[0]) |
479 | rpc_wake_up_task_queue_locked(queue, task); | 476 | rpc_wake_up_task_queue_locked(queue, task); |
480 | } | 477 | } |
481 | spin_unlock(&queue->lock); | 478 | spin_unlock_bh(&queue->lock); |
482 | rcu_read_unlock_bh(); | ||
483 | 479 | ||
484 | return task; | 480 | return task; |
485 | } | 481 | } |
@@ -496,8 +492,7 @@ void rpc_wake_up(struct rpc_wait_queue *queue) | |||
496 | struct rpc_task *task, *next; | 492 | struct rpc_task *task, *next; |
497 | struct list_head *head; | 493 | struct list_head *head; |
498 | 494 | ||
499 | rcu_read_lock_bh(); | 495 | spin_lock_bh(&queue->lock); |
500 | spin_lock(&queue->lock); | ||
501 | head = &queue->tasks[queue->maxpriority]; | 496 | head = &queue->tasks[queue->maxpriority]; |
502 | for (;;) { | 497 | for (;;) { |
503 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) | 498 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) |
@@ -506,8 +501,7 @@ void rpc_wake_up(struct rpc_wait_queue *queue) | |||
506 | break; | 501 | break; |
507 | head--; | 502 | head--; |
508 | } | 503 | } |
509 | spin_unlock(&queue->lock); | 504 | spin_unlock_bh(&queue->lock); |
510 | rcu_read_unlock_bh(); | ||
511 | } | 505 | } |
512 | EXPORT_SYMBOL_GPL(rpc_wake_up); | 506 | EXPORT_SYMBOL_GPL(rpc_wake_up); |
513 | 507 | ||
@@ -523,8 +517,7 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) | |||
523 | struct rpc_task *task, *next; | 517 | struct rpc_task *task, *next; |
524 | struct list_head *head; | 518 | struct list_head *head; |
525 | 519 | ||
526 | rcu_read_lock_bh(); | 520 | spin_lock_bh(&queue->lock); |
527 | spin_lock(&queue->lock); | ||
528 | head = &queue->tasks[queue->maxpriority]; | 521 | head = &queue->tasks[queue->maxpriority]; |
529 | for (;;) { | 522 | for (;;) { |
530 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) { | 523 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) { |
@@ -535,8 +528,7 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) | |||
535 | break; | 528 | break; |
536 | head--; | 529 | head--; |
537 | } | 530 | } |
538 | spin_unlock(&queue->lock); | 531 | spin_unlock_bh(&queue->lock); |
539 | rcu_read_unlock_bh(); | ||
540 | } | 532 | } |
541 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); | 533 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); |
542 | 534 | ||
@@ -848,13 +840,6 @@ rpc_alloc_task(void) | |||
848 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); | 840 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); |
849 | } | 841 | } |
850 | 842 | ||
851 | static void rpc_free_task_rcu(struct rcu_head *rcu) | ||
852 | { | ||
853 | struct rpc_task *task = container_of(rcu, struct rpc_task, u.tk_rcu); | ||
854 | dprintk("RPC: %5u freeing task\n", task->tk_pid); | ||
855 | mempool_free(task, rpc_task_mempool); | ||
856 | } | ||
857 | |||
858 | /* | 843 | /* |
859 | * Create a new task for the specified client. | 844 | * Create a new task for the specified client. |
860 | */ | 845 | */ |
@@ -883,8 +868,10 @@ static void rpc_free_task(struct rpc_task *task) | |||
883 | const struct rpc_call_ops *tk_ops = task->tk_ops; | 868 | const struct rpc_call_ops *tk_ops = task->tk_ops; |
884 | void *calldata = task->tk_calldata; | 869 | void *calldata = task->tk_calldata; |
885 | 870 | ||
886 | if (task->tk_flags & RPC_TASK_DYNAMIC) | 871 | if (task->tk_flags & RPC_TASK_DYNAMIC) { |
887 | call_rcu_bh(&task->u.tk_rcu, rpc_free_task_rcu); | 872 | dprintk("RPC: %5u freeing task\n", task->tk_pid); |
873 | mempool_free(task, rpc_task_mempool); | ||
874 | } | ||
888 | rpc_release_calldata(tk_ops, calldata); | 875 | rpc_release_calldata(tk_ops, calldata); |
889 | } | 876 | } |
890 | 877 | ||