aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-03-16 13:50:02 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-16 13:50:02 -0400
commitd1c76af9e2434fac3add561e26c61b06503de986 (patch)
treecbedc7c96c4b7db3d7a5a8300117804c5e0230d9
parentafece1c6587010cc81d1a43045c855774e8234a3 (diff)
GRO: Move netpoll checks to correct location
As my netpoll fix for net doesn't really work for net-next, we need this update to move the checks into the right place. As it stands we may pass freed skbs to netpoll_receive_skb. This patch also introduces a netpoll_rx_on function to avoid GRO completely if we're invoked through netpoll. This might seem paranoid but as netpoll may have an external receive hook it's better to be safe than sorry. I don't think we need this for 2.6.29 though since there's nothing immediately broken by it. This patch also moves the GRO_* return values to netdevice.h since VLAN needs them too (I tried to avoid this originally but alas this seems to be the easiest way out). This fixes a bug in VLAN where it continued to use the old return value 2 instead of the correct GRO_DROP. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/netpoll.h11
-rw-r--r--net/8021q/vlan_core.c11
-rw-r--r--net/core/dev.c17
4 files changed, 26 insertions, 21 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 493b065f76d7..be3ebd7e8ce5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -330,6 +330,14 @@ enum
330 NAPI_STATE_NPSVC, /* Netpoll - don't dequeue from poll_list */ 330 NAPI_STATE_NPSVC, /* Netpoll - don't dequeue from poll_list */
331}; 331};
332 332
333enum {
334 GRO_MERGED,
335 GRO_MERGED_FREE,
336 GRO_HELD,
337 GRO_NORMAL,
338 GRO_DROP,
339};
340
333extern void __napi_schedule(struct napi_struct *n); 341extern void __napi_schedule(struct napi_struct *n);
334 342
335static inline int napi_disable_pending(struct napi_struct *n) 343static inline int napi_disable_pending(struct napi_struct *n)
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index e38d3c9dccda..de99025f2c5d 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -63,6 +63,13 @@ static inline int netpoll_rx(struct sk_buff *skb)
63 return ret; 63 return ret;
64} 64}
65 65
66static inline int netpoll_rx_on(struct sk_buff *skb)
67{
68 struct netpoll_info *npinfo = skb->dev->npinfo;
69
70 return npinfo && (npinfo->rx_np || npinfo->rx_flags);
71}
72
66static inline int netpoll_receive_skb(struct sk_buff *skb) 73static inline int netpoll_receive_skb(struct sk_buff *skb)
67{ 74{
68 if (!list_empty(&skb->dev->napi_list)) 75 if (!list_empty(&skb->dev->napi_list))
@@ -99,6 +106,10 @@ static inline int netpoll_rx(struct sk_buff *skb)
99{ 106{
100 return 0; 107 return 0;
101} 108}
109static inline int netpoll_rx_on(struct sk_buff *skb)
110{
111 return 0;
112}
102static inline int netpoll_receive_skb(struct sk_buff *skb) 113static inline int netpoll_receive_skb(struct sk_buff *skb)
103{ 114{
104 return 0; 115 return 0;
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 2d6e405fc498..6227248597c4 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -79,6 +79,9 @@ static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
79{ 79{
80 struct sk_buff *p; 80 struct sk_buff *p;
81 81
82 if (netpoll_rx_on(skb))
83 return GRO_NORMAL;
84
82 if (skb_bond_should_drop(skb)) 85 if (skb_bond_should_drop(skb))
83 goto drop; 86 goto drop;
84 87
@@ -98,7 +101,7 @@ static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
98 return dev_gro_receive(napi, skb); 101 return dev_gro_receive(napi, skb);
99 102
100drop: 103drop:
101 return 2; 104 return GRO_DROP;
102} 105}
103 106
104int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, 107int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
@@ -106,9 +109,6 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
106{ 109{
107 skb_gro_reset_offset(skb); 110 skb_gro_reset_offset(skb);
108 111
109 if (netpoll_receive_skb(skb))
110 return NET_RX_DROP;
111
112 return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb); 112 return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb);
113} 113}
114EXPORT_SYMBOL(vlan_gro_receive); 114EXPORT_SYMBOL(vlan_gro_receive);
@@ -121,9 +121,6 @@ int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
121 if (!skb) 121 if (!skb)
122 return NET_RX_DROP; 122 return NET_RX_DROP;
123 123
124 if (netpoll_receive_skb(skb))
125 return NET_RX_DROP;
126
127 return napi_frags_finish(napi, skb, 124 return napi_frags_finish(napi, skb,
128 vlan_gro_common(napi, grp, vlan_tci, skb)); 125 vlan_gro_common(napi, grp, vlan_tci, skb));
129} 126}
diff --git a/net/core/dev.c b/net/core/dev.c
index 033d7ca28e6e..7bd3c29c5a78 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -135,14 +135,6 @@
135/* This should be increased if a protocol with a bigger head is added. */ 135/* This should be increased if a protocol with a bigger head is added. */
136#define GRO_MAX_HEAD (MAX_HEADER + 128) 136#define GRO_MAX_HEAD (MAX_HEADER + 128)
137 137
138enum {
139 GRO_MERGED,
140 GRO_MERGED_FREE,
141 GRO_HELD,
142 GRO_NORMAL,
143 GRO_DROP,
144};
145
146/* 138/*
147 * The list of packet types we will receive (as opposed to discard) 139 * The list of packet types we will receive (as opposed to discard)
148 * and the routines to invoke. 140 * and the routines to invoke.
@@ -2474,6 +2466,9 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
2474{ 2466{
2475 struct sk_buff *p; 2467 struct sk_buff *p;
2476 2468
2469 if (netpoll_rx_on(skb))
2470 return GRO_NORMAL;
2471
2477 for (p = napi->gro_list; p; p = p->next) { 2472 for (p = napi->gro_list; p; p = p->next) {
2478 NAPI_GRO_CB(p)->same_flow = !compare_ether_header( 2473 NAPI_GRO_CB(p)->same_flow = !compare_ether_header(
2479 skb_mac_header(p), skb_gro_mac_header(skb)); 2474 skb_mac_header(p), skb_gro_mac_header(skb));
@@ -2487,9 +2482,6 @@ int napi_skb_finish(int ret, struct sk_buff *skb)
2487{ 2482{
2488 int err = NET_RX_SUCCESS; 2483 int err = NET_RX_SUCCESS;
2489 2484
2490 if (netpoll_receive_skb(skb))
2491 return NET_RX_DROP;
2492
2493 switch (ret) { 2485 switch (ret) {
2494 case GRO_NORMAL: 2486 case GRO_NORMAL:
2495 return netif_receive_skb(skb); 2487 return netif_receive_skb(skb);
@@ -2587,9 +2579,6 @@ int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
2587{ 2579{
2588 int err = NET_RX_SUCCESS; 2580 int err = NET_RX_SUCCESS;
2589 2581
2590 if (netpoll_receive_skb(skb))
2591 return NET_RX_DROP;
2592
2593 switch (ret) { 2582 switch (ret) {
2594 case GRO_NORMAL: 2583 case GRO_NORMAL:
2595 case GRO_HELD: 2584 case GRO_HELD: