Re: [PATCH] ipvs: optimize release of connections in OPS mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



	Hello,

On Tue, 5 Apr 2016, Marco Angaroni wrote:

> One-packet-scheduling is the most expensive mode in IPVS from
> performance point of view: for each packet to be processed a new
> connection data structure is created and, after packet is sent,
> deleted by starting a new timer set to expire immediately.
> 
> SIP persistent-engine needs OPS mode to have Call-ID based load
> balancing, so OPS mode performance has negative impact in SIP
> protocol load balancing.
> 
> This patch aims to improve performance of OPS mode by means of the
> following changes in the release mechanism of OPS connections:
> a) call expire callback ip_vs_conn_expire() directly instead of
>    starting a timer programmed to fire immediately.
> b) avoid call_rcu() overhead inside expire callback, since OPS
>    connection are not inserted in the hash-table and last just the
>    time to process the packet, hence there is no concurrent access
>    to such data structures.
> 
> Signed-off-by: Marco Angaroni <marcoangaroni@xxxxxxxxx>

	Looks good to me. Simon, please apply.

Acked-by: Julian Anastasov <ja@xxxxxx>

> ---
>  net/netfilter/ipvs/ip_vs_conn.c | 26 +++++++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> index 85ca189..dd75d41 100644
> --- a/net/netfilter/ipvs/ip_vs_conn.c
> +++ b/net/netfilter/ipvs/ip_vs_conn.c
> @@ -104,6 +104,7 @@ static inline void ct_write_unlock_bh(unsigned int key)
>  	spin_unlock_bh(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l);
>  }
>  
> +static void ip_vs_conn_expire(unsigned long data);
>  
>  /*
>   *	Returns hash value for IPVS connection entry
> @@ -453,10 +454,16 @@ ip_vs_conn_out_get_proto(struct netns_ipvs *ipvs, int af,
>  }
>  EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto);
>  
> +static void __ip_vs_conn_put_notimer(struct ip_vs_conn *cp)
> +{
> +	__ip_vs_conn_put(cp);
> +	ip_vs_conn_expire((unsigned long)cp);
> +}
> +
>  /*
>   *      Put back the conn and restart its timer with its timeout
>   */
> -void ip_vs_conn_put(struct ip_vs_conn *cp)
> +static void __ip_vs_conn_put_timer(struct ip_vs_conn *cp)
>  {
>  	unsigned long t = (cp->flags & IP_VS_CONN_F_ONE_PACKET) ?
>  		0 : cp->timeout;
> @@ -465,6 +472,16 @@ void ip_vs_conn_put(struct ip_vs_conn *cp)
>  	__ip_vs_conn_put(cp);
>  }
>  
> +void ip_vs_conn_put(struct ip_vs_conn *cp)
> +{
> +	if ((cp->flags & IP_VS_CONN_F_ONE_PACKET) &&
> +	    (atomic_read(&cp->refcnt) == 1) &&
> +	    !timer_pending(&cp->timer))
> +		/* expire connection immediately */
> +		__ip_vs_conn_put_notimer(cp);
> +	else
> +		__ip_vs_conn_put_timer(cp);
> +}
>  
>  /*
>   *	Fill a no_client_port connection with a client port number
> @@ -834,7 +851,10 @@ static void ip_vs_conn_expire(unsigned long data)
>  		ip_vs_unbind_dest(cp);
>  		if (cp->flags & IP_VS_CONN_F_NO_CPORT)
>  			atomic_dec(&ip_vs_conn_no_cport_cnt);
> -		call_rcu(&cp->rcu_head, ip_vs_conn_rcu_free);
> +		if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
> +			ip_vs_conn_rcu_free(&cp->rcu_head);
> +		else
> +			call_rcu(&cp->rcu_head, ip_vs_conn_rcu_free);
>  		atomic_dec(&ipvs->conn_count);
>  		return;
>  	}
> @@ -850,7 +870,7 @@ static void ip_vs_conn_expire(unsigned long data)
>  	if (ipvs->sync_state & IP_VS_STATE_MASTER)
>  		ip_vs_sync_conn(ipvs, cp, sysctl_sync_threshold(ipvs));
>  
> -	ip_vs_conn_put(cp);
> +	__ip_vs_conn_put_timer(cp);
>  }
>  
>  /* Modify timer, so that it expires as soon as possible.
> -- 
> 1.8.3.1

Regards

--
Julian Anastasov <ja@xxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Devel]     [Linux NFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [X.Org]

  Powered by Linux