aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSven Wegener <sven.wegener@stealer.net>2008-08-13 18:47:16 -0400
committerSimon Horman <horms@verge.net.au>2008-08-14 19:26:15 -0400
commita919cf4b6b499416b6e2247dbc79196c4325f2e6 (patch)
tree07125d10469cb9d2779280a0f389848b5e045b5a /net
parent82dfb6f32219d8e6cf6b979a520cb2b11d977d4e (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')
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_est.c18
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
157int __init ip_vs_estimator_init(void)
158{
159 mod_timer(&est_timer, jiffies + 2 * HZ);
160 return 0;
161}
162
163void ip_vs_estimator_cleanup(void)
164{
165 del_timer_sync(&est_timer);
166}