diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/sunrpc/sched.c | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index b5723c262a3e..954d7ec86c7e 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -50,8 +50,6 @@ static RPC_WAITQ(delay_queue, "delayq"); | |||
| 50 | /* | 50 | /* |
| 51 | * rpciod-related stuff | 51 | * rpciod-related stuff |
| 52 | */ | 52 | */ |
| 53 | static DEFINE_MUTEX(rpciod_mutex); | ||
| 54 | static atomic_t rpciod_users = ATOMIC_INIT(0); | ||
| 55 | struct workqueue_struct *rpciod_workqueue; | 53 | struct workqueue_struct *rpciod_workqueue; |
| 56 | 54 | ||
| 57 | /* | 55 | /* |
| @@ -961,60 +959,49 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) | |||
| 961 | spin_unlock(&clnt->cl_lock); | 959 | spin_unlock(&clnt->cl_lock); |
| 962 | } | 960 | } |
| 963 | 961 | ||
| 962 | int rpciod_up(void) | ||
| 963 | { | ||
| 964 | return try_module_get(THIS_MODULE) ? 0 : -EINVAL; | ||
| 965 | } | ||
| 966 | |||
| 967 | void rpciod_down(void) | ||
| 968 | { | ||
| 969 | module_put(THIS_MODULE); | ||
| 970 | } | ||
| 971 | |||
| 964 | /* | 972 | /* |
| 965 | * Start up the rpciod process if it's not already running. | 973 | * Start up the rpciod workqueue. |
| 966 | */ | 974 | */ |
| 967 | int | 975 | static int rpciod_start(void) |
| 968 | rpciod_up(void) | ||
| 969 | { | 976 | { |
| 970 | struct workqueue_struct *wq; | 977 | struct workqueue_struct *wq; |
| 971 | int error = 0; | ||
| 972 | |||
| 973 | if (atomic_inc_not_zero(&rpciod_users)) | ||
| 974 | return 0; | ||
| 975 | |||
| 976 | mutex_lock(&rpciod_mutex); | ||
| 977 | 978 | ||
| 978 | /* Guard against races with rpciod_down() */ | ||
| 979 | if (rpciod_workqueue != NULL) | ||
| 980 | goto out_ok; | ||
| 981 | /* | 979 | /* |
| 982 | * Create the rpciod thread and wait for it to start. | 980 | * Create the rpciod thread and wait for it to start. |
| 983 | */ | 981 | */ |
| 984 | dprintk("RPC: creating workqueue rpciod\n"); | 982 | dprintk("RPC: creating workqueue rpciod\n"); |
| 985 | error = -ENOMEM; | ||
| 986 | wq = create_workqueue("rpciod"); | 983 | wq = create_workqueue("rpciod"); |
| 987 | if (wq == NULL) | ||
| 988 | goto out; | ||
| 989 | |||
| 990 | rpciod_workqueue = wq; | 984 | rpciod_workqueue = wq; |
| 991 | error = 0; | 985 | return rpciod_workqueue != NULL; |
| 992 | out_ok: | ||
| 993 | atomic_inc(&rpciod_users); | ||
| 994 | out: | ||
| 995 | mutex_unlock(&rpciod_mutex); | ||
| 996 | return error; | ||
| 997 | } | 986 | } |
| 998 | 987 | ||
| 999 | void | 988 | static void rpciod_stop(void) |
| 1000 | rpciod_down(void) | ||
| 1001 | { | 989 | { |
| 1002 | if (!atomic_dec_and_test(&rpciod_users)) | 990 | struct workqueue_struct *wq = NULL; |
| 1003 | return; | ||
| 1004 | 991 | ||
| 1005 | mutex_lock(&rpciod_mutex); | 992 | if (rpciod_workqueue == NULL) |
| 993 | return; | ||
| 1006 | dprintk("RPC: destroying workqueue rpciod\n"); | 994 | dprintk("RPC: destroying workqueue rpciod\n"); |
| 1007 | 995 | ||
| 1008 | if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) { | 996 | wq = rpciod_workqueue; |
| 1009 | destroy_workqueue(rpciod_workqueue); | 997 | rpciod_workqueue = NULL; |
| 1010 | rpciod_workqueue = NULL; | 998 | destroy_workqueue(wq); |
| 1011 | } | ||
| 1012 | mutex_unlock(&rpciod_mutex); | ||
| 1013 | } | 999 | } |
| 1014 | 1000 | ||
| 1015 | void | 1001 | void |
| 1016 | rpc_destroy_mempool(void) | 1002 | rpc_destroy_mempool(void) |
| 1017 | { | 1003 | { |
| 1004 | rpciod_stop(); | ||
| 1018 | if (rpc_buffer_mempool) | 1005 | if (rpc_buffer_mempool) |
| 1019 | mempool_destroy(rpc_buffer_mempool); | 1006 | mempool_destroy(rpc_buffer_mempool); |
| 1020 | if (rpc_task_mempool) | 1007 | if (rpc_task_mempool) |
| @@ -1048,6 +1035,8 @@ rpc_init_mempool(void) | |||
| 1048 | rpc_buffer_slabp); | 1035 | rpc_buffer_slabp); |
| 1049 | if (!rpc_buffer_mempool) | 1036 | if (!rpc_buffer_mempool) |
| 1050 | goto err_nomem; | 1037 | goto err_nomem; |
| 1038 | if (!rpciod_start()) | ||
| 1039 | goto err_nomem; | ||
| 1051 | return 0; | 1040 | return 0; |
| 1052 | err_nomem: | 1041 | err_nomem: |
| 1053 | rpc_destroy_mempool(); | 1042 | rpc_destroy_mempool(); |
