diff options
author | Jesse Gross <jesse@nicira.com> | 2010-10-29 08:14:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-15 12:22:52 -0500 |
commit | e1e78db628b33c657944865e3bca01ee59cc5b80 (patch) | |
tree | 98649d2224fbd76f9783905be498c5b70a63f50a /net/core/dev.c | |
parent | 410989f65151557701ce86875b141e694281dd6c (diff) |
offloading: Make scatter/gather more tolerant of vlans.
When checking if it is necessary to linearize a packet, we currently
use vlan_features if the packet contains either an in-band or out-
of-band vlan tag. However, in-band tags aren't special in any way
for scatter/gather since they are part of the packet buffer and are
simply more data to DMA. Therefore, only use vlan_features for out-
of-band tags, which could potentially have some interaction with
scatter/gather.
Signed-off-by: Jesse Gross <jesse@nicira.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 5968c822c999..0b403d503311 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1976,15 +1976,20 @@ static inline void skb_orphan_try(struct sk_buff *skb) | |||
1976 | static inline int skb_needs_linearize(struct sk_buff *skb, | 1976 | static inline int skb_needs_linearize(struct sk_buff *skb, |
1977 | struct net_device *dev) | 1977 | struct net_device *dev) |
1978 | { | 1978 | { |
1979 | int features = dev->features; | 1979 | if (skb_is_nonlinear(skb)) { |
1980 | int features = dev->features; | ||
1980 | 1981 | ||
1981 | if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) | 1982 | if (vlan_tx_tag_present(skb)) |
1982 | features &= dev->vlan_features; | 1983 | features &= dev->vlan_features; |
1983 | 1984 | ||
1984 | return skb_is_nonlinear(skb) && | 1985 | return (skb_has_frag_list(skb) && |
1985 | ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || | 1986 | !(features & NETIF_F_FRAGLIST)) || |
1986 | (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || | 1987 | (skb_shinfo(skb)->nr_frags && |
1987 | illegal_highdma(dev, skb)))); | 1988 | (!(features & NETIF_F_SG) || |
1989 | illegal_highdma(dev, skb))); | ||
1990 | } | ||
1991 | |||
1992 | return 0; | ||
1988 | } | 1993 | } |
1989 | 1994 | ||
1990 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 1995 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |