Revert "icmp: avoid allocating large struct on stack"
authorJesper Dangaard Brouer <brouer@redhat.com>
Mon, 9 Jan 2017 15:04:04 +0000 (16:04 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Jan 2017 20:49:12 +0000 (15:49 -0500)
This reverts commit 9a99d4a50cb8 ("icmp: avoid allocating large struct
on stack"), because struct icmp_bxm no really a large struct, and
allocating and free of this small 112 bytes hurts performance.

Fixes: 9a99d4a50cb8 ("icmp: avoid allocating large struct on stack")
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/icmp.c

index 0777ea9..b4b9807 100644 (file)
@@ -571,7 +571,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 {
        struct iphdr *iph;
        int room;
-       struct icmp_bxm *icmp_param;
+       struct icmp_bxm icmp_param;
        struct rtable *rt = skb_rtable(skb_in);
        struct ipcm_cookie ipc;
        struct flowi4 fl4;
@@ -648,13 +648,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                }
        }
 
-       icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC);
-       if (!icmp_param)
-               return;
-
        sk = icmp_xmit_lock(net);
        if (!sk)
-               goto out_free;
+               return;
 
        /*
         *      Construct source address and options.
@@ -681,7 +677,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                                          iph->tos;
        mark = IP4_REPLY_MARK(net, skb_in->mark);
 
-       if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb_in))
+       if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in))
                goto out_unlock;
 
 
@@ -689,22 +685,22 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
         *      Prepare data for ICMP header.
         */
 
-       icmp_param->data.icmph.type      = type;
-       icmp_param->data.icmph.code      = code;
-       icmp_param->data.icmph.un.gateway = info;
-       icmp_param->data.icmph.checksum  = 0;
-       icmp_param->skb   = skb_in;
-       icmp_param->offset = skb_network_offset(skb_in);
+       icmp_param.data.icmph.type       = type;
+       icmp_param.data.icmph.code       = code;
+       icmp_param.data.icmph.un.gateway = info;
+       icmp_param.data.icmph.checksum   = 0;
+       icmp_param.skb    = skb_in;
+       icmp_param.offset = skb_network_offset(skb_in);
        inet_sk(sk)->tos = tos;
        sk->sk_mark = mark;
        ipc.addr = iph->saddr;
-       ipc.opt = &icmp_param->replyopts.opt;
+       ipc.opt = &icmp_param.replyopts.opt;
        ipc.tx_flags = 0;
        ipc.ttl = 0;
        ipc.tos = -1;
 
        rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark,
-                              type, code, icmp_param);
+                              type, code, &icmp_param);
        if (IS_ERR(rt))
                goto out_unlock;
 
@@ -716,21 +712,19 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
        room = dst_mtu(&rt->dst);
        if (room > 576)
                room = 576;
-       room -= sizeof(struct iphdr) + icmp_param->replyopts.opt.opt.optlen;
+       room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
        room -= sizeof(struct icmphdr);
 
-       icmp_param->data_len = skb_in->len - icmp_param->offset;
-       if (icmp_param->data_len > room)
-               icmp_param->data_len = room;
-       icmp_param->head_len = sizeof(struct icmphdr);
+       icmp_param.data_len = skb_in->len - icmp_param.offset;
+       if (icmp_param.data_len > room)
+               icmp_param.data_len = room;
+       icmp_param.head_len = sizeof(struct icmphdr);
 
-       icmp_push_reply(icmp_param, &fl4, &ipc, &rt);
+       icmp_push_reply(&icmp_param, &fl4, &ipc, &rt);
 ende:
        ip_rt_put(rt);
 out_unlock:
        icmp_xmit_unlock(sk);
-out_free:
-       kfree(icmp_param);
 out:;
 }
 EXPORT_SYMBOL(icmp_send);