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
State New
Headers show
Series net: avoid retpoline overhead on VLAN and TEB GRO | expand

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 */