diff options
author | Sven Wegener <sven.wegener@stealer.net> | 2008-08-13 18:47:16 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-08-14 19:26:15 -0400 |
commit | a919cf4b6b499416b6e2247dbc79196c4325f2e6 (patch) | |
tree | 07125d10469cb9d2779280a0f389848b5e045b5a /net/ipv4/ipvs | |
parent | 82dfb6f32219d8e6cf6b979a520cb2b11d977d4e (diff) |
ipvs: Create init functions for estimator code
Commit 8ab19ea36c5c5340ff598e4d15fc084eb65671dc ("ipvs: Fix possible deadlock
in estimator code") fixed a deadlock condition, but that condition can only
happen during unload of IPVS, because during normal operation there is at least
our global stats structure in the estimator list. The mod_timer() and
del_timer_sync() calls are actually initialization and cleanup code in
disguise. Let's make it explicit and move them to their own init and cleanup
function.
Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/ipv4/ipvs')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_core.c | 8 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_est.c | 18 |
2 files changed, 17 insertions, 9 deletions
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index a7879eafc3b5..9fbf0a6d7392 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
@@ -1070,10 +1070,12 @@ static int __init ip_vs_init(void) | |||
1070 | { | 1070 | { |
1071 | int ret; | 1071 | int ret; |
1072 | 1072 | ||
1073 | ip_vs_estimator_init(); | ||
1074 | |||
1073 | ret = ip_vs_control_init(); | 1075 | ret = ip_vs_control_init(); |
1074 | if (ret < 0) { | 1076 | if (ret < 0) { |
1075 | IP_VS_ERR("can't setup control.\n"); | 1077 | IP_VS_ERR("can't setup control.\n"); |
1076 | goto cleanup_nothing; | 1078 | goto cleanup_estimator; |
1077 | } | 1079 | } |
1078 | 1080 | ||
1079 | ip_vs_protocol_init(); | 1081 | ip_vs_protocol_init(); |
@@ -1106,7 +1108,8 @@ static int __init ip_vs_init(void) | |||
1106 | cleanup_protocol: | 1108 | cleanup_protocol: |
1107 | ip_vs_protocol_cleanup(); | 1109 | ip_vs_protocol_cleanup(); |
1108 | ip_vs_control_cleanup(); | 1110 | ip_vs_control_cleanup(); |
1109 | cleanup_nothing: | 1111 | cleanup_estimator: |
1112 | ip_vs_estimator_cleanup(); | ||
1110 | return ret; | 1113 | return ret; |
1111 | } | 1114 | } |
1112 | 1115 | ||
@@ -1117,6 +1120,7 @@ static void __exit ip_vs_cleanup(void) | |||
1117 | ip_vs_app_cleanup(); | 1120 | ip_vs_app_cleanup(); |
1118 | ip_vs_protocol_cleanup(); | 1121 | ip_vs_protocol_cleanup(); |
1119 | ip_vs_control_cleanup(); | 1122 | ip_vs_control_cleanup(); |
1123 | ip_vs_estimator_cleanup(); | ||
1120 | IP_VS_INFO("ipvs unloaded.\n"); | 1124 | IP_VS_INFO("ipvs unloaded.\n"); |
1121 | } | 1125 | } |
1122 | 1126 | ||
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c index 5a20f93bd7f9..4fb620ec2086 100644 --- a/net/ipv4/ipvs/ip_vs_est.c +++ b/net/ipv4/ipvs/ip_vs_est.c | |||
@@ -124,8 +124,6 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats) | |||
124 | est->outbps = stats->outbps<<5; | 124 | est->outbps = stats->outbps<<5; |
125 | 125 | ||
126 | spin_lock_bh(&est_lock); | 126 | spin_lock_bh(&est_lock); |
127 | if (list_empty(&est_list)) | ||
128 | mod_timer(&est_timer, jiffies + 2 * HZ); | ||
129 | list_add(&est->list, &est_list); | 127 | list_add(&est->list, &est_list); |
130 | spin_unlock_bh(&est_lock); | 128 | spin_unlock_bh(&est_lock); |
131 | } | 129 | } |
@@ -136,11 +134,6 @@ void ip_vs_kill_estimator(struct ip_vs_stats *stats) | |||
136 | 134 | ||
137 | spin_lock_bh(&est_lock); | 135 | spin_lock_bh(&est_lock); |
138 | list_del(&est->list); | 136 | list_del(&est->list); |
139 | while (list_empty(&est_list) && try_to_del_timer_sync(&est_timer) < 0) { | ||
140 | spin_unlock_bh(&est_lock); | ||
141 | cpu_relax(); | ||
142 | spin_lock_bh(&est_lock); | ||
143 | } | ||
144 | spin_unlock_bh(&est_lock); | 137 | spin_unlock_bh(&est_lock); |
145 | } | 138 | } |
146 | 139 | ||
@@ -160,3 +153,14 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats) | |||
160 | est->inbps = 0; | 153 | est->inbps = 0; |
161 | est->outbps = 0; | 154 | est->outbps = 0; |
162 | } | 155 | } |
156 | |||
157 | int __init ip_vs_estimator_init(void) | ||
158 | { | ||
159 | mod_timer(&est_timer, jiffies + 2 * HZ); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | void ip_vs_estimator_cleanup(void) | ||
164 | { | ||
165 | del_timer_sync(&est_timer); | ||
166 | } | ||