sctp_v{4,6}_xmit unnecessarily clone the dst from the transport when sending an encapsulated skb. Reduce this overhead by avoiding the refcount increment introduced by cloning the dst. Since t->dst is already assumed to be valid throughout both functions, it's safe to use the dst without incrementing the refcount. Signed-off-by: Marek Mietus --- net/sctp/ipv6.c | 6 +++--- net/sctp/protocol.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 53a6d3adf452..7b1dbd9aa565 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -219,7 +219,7 @@ int sctp_udp_v6_err(struct sock *sk, struct sk_buff *skb) static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) { - struct dst_entry *dst = dst_clone(t->dst); + struct dst_entry *dst = t->dst; struct flowi6 *fl6 = &t->fl.u.ip6; struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); @@ -243,7 +243,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) if (!t->encap_port || !sctp_sk(sk)->udp_port) { int res; - skb_dst_set(skb, dst); + skb_dst_set(skb, dst_clone(dst)); rcu_read_lock(); res = ip6_xmit(sk, skb, fl6, sk->sk_mark, rcu_dereference(np->opt), @@ -261,7 +261,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) skb_set_inner_ipproto(skb, IPPROTO_SCTP); label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6); - udp_tunnel6_xmit_skb(dst_to_dstref(dst), sk, skb, NULL, &fl6->saddr, &fl6->daddr, + udp_tunnel6_xmit_skb(dst_to_dstref_noref(dst), sk, skb, NULL, &fl6->saddr, &fl6->daddr, tclass, ip6_dst_hoplimit(dst), label, sctp_sk(sk)->udp_port, t->encap_port, false, 0); return 0; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 77c16318f62e..04990727c1b0 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1070,7 +1070,7 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt, /* Wrapper routine that calls the ip transmit routine. */ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t) { - struct dst_entry *dst = dst_clone(t->dst); + struct dst_entry *dst = t->dst; struct flowi4 *fl4 = &t->fl.u.ip4; struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); @@ -1088,7 +1088,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t) SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); if (!t->encap_port || !sctp_sk(sk)->udp_port) { - skb_dst_set(skb, dst); + skb_dst_set(skb, dst_clone(dst)); return __ip_queue_xmit(sk, skb, &t->fl, dscp); } @@ -1102,7 +1102,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t) skb_reset_inner_mac_header(skb); skb_reset_inner_transport_header(skb); skb_set_inner_ipproto(skb, IPPROTO_SCTP); - udp_tunnel_xmit_skb(dst_to_dstref(dst), sk, skb, fl4->saddr, + udp_tunnel_xmit_skb(dst_to_dstref_noref(dst), sk, skb, fl4->saddr, fl4->daddr, dscp, ip4_dst_hoplimit(dst), df, sctp_sk(sk)->udp_port, t->encap_port, false, false, 0); -- 2.51.0