From ac8ab48298dbd455e25c1b9b9db1393844e9972e Mon Sep 17 00:00:00 2001 From: Sven Wegener Date: Fri, 19 Sep 2008 17:38:06 +0000 Subject: ipvs: Mark destinations with lots of backlog connections as overloaded Add two sysctl variables that allow to set upper and lower thresholds on backlog connections. These thresholds get used to mark destinations as overloaded. If we hit the upper threshold we mark the destination as overloaded and when it decreases below the lower threshold we unmark it. Signed-off-by: Sven Wegener --- include/net/ip_vs.h | 2 ++ net/netfilter/ipvs/ip_vs_conn.c | 14 ++++++++++++-- net/netfilter/ipvs/ip_vs_ctl.c | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 119637e137ed..10e7a7da3a0e 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -789,6 +789,8 @@ extern int sysctl_ip_vs_expire_nodest_conn; extern int sysctl_ip_vs_expire_quiescent_template; extern int sysctl_ip_vs_sync_threshold[2]; extern int sysctl_ip_vs_nat_icmp_send; +extern int sysctl_ip_vs_max_backlog_u; +extern int sysctl_ip_vs_max_backlog_l; extern struct ip_vs_stats ip_vs_stats; extern const struct ctl_path net_vs_ctl_path[]; diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index f1bf02ab4d94..e068e9cc6616 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -498,7 +498,12 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) atomic_inc(&dest->persistconns); } - if (dest->u_threshold != 0 && + if (dest->svc->protocol == IPPROTO_TCP && sysctl_ip_vs_max_backlog_u && + sysctl_ip_vs_max_backlog_l && + atomic_read(&dest->backlogconns) > + sysctl_ip_vs_max_backlog_u) + dest->flags |= IP_VS_DEST_F_OVERLOAD; + else if (dest->u_threshold != 0 && ip_vs_dest_totalconns(dest) >= dest->u_threshold) dest->flags |= IP_VS_DEST_F_OVERLOAD; } @@ -563,7 +568,12 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp) atomic_dec(&dest->persistconns); } - if (dest->l_threshold != 0) { + if (dest->svc->protocol == IPPROTO_TCP && sysctl_ip_vs_max_backlog_u && + sysctl_ip_vs_max_backlog_l && + atomic_read(&dest->backlogconns) < + sysctl_ip_vs_max_backlog_l) { + dest->flags &= ~IP_VS_DEST_F_OVERLOAD; + } else if (dest->l_threshold != 0) { if (ip_vs_dest_totalconns(dest) < dest->l_threshold) dest->flags &= ~IP_VS_DEST_F_OVERLOAD; } else if (dest->u_threshold != 0) { diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 7f532d03ce72..c15a422b7cc9 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -88,6 +88,8 @@ int sysctl_ip_vs_expire_nodest_conn = 0; int sysctl_ip_vs_expire_quiescent_template = 0; int sysctl_ip_vs_sync_threshold[2] = { 3, 50 }; int sysctl_ip_vs_nat_icmp_send = 0; +int sysctl_ip_vs_max_backlog_u = 0; +int sysctl_ip_vs_max_backlog_l = 0; #ifdef CONFIG_IP_VS_DEBUG @@ -1708,6 +1710,20 @@ static struct ctl_table vs_vars[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "max_backlog_upper", + .data = &sysctl_ip_vs_max_backlog_u, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .procname = "max_backlog_lower", + .data = &sysctl_ip_vs_max_backlog_l, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { } }; -- cgit v1.2.3