netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] tipc: add dst_cache support for udp media
@ 2019-06-20 11:03 Xin Long
  2019-06-20 12:53 ` Jon Maloy
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Xin Long @ 2019-06-20 11:03 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jon Maloy, Ying Xue, tipc-discussion, Paolo Abeni

As other udp/ip tunnels do, tipc udp media should also have a
lockless dst_cache supported on its tx path.

Here we add dst_cache into udp_replicast to support dst cache
for both rmcast and rcast, and rmcast uses ub->rcast and each
rcast uses its own node in ub->rcast.list.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/tipc/udp_media.c | 72 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 25 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 1405ccc..b8962df 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -76,6 +76,7 @@ struct udp_media_addr {
 /* struct udp_replicast - container for UDP remote addresses */
 struct udp_replicast {
 	struct udp_media_addr addr;
+	struct dst_cache dst_cache;
 	struct rcu_head rcu;
 	struct list_head list;
 };
@@ -158,22 +159,27 @@ static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
 /* tipc_send_msg - enqueue a send request */
 static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
 			 struct udp_bearer *ub, struct udp_media_addr *src,
-			 struct udp_media_addr *dst)
+			 struct udp_media_addr *dst, struct dst_cache *cache)
 {
+	struct dst_entry *ndst = dst_cache_get(cache);
 	int ttl, err = 0;
-	struct rtable *rt;
 
 	if (dst->proto == htons(ETH_P_IP)) {
-		struct flowi4 fl = {
-			.daddr = dst->ipv4.s_addr,
-			.saddr = src->ipv4.s_addr,
-			.flowi4_mark = skb->mark,
-			.flowi4_proto = IPPROTO_UDP
-		};
-		rt = ip_route_output_key(net, &fl);
-		if (IS_ERR(rt)) {
-			err = PTR_ERR(rt);
-			goto tx_error;
+		struct rtable *rt = (struct rtable *)ndst;
+
+		if (!rt) {
+			struct flowi4 fl = {
+				.daddr = dst->ipv4.s_addr,
+				.saddr = src->ipv4.s_addr,
+				.flowi4_mark = skb->mark,
+				.flowi4_proto = IPPROTO_UDP
+			};
+			rt = ip_route_output_key(net, &fl);
+			if (IS_ERR(rt)) {
+				err = PTR_ERR(rt);
+				goto tx_error;
+			}
+			dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
 		}
 
 		ttl = ip4_dst_hoplimit(&rt->dst);
@@ -182,17 +188,19 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
 				    dst->port, false, true);
 #if IS_ENABLED(CONFIG_IPV6)
 	} else {
-		struct dst_entry *ndst;
-		struct flowi6 fl6 = {
-			.flowi6_oif = ub->ifindex,
-			.daddr = dst->ipv6,
-			.saddr = src->ipv6,
-			.flowi6_proto = IPPROTO_UDP
-		};
-		err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk, &ndst,
-						 &fl6);
-		if (err)
-			goto tx_error;
+		if (!ndst) {
+			struct flowi6 fl6 = {
+				.flowi6_oif = ub->ifindex,
+				.daddr = dst->ipv6,
+				.saddr = src->ipv6,
+				.flowi6_proto = IPPROTO_UDP
+			};
+			err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk,
+							 &ndst, &fl6);
+			if (err)
+				goto tx_error;
+			dst_cache_set_ip6(cache, ndst, &fl6.saddr);
+		}
 		ttl = ip6_dst_hoplimit(ndst);
 		err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
 					   &src->ipv6, &dst->ipv6, 0, ttl, 0,
@@ -230,7 +238,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
 	}
 
 	if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
-		return tipc_udp_xmit(net, skb, ub, src, dst);
+		return tipc_udp_xmit(net, skb, ub, src, dst,
+				     &ub->rcast.dst_cache);
 
 	/* Replicast, send an skb to each configured IP address */
 	list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
@@ -242,7 +251,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
 			goto out;
 		}
 
-		err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr);
+		err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
+				    &rcast->dst_cache);
 		if (err)
 			goto out;
 	}
@@ -286,6 +296,11 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
 	if (!rcast)
 		return -ENOMEM;
 
+	if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
+		kfree(rcast);
+		return -ENOMEM;
+	}
+
 	memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
 
 	if (ntohs(addr->proto) == ETH_P_IP)
@@ -742,6 +757,10 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
 	tuncfg.encap_destroy = NULL;
 	setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
 
+	err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
+	if (err)
+		goto err;
+
 	/**
 	 * The bcast media address port is used for all peers and the ip
 	 * is used if it's a multicast address.
@@ -756,6 +775,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
 
 	return 0;
 err:
+	dst_cache_destroy(&ub->rcast.dst_cache);
 	if (ub->ubsock)
 		udp_tunnel_sock_release(ub->ubsock);
 	kfree(ub);
@@ -769,10 +789,12 @@ static void cleanup_bearer(struct work_struct *work)
 	struct udp_replicast *rcast, *tmp;
 
 	list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
+		dst_cache_destroy(&rcast->dst_cache);
 		list_del_rcu(&rcast->list);
 		kfree_rcu(rcast, rcu);
 	}
 
+	dst_cache_destroy(&ub->rcast.dst_cache);
 	if (ub->ubsock)
 		udp_tunnel_sock_release(ub->ubsock);
 	synchronize_net();
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [PATCH net] tipc: add dst_cache support for udp media
  2019-06-20 11:03 [PATCH net] tipc: add dst_cache support for udp media Xin Long
@ 2019-06-20 12:53 ` Jon Maloy
  2019-06-22 23:54 ` David Miller
  2019-06-28  5:37 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Jon Maloy @ 2019-06-20 12:53 UTC (permalink / raw)
  To: Xin Long, network dev; +Cc: davem, Ying Xue, tipc-discussion, Paolo Abeni

Acked-by: Jon Maloy <jon.maloy@ericsson.com>

> -----Original Message-----
> From: netdev-owner@vger.kernel.org <netdev-owner@vger.kernel.org> On
> Behalf Of Xin Long
> Sent: 20-Jun-19 07:04
> To: network dev <netdev@vger.kernel.org>
> Cc: davem@davemloft.net; Jon Maloy <jon.maloy@ericsson.com>; Ying Xue
> <ying.xue@windriver.com>; tipc-discussion@lists.sourceforge.net; Paolo
> Abeni <pabeni@redhat.com>
> Subject: [PATCH net] tipc: add dst_cache support for udp media
> 
> As other udp/ip tunnels do, tipc udp media should also have a lockless
> dst_cache supported on its tx path.
> 
> Here we add dst_cache into udp_replicast to support dst cache for both
> rmcast and rcast, and rmcast uses ub->rcast and each rcast uses its own node
> in ub->rcast.list.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/tipc/udp_media.c | 72 ++++++++++++++++++++++++++++++++++-------
> -----------
>  1 file changed, 47 insertions(+), 25 deletions(-)
> 
> diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index
> 1405ccc..b8962df 100644
> --- a/net/tipc/udp_media.c
> +++ b/net/tipc/udp_media.c
> @@ -76,6 +76,7 @@ struct udp_media_addr {
>  /* struct udp_replicast - container for UDP remote addresses */  struct
> udp_replicast {
>  	struct udp_media_addr addr;
> +	struct dst_cache dst_cache;
>  	struct rcu_head rcu;
>  	struct list_head list;
>  };
> @@ -158,22 +159,27 @@ static int tipc_udp_addr2msg(char *msg, struct
> tipc_media_addr *a)
>  /* tipc_send_msg - enqueue a send request */  static int tipc_udp_xmit(struct
> net *net, struct sk_buff *skb,
>  			 struct udp_bearer *ub, struct udp_media_addr *src,
> -			 struct udp_media_addr *dst)
> +			 struct udp_media_addr *dst, struct dst_cache *cache)
>  {
> +	struct dst_entry *ndst = dst_cache_get(cache);
>  	int ttl, err = 0;
> -	struct rtable *rt;
> 
>  	if (dst->proto == htons(ETH_P_IP)) {
> -		struct flowi4 fl = {
> -			.daddr = dst->ipv4.s_addr,
> -			.saddr = src->ipv4.s_addr,
> -			.flowi4_mark = skb->mark,
> -			.flowi4_proto = IPPROTO_UDP
> -		};
> -		rt = ip_route_output_key(net, &fl);
> -		if (IS_ERR(rt)) {
> -			err = PTR_ERR(rt);
> -			goto tx_error;
> +		struct rtable *rt = (struct rtable *)ndst;
> +
> +		if (!rt) {
> +			struct flowi4 fl = {
> +				.daddr = dst->ipv4.s_addr,
> +				.saddr = src->ipv4.s_addr,
> +				.flowi4_mark = skb->mark,
> +				.flowi4_proto = IPPROTO_UDP
> +			};
> +			rt = ip_route_output_key(net, &fl);
> +			if (IS_ERR(rt)) {
> +				err = PTR_ERR(rt);
> +				goto tx_error;
> +			}
> +			dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
>  		}
> 
>  		ttl = ip4_dst_hoplimit(&rt->dst);
> @@ -182,17 +188,19 @@ static int tipc_udp_xmit(struct net *net, struct
> sk_buff *skb,
>  				    dst->port, false, true);
>  #if IS_ENABLED(CONFIG_IPV6)
>  	} else {
> -		struct dst_entry *ndst;
> -		struct flowi6 fl6 = {
> -			.flowi6_oif = ub->ifindex,
> -			.daddr = dst->ipv6,
> -			.saddr = src->ipv6,
> -			.flowi6_proto = IPPROTO_UDP
> -		};
> -		err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk, &ndst,
> -						 &fl6);
> -		if (err)
> -			goto tx_error;
> +		if (!ndst) {
> +			struct flowi6 fl6 = {
> +				.flowi6_oif = ub->ifindex,
> +				.daddr = dst->ipv6,
> +				.saddr = src->ipv6,
> +				.flowi6_proto = IPPROTO_UDP
> +			};
> +			err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk,
> +							 &ndst, &fl6);
> +			if (err)
> +				goto tx_error;
> +			dst_cache_set_ip6(cache, ndst, &fl6.saddr);
> +		}
>  		ttl = ip6_dst_hoplimit(ndst);
>  		err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
>  					   &src->ipv6, &dst->ipv6, 0, ttl, 0, @@ -230,7
> +238,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
>  	}
> 
>  	if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
> -		return tipc_udp_xmit(net, skb, ub, src, dst);
> +		return tipc_udp_xmit(net, skb, ub, src, dst,
> +				     &ub->rcast.dst_cache);
> 
>  	/* Replicast, send an skb to each configured IP address */
>  	list_for_each_entry_rcu(rcast, &ub->rcast.list, list) { @@ -242,7 +251,8
> @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
>  			goto out;
>  		}
> 
> -		err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr);
> +		err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
> +				    &rcast->dst_cache);
>  		if (err)
>  			goto out;
>  	}
> @@ -286,6 +296,11 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
>  	if (!rcast)
>  		return -ENOMEM;
> 
> +	if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
> +		kfree(rcast);
> +		return -ENOMEM;
> +	}
> +
>  	memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
> 
>  	if (ntohs(addr->proto) == ETH_P_IP)
> @@ -742,6 +757,10 @@ static int tipc_udp_enable(struct net *net, struct
> tipc_bearer *b,
>  	tuncfg.encap_destroy = NULL;
>  	setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
> 
> +	err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
> +	if (err)
> +		goto err;
> +
>  	/**
>  	 * The bcast media address port is used for all peers and the ip
>  	 * is used if it's a multicast address.
> @@ -756,6 +775,7 @@ static int tipc_udp_enable(struct net *net, struct
> tipc_bearer *b,
> 
>  	return 0;
>  err:
> +	dst_cache_destroy(&ub->rcast.dst_cache);
>  	if (ub->ubsock)
>  		udp_tunnel_sock_release(ub->ubsock);
>  	kfree(ub);
> @@ -769,10 +789,12 @@ static void cleanup_bearer(struct work_struct
> *work)
>  	struct udp_replicast *rcast, *tmp;
> 
>  	list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
> +		dst_cache_destroy(&rcast->dst_cache);
>  		list_del_rcu(&rcast->list);
>  		kfree_rcu(rcast, rcu);
>  	}
> 
> +	dst_cache_destroy(&ub->rcast.dst_cache);
>  	if (ub->ubsock)
>  		udp_tunnel_sock_release(ub->ubsock);
>  	synchronize_net();
> --
> 2.1.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] tipc: add dst_cache support for udp media
  2019-06-20 11:03 [PATCH net] tipc: add dst_cache support for udp media Xin Long
  2019-06-20 12:53 ` Jon Maloy
@ 2019-06-22 23:54 ` David Miller
  2019-06-28  5:37 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2019-06-22 23:54 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, jon.maloy, ying.xue, tipc-discussion, pabeni

From: Xin Long <lucien.xin@gmail.com>
Date: Thu, 20 Jun 2019 19:03:41 +0800

> As other udp/ip tunnels do, tipc udp media should also have a
> lockless dst_cache supported on its tx path.
> 
> Here we add dst_cache into udp_replicast to support dst cache
> for both rmcast and rcast, and rmcast uses ub->rcast and each
> rcast uses its own node in ub->rcast.list.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

I'll apply this to net-next after the next net --> net-next
marge since it depends upon the register_pernet_device change.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] tipc: add dst_cache support for udp media
  2019-06-20 11:03 [PATCH net] tipc: add dst_cache support for udp media Xin Long
  2019-06-20 12:53 ` Jon Maloy
  2019-06-22 23:54 ` David Miller
@ 2019-06-28  5:37 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2019-06-28  5:37 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, jon.maloy, ying.xue, tipc-discussion, pabeni

From: Xin Long <lucien.xin@gmail.com>
Date: Thu, 20 Jun 2019 19:03:41 +0800

> As other udp/ip tunnels do, tipc udp media should also have a
> lockless dst_cache supported on its tx path.
> 
> Here we add dst_cache into udp_replicast to support dst cache
> for both rmcast and rcast, and rmcast uses ub->rcast and each
> rcast uses its own node in ub->rcast.list.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Applied to net-next.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-06-28  5:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-20 11:03 [PATCH net] tipc: add dst_cache support for udp media Xin Long
2019-06-20 12:53 ` Jon Maloy
2019-06-22 23:54 ` David Miller
2019-06-28  5:37 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).