diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-06-14 17:08:36 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:30 -0400 |
commit | ab418d70e1fceda1e2824c45ba3323a1b1413507 (patch) | |
tree | f7ece30a34a089476f84afc4a95be459a5cb06bf /net/sunrpc | |
parent | d431a555fcf920e1b5c3e3eba52eb5f5e7836771 (diff) |
SUNRPC: Optimise rpciod_up()
Instead of taking the mutex every time we just need to increment/decrement
rpciod_users, we can optmise by using atomic_inc_not_zero and
atomic_dec_and_test.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/sched.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index d95fe4e40eb4..f6eed4d4e5dd 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -58,7 +58,7 @@ static DECLARE_WAIT_QUEUE_HEAD(client_kill_wait); | |||
58 | * rpciod-related stuff | 58 | * rpciod-related stuff |
59 | */ | 59 | */ |
60 | static DEFINE_MUTEX(rpciod_mutex); | 60 | static DEFINE_MUTEX(rpciod_mutex); |
61 | static unsigned int rpciod_users; | 61 | static atomic_t rpciod_users = ATOMIC_INIT(0); |
62 | struct workqueue_struct *rpciod_workqueue; | 62 | struct workqueue_struct *rpciod_workqueue; |
63 | 63 | ||
64 | /* | 64 | /* |
@@ -1047,28 +1047,27 @@ rpciod_up(void) | |||
1047 | struct workqueue_struct *wq; | 1047 | struct workqueue_struct *wq; |
1048 | int error = 0; | 1048 | int error = 0; |
1049 | 1049 | ||
1050 | if (atomic_inc_not_zero(&rpciod_users)) | ||
1051 | return 0; | ||
1052 | |||
1050 | mutex_lock(&rpciod_mutex); | 1053 | mutex_lock(&rpciod_mutex); |
1051 | dprintk("RPC: rpciod_up: users %u\n", rpciod_users); | 1054 | |
1052 | rpciod_users++; | 1055 | /* Guard against races with rpciod_down() */ |
1053 | if (rpciod_workqueue) | 1056 | if (rpciod_workqueue != NULL) |
1054 | goto out; | 1057 | goto out_ok; |
1055 | /* | ||
1056 | * If there's no pid, we should be the first user. | ||
1057 | */ | ||
1058 | if (rpciod_users > 1) | ||
1059 | printk(KERN_WARNING "rpciod_up: no workqueue, %u users??\n", rpciod_users); | ||
1060 | /* | 1058 | /* |
1061 | * Create the rpciod thread and wait for it to start. | 1059 | * Create the rpciod thread and wait for it to start. |
1062 | */ | 1060 | */ |
1061 | dprintk("RPC: creating workqueue rpciod\n"); | ||
1063 | error = -ENOMEM; | 1062 | error = -ENOMEM; |
1064 | wq = create_workqueue("rpciod"); | 1063 | wq = create_workqueue("rpciod"); |
1065 | if (wq == NULL) { | 1064 | if (wq == NULL) |
1066 | printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error); | ||
1067 | rpciod_users--; | ||
1068 | goto out; | 1065 | goto out; |
1069 | } | 1066 | |
1070 | rpciod_workqueue = wq; | 1067 | rpciod_workqueue = wq; |
1071 | error = 0; | 1068 | error = 0; |
1069 | out_ok: | ||
1070 | atomic_inc(&rpciod_users); | ||
1072 | out: | 1071 | out: |
1073 | mutex_unlock(&rpciod_mutex); | 1072 | mutex_unlock(&rpciod_mutex); |
1074 | return error; | 1073 | return error; |
@@ -1077,23 +1076,17 @@ out: | |||
1077 | void | 1076 | void |
1078 | rpciod_down(void) | 1077 | rpciod_down(void) |
1079 | { | 1078 | { |
1079 | if (!atomic_dec_and_test(&rpciod_users)) | ||
1080 | return; | ||
1081 | |||
1080 | mutex_lock(&rpciod_mutex); | 1082 | mutex_lock(&rpciod_mutex); |
1081 | dprintk("RPC: rpciod_down sema %u\n", rpciod_users); | 1083 | dprintk("RPC: destroying workqueue rpciod\n"); |
1082 | if (rpciod_users) { | ||
1083 | if (--rpciod_users) | ||
1084 | goto out; | ||
1085 | } else | ||
1086 | printk(KERN_WARNING "rpciod_down: no users??\n"); | ||
1087 | 1084 | ||
1088 | if (!rpciod_workqueue) { | 1085 | if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) { |
1089 | dprintk("RPC: rpciod_down: Nothing to do!\n"); | 1086 | rpciod_killall(); |
1090 | goto out; | 1087 | destroy_workqueue(rpciod_workqueue); |
1088 | rpciod_workqueue = NULL; | ||
1091 | } | 1089 | } |
1092 | rpciod_killall(); | ||
1093 | |||
1094 | destroy_workqueue(rpciod_workqueue); | ||
1095 | rpciod_workqueue = NULL; | ||
1096 | out: | ||
1097 | mutex_unlock(&rpciod_mutex); | 1090 | mutex_unlock(&rpciod_mutex); |
1098 | } | 1091 | } |
1099 | 1092 | ||