ipv6: refactor opts push in __ip6_make_skb()
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 8/10 ipv6: refactor opts push in __ip6_make_skb()
Don't preload v6_cork->opt before we actually need it, it likely to be saved on the stack and read again for no good reason.
--- net/ipv6/ip6_output.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
net/ipv6/ip6_output.c +8 -5
@@ -1855,7 +1855,6 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,struct ipv6_pinfo *np =inet6_sk (sk);struct net *net =sock_net (sk);struct ipv6hdr *hdr; -struct ipv6_txoptions *opt = v6_cork->opt;struct rt6_info *rt = (struct rt6_info *)cork->base.dst;struct flowi6 *fl6 = &cork->fl.u.ip6;unsigned char proto = fl6->flowi6_proto;
@@ -1884,10 +1883,14 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,__skb_pull (skb,skb_network_header_len (skb)); final_dst = &fl6->daddr; -if (opt && opt->opt_flen) -ipv6_push_frag_opts (skb, opt, &proto); -if (opt && opt->opt_nflen) -ipv6_push_nfrag_opts (skb, opt, &proto, &final_dst, &fl6->saddr); +if (v6_cork->opt) { +struct ipv6_txoptions *opt = v6_cork->opt; + +if (opt->opt_flen) +ipv6_push_frag_opts (skb, opt, &proto); +if (opt->opt_nflen) +ipv6_push_nfrag_opts (skb, opt, &proto, &final_dst, &fl6->saddr); + }skb_push (skb,sizeof (struct ipv6hdr ));skb_reset_network_header (skb);
Signature · 1 line
2.36.0
Paolo Abeni
maintainerQuoted 4 lines · Pavel Begunkov
Don't preload
v6_cork->optbefore we actually need it, it likely to be saved on the stack and read again for no good reason.Signed-off-by Pavel Begunkov <[email protected]>
It looks like most part of this series has been lost ?!? only 8/10, 9/10 and 10/10 landed on the ML. Could you please double check?
Thanks
Paolo
Quoted 8 lines · Paolo Abeni
Quoted 4 lines · Pavel Begunkov
Don't preload
v6_cork->optbefore we actually need it, it likely to be saved on the stack and read again for no good reason.Signed-off-by Pavel Begunkov <[email protected]>It looks like most part of this series has been lost ?!? only 8/10, 9/10 and 10/10 landed on the ML. Could you please double check?
Seems I somehow sent duplicates of those and with weird numbering, sorry for that. Let me resend the set, will tag v2 for convenience.
Signature · 1 line
Pavel Begunkov
PATCH 9/10 ipv6: improve opt-less __ip6_make_skb()
In reply to a message not in the archiveWe do a bit of a network header pointer shuffling in __ip6_make_skb() expecting that ipv6_push_*frag_opts() might change the layout. Avoid it with associated overhead when there are no opts.
--- net/ipv6/ip6_output.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/ipv6/ip6_output.c +3 -5
@@ -1880,22 +1880,20 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,/* Allow local fragmentation. */ skb->ignore_df =ip6_sk_ignore_df (sk); -__skb_pull (skb,skb_network_header_len (skb)); - final_dst = &fl6->daddr;if (v6_cork->opt) {struct ipv6_txoptions *opt = v6_cork->opt; +__skb_pull (skb,skb_network_header_len (skb));if (opt->opt_flen)ipv6_push_frag_opts (skb, opt, &proto);if (opt->opt_nflen)ipv6_push_nfrag_opts (skb, opt, &proto, &final_dst, &fl6->saddr); +skb_push (skb,sizeof (struct ipv6hdr )); +skb_reset_network_header (skb); } -skb_push (skb,sizeof (struct ipv6hdr )); -skb_reset_network_header (skb); hdr =ipv6_hdr (skb); -ip6_flow_hdr (hdr, v6_cork->tclass,ip6_make_flowlabel (net, skb, fl6->flowlabel,ip6_autoflowlabel (net, np), fl6));
Signature · 1 line
2.36.0
PATCH 10/10 ipv6: clean up ip6_setup_cork
In reply to a message not in the archiveDo a bit of refactoring for ip6_setup_cork(). Cache a xfrm_dst_path() result to not call it twice, reshuffle ifs to not repeat some parts twice and so.
--- net/ipv6/ip6_output.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
net/ipv6/ip6_output.c +13 -17
@@ -1358,15 +1358,13 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,struct ipv6_pinfo *np =inet6_sk (sk);unsigned int mtu;struct ipv6_txoptions *nopt, *opt = ipc6->opt; +struct dst_entry *xrfm_dst;/* callers pass dst together with a reference, set it first so * ip6_cork_release() can put it down even in case of an error. */ cork->base.dst = &rt->dst; -/* -* setup for corking -*/ if (opt) {if (WARN_ON (v6_cork->opt))return -EINVAL ;
@@ -1399,28 +1397,26 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, } v6_cork->hop_limit = ipc6->hlimit; v6_cork->tclass = ipc6->tclass; -if (rt->dst.flags &DST_XFRM_TUNNEL ) - mtu = np->pmtudisc >=IPV6_PMTUDISC_PROBE ? -READ_ONCE (rt->dst.dev->mtu) :dst_mtu (&rt->dst); + + xrfm_dst =xfrm_dst_path (&rt->dst); +if (dst_allfrag (xrfm_dst)) + cork->base.flags |=IPCORK_ALLFRAG ; + +if (np->pmtudisc <IPV6_PMTUDISC_PROBE ) + mtu =dst_mtu (rt->dst.flags &DST_XFRM_TUNNEL ? &rt->dst : xrfm_dst);else - mtu = np->pmtudisc >=IPV6_PMTUDISC_PROBE ? -READ_ONCE (rt->dst.dev->mtu) :dst_mtu (xfrm_dst_path (&rt->dst)); -if (np->frag_size < mtu) { -if (np->frag_size) - mtu = np->frag_size; - } + mtu =READ_ONCE (rt->dst.dev->mtu); + +if (np->frag_size < mtu && np->frag_size) + mtu = np->frag_size; + cork->base.fragsize = mtu; cork->base.gso_size = ipc6->gso_size; cork->base.tx_flags =0 ; cork->base.mark = ipc6->sockc.mark;sock_tx_timestamp (sk, ipc6->sockc.tsflags, &cork->base.tx_flags); - -if (dst_allfrag (xfrm_dst_path (&rt->dst))) - cork->base.flags |=IPCORK_ALLFRAG ; cork->base.length =0 ; - cork->base.transmit_time = ipc6->sockc.transmit_time; -return 0 ; }
Signature · 1 line
2.36.0