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
|