diff mbox

net: ipv4: inlining ip_send_check()

Message ID 20150818121439.3E5621A241A@localhost.localdomain
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Christophe Leroy Aug. 18, 2015, 12:14 p.m. UTC
ip_send_check() is a function that does nothing but calling
ip_fast_csum() after having zeroed iph->check

We get (on PPC) a quite long function for just that, as it requires
setting the stack frame, saving volatile regs, restoring them after
the call, etc ...

c02d3e3c <ip_send_check>:
c02d3e3c:       7c 08 02 a6     mflr    r0
c02d3e40:       94 21 ff f0     stwu    r1,-16(r1)
c02d3e44:       39 20 00 00     li      r9,0
c02d3e48:       93 e1 00 0c     stw     r31,12(r1)
c02d3e4c:       90 01 00 14     stw     r0,20(r1)
c02d3e50:       b1 23 00 0a     sth     r9,10(r3)
c02d3e54:       88 83 00 00     lbz     r4,0(r3)
c02d3e58:       7c 7f 1b 78     mr      r31,r3
c02d3e5c:       54 84 07 3e     clrlwi  r4,r4,28
c02d3e60:       4b d3 ab 7d     bl      c000e9dc <ip_fast_csum>
c02d3e64:       b0 7f 00 0a     sth     r3,10(r31)
c02d3e68:       80 01 00 14     lwz     r0,20(r1)
c02d3e6c:       83 e1 00 0c     lwz     r31,12(r1)
c02d3e70:       7c 08 03 a6     mtlr    r0
c02d3e74:       38 21 00 10     addi    r1,r1,16
c02d3e78:       4e 80 00 20     blr

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 include/net/ip.h     | 9 ++++++++-
 net/ipv4/ip_output.c | 8 --------
 2 files changed, 8 insertions(+), 9 deletions(-)

Comments

Eric Dumazet Aug. 18, 2015, 2:46 p.m. UTC | #1
On Tue, 2015-08-18 at 14:14 +0200, Christophe Leroy wrote:
> ip_send_check() is a function that does nothing but calling
> ip_fast_csum() after having zeroed iph->check
> 
> We get (on PPC) a quite long function for just that, as it requires
> setting the stack frame, saving volatile regs, restoring them after
> the call, etc ...
> 
> c02d3e3c <ip_send_check>:
> c02d3e3c:       7c 08 02 a6     mflr    r0
> c02d3e40:       94 21 ff f0     stwu    r1,-16(r1)
> c02d3e44:       39 20 00 00     li      r9,0
> c02d3e48:       93 e1 00 0c     stw     r31,12(r1)
> c02d3e4c:       90 01 00 14     stw     r0,20(r1)
> c02d3e50:       b1 23 00 0a     sth     r9,10(r3)
> c02d3e54:       88 83 00 00     lbz     r4,0(r3)
> c02d3e58:       7c 7f 1b 78     mr      r31,r3
> c02d3e5c:       54 84 07 3e     clrlwi  r4,r4,28
> c02d3e60:       4b d3 ab 7d     bl      c000e9dc <ip_fast_csum>
> c02d3e64:       b0 7f 00 0a     sth     r3,10(r31)
> c02d3e68:       80 01 00 14     lwz     r0,20(r1)
> c02d3e6c:       83 e1 00 0c     lwz     r31,12(r1)
> c02d3e70:       7c 08 03 a6     mtlr    r0
> c02d3e74:       38 21 00 10     addi    r1,r1,16
> c02d3e78:       4e 80 00 20     blr

That's because you should inline ip_fast_csum() instead.

We do not want to inline ip_send_check() on eg x86, as it is clearly too
long.

ffffffff816d72e0 <ip_send_check>:
ffffffff816d72e0:       e8 9b e3 0c 00          callq  ffffffff817a5680 <__fentry__>
ffffffff816d72e5:       0f b6 17                movzbl (%rdi),%edx
ffffffff816d72e8:       55                      push   %rbp
ffffffff816d72e9:       31 c0                   xor    %eax,%eax
ffffffff816d72eb:       66 89 47 0a             mov    %ax,0xa(%rdi)
ffffffff816d72ef:       48 89 f8                mov    %rdi,%rax
ffffffff816d72f2:       48 89 e5                mov    %rsp,%rbp
ffffffff816d72f5:       83 e2 0f                and    $0xf,%edx
ffffffff816d72f8:       8b 08                   mov    (%rax),%ecx
ffffffff816d72fa:       83 ea 04                sub    $0x4,%edx
ffffffff816d72fd:       76 24                   jbe    ffffffff816d7323 <ip_send_check+0x43>
ffffffff816d72ff:       03 48 04                add    0x4(%rax),%ecx
ffffffff816d7302:       13 48 08                adc    0x8(%rax),%ecx
ffffffff816d7305:       13 48 0c                adc    0xc(%rax),%ecx
ffffffff816d7308:       13 48 10                adc    0x10(%rax),%ecx
ffffffff816d730b:       48 8d 40 04             lea    0x4(%rax),%rax
ffffffff816d730f:       ff ca                   dec    %edx
ffffffff816d7311:       75 f5                   jne    ffffffff816d7308 <ip_send_check+0x28>
ffffffff816d7313:       83 d1 00                adc    $0x0,%ecx
ffffffff816d7316:       89 ca                   mov    %ecx,%edx
ffffffff816d7318:       c1 e9 10                shr    $0x10,%ecx
ffffffff816d731b:       66 01 d1                add    %dx,%cx
ffffffff816d731e:       83 d1 00                adc    $0x0,%ecx
ffffffff816d7321:       f7 d1                   not    %ecx
ffffffff816d7323:       66 89 4f 0a             mov    %cx,0xa(%rdi)
ffffffff816d7327:       5d                      pop    %rbp
ffffffff816d7328:       c3                      retq



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/net/ip.h b/include/net/ip.h
index c0c26c3..b88d592 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -32,6 +32,7 @@ 
 #include <net/snmp.h>
 #include <net/flow.h>
 #include <net/flow_keys.h>
+#include <net/checksum.h>
 
 struct sock;
 
@@ -110,7 +111,13 @@  int ip_output(struct sock *sk, struct sk_buff *skb);
 int ip_mc_output(struct sock *sk, struct sk_buff *skb);
 int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 int ip_do_nat(struct sk_buff *skb);
-void ip_send_check(struct iphdr *ip);
+/* Generate a checksum for an outgoing IP datagram. */
+static inline void ip_send_check(struct iphdr *iph)
+{
+	iph->check = 0;
+	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+}
+
 int __ip_local_out(struct sk_buff *skb);
 int ip_local_out_sk(struct sock *sk, struct sk_buff *skb);
 static inline int ip_local_out(struct sk_buff *skb)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 357c2a9..fa054cf 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -83,14 +83,6 @@ 
 int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
 EXPORT_SYMBOL(sysctl_ip_default_ttl);
 
-/* Generate a checksum for an outgoing IP datagram. */
-void ip_send_check(struct iphdr *iph)
-{
-	iph->check = 0;
-	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-}
-EXPORT_SYMBOL(ip_send_check);
-
 int __ip_local_out(struct sk_buff *skb)
 {
 	struct iphdr *iph = ip_hdr(skb);