Commit a919cf4b authored by Sven Wegener's avatar Sven Wegener Committed by Simon Horman

ipvs: Create init functions for estimator code

Commit 8ab19ea3 ("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: default avatarSven Wegener <sven.wegener@stealer.net>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 82dfb6f3
...@@ -683,6 +683,8 @@ extern void ip_vs_sync_conn(struct ip_vs_conn *cp); ...@@ -683,6 +683,8 @@ extern void ip_vs_sync_conn(struct ip_vs_conn *cp);
/* /*
* IPVS rate estimator prototypes (from ip_vs_est.c) * IPVS rate estimator prototypes (from ip_vs_est.c)
*/ */
extern int ip_vs_estimator_init(void);
extern void ip_vs_estimator_cleanup(void);
extern void ip_vs_new_estimator(struct ip_vs_stats *stats); extern void ip_vs_new_estimator(struct ip_vs_stats *stats);
extern void ip_vs_kill_estimator(struct ip_vs_stats *stats); extern void ip_vs_kill_estimator(struct ip_vs_stats *stats);
extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); extern void ip_vs_zero_estimator(struct ip_vs_stats *stats);
......
...@@ -1070,10 +1070,12 @@ static int __init ip_vs_init(void) ...@@ -1070,10 +1070,12 @@ static int __init ip_vs_init(void)
{ {
int ret; int ret;
ip_vs_estimator_init();
ret = ip_vs_control_init(); ret = ip_vs_control_init();
if (ret < 0) { if (ret < 0) {
IP_VS_ERR("can't setup control.\n"); IP_VS_ERR("can't setup control.\n");
goto cleanup_nothing; goto cleanup_estimator;
} }
ip_vs_protocol_init(); ip_vs_protocol_init();
...@@ -1106,7 +1108,8 @@ static int __init ip_vs_init(void) ...@@ -1106,7 +1108,8 @@ static int __init ip_vs_init(void)
cleanup_protocol: cleanup_protocol:
ip_vs_protocol_cleanup(); ip_vs_protocol_cleanup();
ip_vs_control_cleanup(); ip_vs_control_cleanup();
cleanup_nothing: cleanup_estimator:
ip_vs_estimator_cleanup();
return ret; return ret;
} }
...@@ -1117,6 +1120,7 @@ static void __exit ip_vs_cleanup(void) ...@@ -1117,6 +1120,7 @@ static void __exit ip_vs_cleanup(void)
ip_vs_app_cleanup(); ip_vs_app_cleanup();
ip_vs_protocol_cleanup(); ip_vs_protocol_cleanup();
ip_vs_control_cleanup(); ip_vs_control_cleanup();
ip_vs_estimator_cleanup();
IP_VS_INFO("ipvs unloaded.\n"); IP_VS_INFO("ipvs unloaded.\n");
} }
......
...@@ -124,8 +124,6 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats) ...@@ -124,8 +124,6 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats)
est->outbps = stats->outbps<<5; est->outbps = stats->outbps<<5;
spin_lock_bh(&est_lock); spin_lock_bh(&est_lock);
if (list_empty(&est_list))
mod_timer(&est_timer, jiffies + 2 * HZ);
list_add(&est->list, &est_list); list_add(&est->list, &est_list);
spin_unlock_bh(&est_lock); spin_unlock_bh(&est_lock);
} }
...@@ -136,11 +134,6 @@ void ip_vs_kill_estimator(struct ip_vs_stats *stats) ...@@ -136,11 +134,6 @@ void ip_vs_kill_estimator(struct ip_vs_stats *stats)
spin_lock_bh(&est_lock); spin_lock_bh(&est_lock);
list_del(&est->list); list_del(&est->list);
while (list_empty(&est_list) && try_to_del_timer_sync(&est_timer) < 0) {
spin_unlock_bh(&est_lock);
cpu_relax();
spin_lock_bh(&est_lock);
}
spin_unlock_bh(&est_lock); spin_unlock_bh(&est_lock);
} }
...@@ -160,3 +153,14 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats) ...@@ -160,3 +153,14 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats)
est->inbps = 0; est->inbps = 0;
est->outbps = 0; est->outbps = 0;
} }
int __init ip_vs_estimator_init(void)
{
mod_timer(&est_timer, jiffies + 2 * HZ);
return 0;
}
void ip_vs_estimator_cleanup(void)
{
del_timer_sync(&est_timer);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment