[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180914175941.213950-4-willemdebruijn.kernel@gmail.com>
Date: Fri, 14 Sep 2018 13:59:36 -0400
From: Willem de Bruijn <willemdebruijn.kernel@...il.com>
To: netdev@...r.kernel.org
Cc: pabeni@...hat.com, steffen.klassert@...unet.com,
davem@...emloft.net, Willem de Bruijn <willemb@...gle.com>
Subject: [PATCH net-next RFC 3/8] gro: add net_gro_receive
From: Willem de Bruijn <willemb@...gle.com>
For configurable gro_receive all callsites need to be updated. Similar
to gro_complete, introduce a single shared helper, net_gro_receive.
Signed-off-by: Willem de Bruijn <willemb@...gle.com>
---
drivers/net/geneve.c | 2 +-
include/linux/netdevice.h | 14 +++++++++++++-
net/8021q/vlan.c | 2 +-
net/core/dev.c | 20 ++++----------------
net/ethernet/eth.c | 2 +-
net/ipv4/af_inet.c | 4 ++--
net/ipv4/fou.c | 8 ++++----
net/ipv4/gre_offload.c | 12 ++++++------
net/ipv6/ip6_offload.c | 8 ++++----
9 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index a3a4621d9bee..a812a774e5fd 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -467,7 +467,7 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk,
type = gh->proto_type;
rcu_read_lock();
- ptype = gro_find_receive_by_type(type);
+ ptype = net_gro_receive(dev_offloads, type);
if (!ptype)
goto out_unlock;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0d292ea6716e..0be594f8d1ce 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3556,7 +3556,6 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
void napi_gro_flush(struct napi_struct *napi, bool flush_old);
struct sk_buff *napi_get_frags(struct napi_struct *napi);
gro_result_t napi_gro_frags(struct napi_struct *napi);
-struct packet_offload *gro_find_receive_by_type(__be16 type);
extern const struct net_offload __rcu *dev_offloads[256];
@@ -3568,6 +3567,19 @@ static inline u8 net_offload_from_type(u16 type)
return type & 0xFF;
}
+static inline const struct net_offload *
+net_gro_receive(const struct net_offload __rcu **offs, u16 type)
+{
+ const struct net_offload *off;
+
+ off = rcu_dereference(offs[net_offload_from_type(type)]);
+ if (off && off->callbacks.gro_receive &&
+ (!off->type || off->type == type))
+ return off;
+ else
+ return NULL;
+}
+
static inline int net_gro_complete(const struct net_offload __rcu **offs,
u16 type, struct sk_buff *skb, int nhoff)
{
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 6ac27aa9f158..a106c5373b1d 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -670,7 +670,7 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head,
type = vhdr->h_vlan_encapsulated_proto;
rcu_read_lock();
- ptype = gro_find_receive_by_type(type);
+ ptype = net_gro_receive(dev_offloads, type);
if (!ptype)
goto out_unlock;
diff --git a/net/core/dev.c b/net/core/dev.c
index 2c21e507291f..ae5fbd4114d2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5382,7 +5382,7 @@ static void gro_flush_oldest(struct list_head *head)
static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1);
- const struct packet_offload *ptype;
+ const struct net_offload *ops;
__be16 type = skb->protocol;
struct list_head *gro_head;
struct sk_buff *pp = NULL;
@@ -5396,8 +5396,8 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
gro_head = gro_list_prepare(napi, skb);
rcu_read_lock();
- ptype = dev_offloads[net_offload_from_type(type)];
- if (ptype && ptype->callbacks.gro_receive) {
+ ops = net_gro_receive(dev_offloads, type);
+ if (ops) {
skb_set_network_header(skb, skb_gro_offset(skb));
skb_reset_mac_len(skb);
NAPI_GRO_CB(skb)->same_flow = 0;
@@ -5425,7 +5425,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
NAPI_GRO_CB(skb)->csum_valid = 0;
}
- pp = ptype->callbacks.gro_receive(gro_head, skb);
+ pp = ops->callbacks.gro_receive(gro_head, skb);
rcu_read_unlock();
} else {
rcu_read_unlock();
@@ -5483,18 +5483,6 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
goto pull;
}
-struct packet_offload *gro_find_receive_by_type(__be16 type)
-{
- struct net_offload *off;
-
- off = (struct net_offload *) rcu_dereference(dev_offloads[type & 0xFF]);
- if (off && off->type == type && off->callbacks.gro_receive)
- return off;
- else
- return NULL;
-}
-EXPORT_SYMBOL(gro_find_receive_by_type);
-
static void napi_skb_free_stolen_head(struct sk_buff *skb)
{
skb_dst_drop(skb);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index fb17a13722e8..542dbc2ec956 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -462,7 +462,7 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb)
type = eh->h_proto;
rcu_read_lock();
- ptype = gro_find_receive_by_type(type);
+ ptype = net_gro_receive(dev_offloads, type);
if (ptype == NULL) {
flush = 1;
goto out_unlock;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 1b72ee4a7811..28b7c7671789 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1409,8 +1409,8 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)
proto = iph->protocol;
rcu_read_lock();
- ops = rcu_dereference(inet_offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive)
+ ops = net_gro_receive(inet_offloads, proto);
+ if (!ops)
goto out_unlock;
if (*(u8 *)iph != 0x45)
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index c42a3ef17864..13401cb2e7a4 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -246,8 +246,8 @@ static struct sk_buff *fou_gro_receive(struct sock *sk,
rcu_read_lock();
offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
- ops = rcu_dereference(offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive)
+ ops = net_gro_receive(offloads, proto);
+ if (!ops)
goto out_unlock;
pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
@@ -428,8 +428,8 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,
rcu_read_lock();
offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
- ops = rcu_dereference(offloads[proto]);
- if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
+ ops = net_gro_receive(offloads, proto);
+ if (WARN_ON_ONCE(!ops))
goto out_unlock;
pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index fc8c99e4a058..4f9237a4bea1 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -111,13 +111,13 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
static struct sk_buff *gre_gro_receive(struct list_head *head,
struct sk_buff *skb)
{
- struct sk_buff *pp = NULL;
- struct sk_buff *p;
const struct gre_base_hdr *greh;
+ const struct net_offload *ops;
unsigned int hlen, grehlen;
+ struct sk_buff *pp = NULL;
+ struct sk_buff *p;
unsigned int off;
int flush = 1;
- struct packet_offload *ptype;
__be16 type;
if (NAPI_GRO_CB(skb)->encap_mark)
@@ -154,8 +154,8 @@ static struct sk_buff *gre_gro_receive(struct list_head *head,
type = greh->protocol;
rcu_read_lock();
- ptype = gro_find_receive_by_type(type);
- if (!ptype)
+ ops = net_gro_receive(dev_offloads, type);
+ if (!ops)
goto out_unlock;
grehlen = GRE_HEADER_SECTION;
@@ -217,7 +217,7 @@ static struct sk_buff *gre_gro_receive(struct list_head *head,
/* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/
skb_gro_postpull_rcsum(skb, greh, grehlen);
- pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
flush = 0;
out_unlock:
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index e8bf554ae611..9d301bef0e23 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -194,8 +194,8 @@ static struct sk_buff *ipv6_gro_receive(struct list_head *head,
rcu_read_lock();
proto = iph->nexthdr;
- ops = rcu_dereference(inet6_offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive) {
+ ops = net_gro_receive(inet6_offloads, proto);
+ if (!ops) {
__pskb_pull(skb, skb_gro_offset(skb));
skb_gro_frag0_invalidate(skb);
proto = ipv6_gso_pull_exthdrs(skb, proto);
@@ -203,8 +203,8 @@ static struct sk_buff *ipv6_gro_receive(struct list_head *head,
skb_reset_transport_header(skb);
__skb_push(skb, skb_gro_offset(skb));
- ops = rcu_dereference(inet6_offloads[proto]);
- if (!ops || !ops->callbacks.gro_receive)
+ ops = net_gro_receive(inet6_offloads, proto);
+ if (!ops)
goto out_unlock;
iph = ipv6_hdr(skb);
--
2.19.0.397.gdd90340f6a-goog
Powered by blists - more mailing lists