aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2018-12-14 05:51:58 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-15 16:23:02 -0500
commitaaa5d90b395a72faff797b00d815165ee0e664c0 (patch)
tree1200ce4b331921a7ae77964b525c4a3502b726a0 /net/core/dev.c
parent283c16a2dfd332bf5610c874f7b9f9c8b601ce53 (diff)
net: use indirect call wrappers at GRO network layer
This avoids an indirect calls for L3 GRO receive path, both for ipv4 and ipv6, if the latter is not compiled as a module. Note that when IPv6 is compiled as builtin, it will be checked first, so we have a single additional compare for the more common path. v1 -> v2: - adapted to INDIRECT_CALL_ changes Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index ed9aa4a91f1f..1b5a4410be0e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -145,6 +145,7 @@
145#include <linux/sctp.h> 145#include <linux/sctp.h>
146#include <net/udp_tunnel.h> 146#include <net/udp_tunnel.h>
147#include <linux/net_namespace.h> 147#include <linux/net_namespace.h>
148#include <linux/indirect_call_wrapper.h>
148 149
149#include "net-sysfs.h" 150#include "net-sysfs.h"
150 151
@@ -5338,6 +5339,8 @@ static void flush_all_backlogs(void)
5338 put_online_cpus(); 5339 put_online_cpus();
5339} 5340}
5340 5341
5342INDIRECT_CALLABLE_DECLARE(int inet_gro_complete(struct sk_buff *, int));
5343INDIRECT_CALLABLE_DECLARE(int ipv6_gro_complete(struct sk_buff *, int));
5341static int napi_gro_complete(struct sk_buff *skb) 5344static int napi_gro_complete(struct sk_buff *skb)
5342{ 5345{
5343 struct packet_offload *ptype; 5346 struct packet_offload *ptype;
@@ -5357,7 +5360,9 @@ static int napi_gro_complete(struct sk_buff *skb)
5357 if (ptype->type != type || !ptype->callbacks.gro_complete) 5360 if (ptype->type != type || !ptype->callbacks.gro_complete)
5358 continue; 5361 continue;
5359 5362
5360 err = ptype->callbacks.gro_complete(skb, 0); 5363 err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
5364 ipv6_gro_complete, inet_gro_complete,
5365 skb, 0);
5361 break; 5366 break;
5362 } 5367 }
5363 rcu_read_unlock(); 5368 rcu_read_unlock();
@@ -5504,6 +5509,10 @@ static void gro_flush_oldest(struct list_head *head)
5504 napi_gro_complete(oldest); 5509 napi_gro_complete(oldest);
5505} 5510}
5506 5511
5512INDIRECT_CALLABLE_DECLARE(struct sk_buff *inet_gro_receive(struct list_head *,
5513 struct sk_buff *));
5514INDIRECT_CALLABLE_DECLARE(struct sk_buff *ipv6_gro_receive(struct list_head *,
5515 struct sk_buff *));
5507static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) 5516static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
5508{ 5517{
5509 u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1); 5518 u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1);
@@ -5553,7 +5562,9 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
5553 NAPI_GRO_CB(skb)->csum_valid = 0; 5562 NAPI_GRO_CB(skb)->csum_valid = 0;
5554 } 5563 }
5555 5564
5556 pp = ptype->callbacks.gro_receive(gro_head, skb); 5565 pp = INDIRECT_CALL_INET(ptype->callbacks.gro_receive,
5566 ipv6_gro_receive, inet_gro_receive,
5567 gro_head, skb);
5557 break; 5568 break;
5558 } 5569 }
5559 rcu_read_unlock(); 5570 rcu_read_unlock();