diff mbox series

[net-next,2/4] gro: add combined call_gro_receive() + INDIRECT_CALL_INET() helper

Message ID 20210318184157.700604-3-alobakin@pm.me (mailing list archive)
State Accepted
Delegated to: Netdev Maintainers
Headers show
Series net: avoid retpoline overhead on VLAN and TEB GRO | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers success CCed 3 of 3 maintainers
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 10 this patch: 10
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 12 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 10 this patch: 10
netdev/header_inline success Link

Commit Message

Alexander Lobakin March 18, 2021, 6:42 p.m. UTC
call_gro_receive() is used to limit GRO recursion, but it works only
with callback pointers.
There's a combined version of call_gro_receive() + INDIRECT_CALL_2()
in <net/inet_common.h>, but it doesn't check for IPv6 modularity.
Add a similar new helper to cover both of these. It can and will be
used to avoid retpoline overhead when IP header lies behind another
offloaded proto.

Signed-off-by: Alexander Lobakin <alobakin@pm.me>
---
 include/net/gro.h | 8 ++++++++
 1 file changed, 8 insertions(+)

--
2.31.0

Comments

Paolo Abeni March 19, 2021, 10:53 a.m. UTC | #1
Hello,

On Thu, 2021-03-18 at 18:42 +0000, Alexander Lobakin wrote:
> call_gro_receive() is used to limit GRO recursion, but it works only
> with callback pointers.
> There's a combined version of call_gro_receive() + INDIRECT_CALL_2()
> in <net/inet_common.h>, but it doesn't check for IPv6 modularity.

AFAICS, ip6_offload is builtin even when IPv6 is a module, so the above
should not be needed.

Cheers,

Paolo
Alexander Lobakin March 19, 2021, 11:13 a.m. UTC | #2
From: Paolo Abeni <pabeni@redhat.com>
Date: Fri, 19 Mar 2021 11:53:42 +0100

> Hello,

Hi!

> On Thu, 2021-03-18 at 18:42 +0000, Alexander Lobakin wrote:
> > call_gro_receive() is used to limit GRO recursion, but it works only
> > with callback pointers.
> > There's a combined version of call_gro_receive() + INDIRECT_CALL_2()
> > in <net/inet_common.h>, but it doesn't check for IPv6 modularity.
>
> AFAICS, ip6_offload is builtin even when IPv6 is a module, so the above
> should not be needed.

Aww, you are right. I overlooked that since dev_gro_receive() still
use INDIRECT_CALL_INET(), though all GRO callbacks were made
built-in.

Seems like more code can be optimized, thanks!

> Cheers,
>
> Paolo

Al
Alexander Lobakin March 19, 2021, 11:43 a.m. UTC | #3
From: Alexander Lobakin <alobakin@pm.me>
Date: Fri, 19 Mar 2021 11:13:25 +0000

> From: Paolo Abeni <pabeni@redhat.com>
> Date: Fri, 19 Mar 2021 11:53:42 +0100
>
> > Hello,
>
> Hi!
>
> > On Thu, 2021-03-18 at 18:42 +0000, Alexander Lobakin wrote:
> > > call_gro_receive() is used to limit GRO recursion, but it works only
> > > with callback pointers.
> > > There's a combined version of call_gro_receive() + INDIRECT_CALL_2()
> > > in <net/inet_common.h>, but it doesn't check for IPv6 modularity.
> >
> > AFAICS, ip6_offload is builtin even when IPv6 is a module, so the above
> > should not be needed.
>
> Aww, you are right. I overlooked that since dev_gro_receive() still
> use INDIRECT_CALL_INET(), though all GRO callbacks were made
> built-in.

I'm not sure if you did it on purpose in commit aaa5d90b395a7
("net: use indirect call wrappers at GRO network layer").
Was that intentional for the sake of more optimized path for the
kernels with moduled IPv6, or I can replace INDIRECT_CALL_INET()
with INDIRECT_CALL_2() here too? I want to keep GRO callbacks that
make use of indirect call wrappers unified.

> Seems like more code can be optimized, thanks!
>
> > Cheers,
> >
> > Paolo
>
> Al

Thanks,
Al
Paolo Abeni March 19, 2021, 12:35 p.m. UTC | #4
On Fri, 2021-03-19 at 11:43 +0000, Alexander Lobakin wrote:
> I'm not sure if you did it on purpose in commit aaa5d90b395a7
> ("net: use indirect call wrappers at GRO network layer").
> Was that intentional 

I must admit that 2y+ later my own intentions are not so clear to me
too;)

> for the sake of more optimized path for the
> kernels with moduled IPv6, 

Uhm... no I guess that was more an underlook on my side.

> or I can replace INDIRECT_CALL_INET()
> with INDIRECT_CALL_2() here too? 

If that build with IPV6=nmy, I would say yes.

> I want to keep GRO callbacks that
> make use of indirect call wrappers unified.

L4 will still need some special handling as ipv6 udp gro callbacks are
not builtin with CONFIG_IPV6=m :(

Cheers,

Paolo
Alexander Lobakin March 19, 2021, 12:49 p.m. UTC | #5
From: Paolo Abeni <pabeni@redhat.com>
Date: Fri, 19 Mar 2021 13:35:41 +0100

> On Fri, 2021-03-19 at 11:43 +0000, Alexander Lobakin wrote:
> > I'm not sure if you did it on purpose in commit aaa5d90b395a7
> > ("net: use indirect call wrappers at GRO network layer").
> > Was that intentional
>
> I must admit that 2y+ later my own intentions are not so clear to me
> too;)

Heh, know that feel (=

> > for the sake of more optimized path for the
> > kernels with moduled IPv6,
>
> Uhm... no I guess that was more an underlook on my side.
>
> > or I can replace INDIRECT_CALL_INET()
> > with INDIRECT_CALL_2() here too?
>
> If that build with IPV6=nmy, I would say yes.

I think you used INDIRECT_CALL_INET() to protect from CONFIG_INET=n.
But this also hurts with retpoline when CONFIG_IPV6=m. Not so common
case, but still.

Plain INDIRECT_CALL_2() won't build without CONFIG_INET, so we either
introduce a new one (e.g. _INET_2() similarly to _INET_1()), or leave
it as it is for now (Dave's already picked this series to net-next).

> > I want to keep GRO callbacks that
> > make use of indirect call wrappers unified.
>
> L4 will still need some special handling as ipv6 udp gro callbacks are
> not builtin with CONFIG_IPV6=m :(

Yep, I remember. I meant {inet,ipv6}_gro_{complete,receive}()
callers, but didn't mention that for some reason.

> Cheers,
>
> Paolo

Thanks,
Al
diff mbox series

Patch

diff --git a/include/net/gro.h b/include/net/gro.h
index 27c38b36df16..01edaf3fdda0 100644
--- a/include/net/gro.h
+++ b/include/net/gro.h
@@ -14,4 +14,12 @@  INDIRECT_CALLABLE_DECLARE(int ipv6_gro_complete(struct sk_buff *, int));
 INDIRECT_CALLABLE_DECLARE(struct sk_buff *inet_gro_receive(struct list_head *,
 							   struct sk_buff *));
 INDIRECT_CALLABLE_DECLARE(int inet_gro_complete(struct sk_buff *, int));
+
+#define indirect_call_gro_receive_inet(cb, f2, f1, head, skb)	\
+({								\
+	unlikely(gro_recursion_inc_test(skb)) ?			\
+		NAPI_GRO_CB(skb)->flush |= 1, NULL :		\
+		INDIRECT_CALL_INET(cb, f2, f1, head, skb);	\
+})
+
 #endif /* _NET_IPV6_GRO_H */