[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [linux-ppc-2.6] Backport the fix in current xen-unstable tree.
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID bcd09a8690af89f3c8ac1bc92a003d2a9cddb0c6 # Parent 968ced1469e8cbf36d00f437ac084bf064f6df00 Backport the fix in current xen-unstable tree. Signed-off-by: Tony Breeds <tony@xxxxxxxxxxxxxxxxxx> Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> --- --- drivers/net/bnx2.c | 2 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/forcedeth.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/loopback.c | 2 +- drivers/net/sky2.c | 2 +- drivers/net/typhoon.c | 4 ++-- drivers/s390/net/qeth_main.c | 2 +- include/linux/netdevice.h | 14 ++++++++------ include/linux/skbuff.h | 5 +++++ include/net/protocol.h | 1 + include/net/tcp.h | 1 + net/bridge/br_netfilter.c | 2 +- net/core/dev.c | 36 ++++++++++++++++++++++++++++++++---- net/ipv4/af_inet.c | 36 ++++++++++++++++++++++++++++++++++++ net/ipv4/ip_output.c | 4 ++-- net/ipv4/tcp_ipv4.c | 18 ++++++++++++++++++ net/ipv4/xfrm4_output.c | 2 +- net/ipv6/ip6_output.c | 2 +- net/ipv6/xfrm6_output.c | 2 +- 21 files changed, 117 insertions(+), 26 deletions(-) diff -r 968ced1469e8 -r bcd09a8690af drivers/net/bnx2.c --- a/drivers/net/bnx2.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/bnx2.c Tue Oct 24 06:10:42 2006 -0400 @@ -1640,7 +1640,7 @@ bnx2_tx_int(struct bnx2 *bp) skb = tx_buf->skb; #ifdef BCM_TSO /* partial BD completions possible with TSO packets */ - if (skb_shinfo(skb)->gso_size) { + if (skb_is_gso(skb)) { u16 last_idx, last_ring_idx; last_idx = sw_cons + diff -r 968ced1469e8 -r bcd09a8690af drivers/net/chelsio/sge.c --- a/drivers/net/chelsio/sge.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/chelsio/sge.c Tue Oct 24 06:10:42 2006 -0400 @@ -1418,7 +1418,7 @@ int t1_start_xmit(struct sk_buff *skb, s struct cpl_tx_pkt *cpl; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->gso_size) { + if (skb_is_gso(skb)) { int eth_type; struct cpl_tx_pkt_lso *hdr; diff -r 968ced1469e8 -r bcd09a8690af drivers/net/e1000/e1000_main.c --- a/drivers/net/e1000/e1000_main.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/e1000/e1000_main.c Tue Oct 24 06:10:42 2006 -0400 @@ -2394,7 +2394,7 @@ e1000_tso(struct e1000_adapter *adapter, uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; - if (skb_shinfo(skb)->gso_size) { + if (skb_is_gso(skb)) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) diff -r 968ced1469e8 -r bcd09a8690af drivers/net/forcedeth.c --- a/drivers/net/forcedeth.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/forcedeth.c Tue Oct 24 06:10:42 2006 -0400 @@ -1495,7 +1495,7 @@ static int nv_start_xmit(struct sk_buff np->tx_skbuff[nr] = skb; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->gso_size) + if (skb_is_gso(skb)) tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); else #endif diff -r 968ced1469e8 -r bcd09a8690af drivers/net/ixgb/ixgb_main.c --- a/drivers/net/ixgb/ixgb_main.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/ixgb/ixgb_main.c Tue Oct 24 06:10:42 2006 -0400 @@ -1173,7 +1173,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s uint16_t ipcse, tucse, mss; int err; - if(likely(skb_shinfo(skb)->gso_size)) { + if (likely(skb_is_gso(skb))) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) diff -r 968ced1469e8 -r bcd09a8690af drivers/net/loopback.c --- a/drivers/net/loopback.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/loopback.c Tue Oct 24 06:10:42 2006 -0400 @@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff #endif #ifdef LOOPBACK_TSO - if (skb_shinfo(skb)->gso_size) { + if (skb_is_gso(skb)) { BUG_ON(skb->protocol != htons(ETH_P_IP)); BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); diff -r 968ced1469e8 -r bcd09a8690af drivers/net/sky2.c --- a/drivers/net/sky2.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/sky2.c Tue Oct 24 06:10:42 2006 -0400 @@ -1160,7 +1160,7 @@ static unsigned tx_le_req(const struct s count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_shinfo(skb)->gso_size) + if (skb_is_gso(skb)) ++count; if (skb->ip_summed == CHECKSUM_HW) diff -r 968ced1469e8 -r bcd09a8690af drivers/net/typhoon.c --- a/drivers/net/typhoon.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/net/typhoon.c Tue Oct 24 06:10:42 2006 -0400 @@ -805,7 +805,7 @@ typhoon_start_tx(struct sk_buff *skb, st * If problems develop with TSO, check this first. */ numDesc = skb_shinfo(skb)->nr_frags + 1; - if(skb_tso_size(skb)) + if (skb_is_gso(skb)) numDesc++; /* When checking for free space in the ring, we need to also @@ -845,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, st TYPHOON_TX_PF_VLAN_TAG_SHIFT); } - if(skb_tso_size(skb)) { + if (skb_is_gso(skb)) { first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; first_txd->numDesc++; diff -r 968ced1469e8 -r bcd09a8690af drivers/s390/net/qeth_main.c --- a/drivers/s390/net/qeth_main.c Tue Oct 17 17:03:31 2006 -0400 +++ b/drivers/s390/net/qeth_main.c Tue Oct 24 06:10:42 2006 -0400 @@ -4453,7 +4453,7 @@ qeth_send_packet(struct qeth_card *card, queue = card->qdio.out_qs [qeth_get_priority_queue(card, skb, ipv, cast_type)]; - if (skb_shinfo(skb)->gso_size) + if (skb_is_gso(skb)) large_send = card->options.large_send; /*are we able to do TSO ? If so ,prepare and send it from here */ diff -r 968ced1469e8 -r bcd09a8690af include/linux/netdevice.h --- a/include/linux/netdevice.h Tue Oct 17 17:03:31 2006 -0400 +++ b/include/linux/netdevice.h Tue Oct 24 06:10:42 2006 -0400 @@ -547,6 +547,7 @@ struct packet_type { struct net_device *); struct sk_buff *(*gso_segment)(struct sk_buff *skb, int features); + int (*gso_send_check)(struct sk_buff *skb); void *af_packet_priv; struct list_head list; }; @@ -921,10 +922,10 @@ static inline void netif_tx_lock_bh(stru static inline int netif_tx_trylock(struct net_device *dev) { - int err = spin_trylock(&dev->_xmit_lock); - if (!err) + int ok = spin_trylock(&dev->_xmit_lock); + if (likely(ok)) dev->xmit_lock_owner = smp_processor_id(); - return err; + return ok; } static inline void netif_tx_unlock(struct net_device *dev) @@ -993,14 +994,15 @@ extern void linkwatch_run_queue(void); static inline int skb_gso_ok(struct sk_buff *skb, int features) { - int feature = skb_shinfo(skb)->gso_size ? - skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0; + int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT; return (features & feature) == feature; } static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { - return !skb_gso_ok(skb, dev->features); + return skb_is_gso(skb) && + (!skb_gso_ok(skb, dev->features) || + unlikely(skb->ip_summed != CHECKSUM_HW)); } #endif /* __KERNEL__ */ diff -r 968ced1469e8 -r bcd09a8690af include/linux/skbuff.h --- a/include/linux/skbuff.h Tue Oct 17 17:03:31 2006 -0400 +++ b/include/linux/skbuff.h Tue Oct 24 06:10:42 2006 -0400 @@ -1459,5 +1459,10 @@ static inline void skb_init_secmark(stru { } #endif +static inline int skb_is_gso(const struct sk_buff *skb) +{ + return skb_shinfo(skb)->gso_size; +} + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff -r 968ced1469e8 -r bcd09a8690af include/net/protocol.h --- a/include/net/protocol.h Tue Oct 17 17:03:31 2006 -0400 +++ b/include/net/protocol.h Tue Oct 24 06:10:42 2006 -0400 @@ -36,6 +36,7 @@ struct net_protocol { struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); + int (*gso_send_check)(struct sk_buff *skb); struct sk_buff *(*gso_segment)(struct sk_buff *skb, int features); int no_policy; diff -r 968ced1469e8 -r bcd09a8690af include/net/tcp.h --- a/include/net/tcp.h Tue Oct 17 17:03:31 2006 -0400 +++ b/include/net/tcp.h Tue Oct 24 06:10:42 2006 -0400 @@ -1086,6 +1086,7 @@ extern struct request_sock_ops tcp_reque extern int tcp_v4_destroy_sock(struct sock *sk); +extern int tcp_v4_gso_send_check(struct sk_buff *skb); extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); #ifdef CONFIG_PROC_FS diff -r 968ced1469e8 -r bcd09a8690af net/bridge/br_netfilter.c --- a/net/bridge/br_netfilter.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/bridge/br_netfilter.c Tue Oct 24 06:10:42 2006 -0400 @@ -761,7 +761,7 @@ static int br_nf_dev_queue_xmit(struct s { if (skb->protocol == htons(ETH_P_IP) && skb->len > skb->dev->mtu && - !skb_shinfo(skb)->gso_size) + !skb_is_gso(skb)) return ip_fragment(skb, br_dev_queue_push_xmit); else return br_dev_queue_push_xmit(skb); diff -r 968ced1469e8 -r bcd09a8690af net/core/dev.c --- a/net/core/dev.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/core/dev.c Tue Oct 24 06:10:42 2006 -0400 @@ -1169,9 +1169,17 @@ int skb_checksum_help(struct sk_buff *sk unsigned int csum; int ret = 0, offset = skb->h.raw - skb->data; - if (inward) { - skb->ip_summed = CHECKSUM_NONE; - goto out; + if (inward) + goto out_set_summed; + + if (unlikely(skb_shinfo(skb)->gso_size)) { + static int warned; + + WARN_ON(!warned); + warned = 1; + + /* Let GSO fix up the checksum. */ + goto out_set_summed; } if (skb_cloned(skb)) { @@ -1188,6 +1196,8 @@ int skb_checksum_help(struct sk_buff *sk BUG_ON(skb->csum + 2 > offset); *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum); + +out_set_summed: skb->ip_summed = CHECKSUM_NONE; out: return ret; @@ -1208,17 +1218,35 @@ struct sk_buff *skb_gso_segment(struct s struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); struct packet_type *ptype; int type = skb->protocol; + int err; BUG_ON(skb_shinfo(skb)->frag_list); - BUG_ON(skb->ip_summed != CHECKSUM_HW); skb->mac.raw = skb->data; skb->mac_len = skb->nh.raw - skb->data; __skb_pull(skb, skb->mac_len); + if (unlikely(skb->ip_summed != CHECKSUM_HW)) { + static int warned; + + WARN_ON(!warned); + warned = 1; + + if (skb_header_cloned(skb) && + (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) + return ERR_PTR(err); + } + rcu_read_lock(); list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { if (ptype->type == type && !ptype->dev && ptype->gso_segment) { + if (unlikely(skb->ip_summed != CHECKSUM_HW)) { + err = ptype->gso_send_check(skb); + segs = ERR_PTR(err); + if (err || skb_gso_ok(skb, features)) + break; + __skb_push(skb, skb->data - skb->nh.raw); + } segs = ptype->gso_segment(skb, features); break; } diff -r 968ced1469e8 -r bcd09a8690af net/ipv4/af_inet.c --- a/net/ipv4/af_inet.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv4/af_inet.c Tue Oct 24 06:10:42 2006 -0400 @@ -1097,6 +1097,40 @@ int inet_sk_rebuild_header(struct sock * EXPORT_SYMBOL(inet_sk_rebuild_header); +static int inet_gso_send_check(struct sk_buff *skb) +{ + struct iphdr *iph; + struct net_protocol *ops; + int proto; + int ihl; + int err = -EINVAL; + + if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) + goto out; + + iph = skb->nh.iph; + ihl = iph->ihl * 4; + if (ihl < sizeof(*iph)) + goto out; + + if (unlikely(!pskb_may_pull(skb, ihl))) + goto out; + + skb->h.raw = __skb_pull(skb, ihl); + iph = skb->nh.iph; + proto = iph->protocol & (MAX_INET_PROTOS - 1); + err = -EPROTONOSUPPORT; + + rcu_read_lock(); + ops = rcu_dereference(inet_protos[proto]); + if (likely(ops && ops->gso_send_check)) + err = ops->gso_send_check(skb); + rcu_read_unlock(); + +out: + return err; +} + static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) { struct sk_buff *segs = ERR_PTR(-EINVAL); @@ -1154,6 +1188,7 @@ static struct net_protocol tcp_protocol static struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, + .gso_send_check = tcp_v4_gso_send_check, .gso_segment = tcp_tso_segment, .no_policy = 1, }; @@ -1200,6 +1235,7 @@ static struct packet_type ip_packet_type static struct packet_type ip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = ip_rcv, + .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment, }; diff -r 968ced1469e8 -r bcd09a8690af net/ipv4/ip_output.c --- a/net/ipv4/ip_output.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv4/ip_output.c Tue Oct 24 06:10:42 2006 -0400 @@ -210,7 +210,7 @@ static inline int ip_finish_output(struc return dst_output(skb); } #endif - if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) + if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) return ip_fragment(skb, ip_finish_output2); else return ip_finish_output2(skb); @@ -1096,7 +1096,7 @@ ssize_t ip_append_page(struct sock *sk, while (size > 0) { int i; - if (skb_shinfo(skb)->gso_size) + if (skb_is_gso(skb)) len = size; else { diff -r 968ced1469e8 -r bcd09a8690af net/ipv4/tcp_ipv4.c --- a/net/ipv4/tcp_ipv4.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv4/tcp_ipv4.c Tue Oct 24 06:10:42 2006 -0400 @@ -494,6 +494,24 @@ void tcp_v4_send_check(struct sock *sk, th->doff << 2, skb->csum)); } +} + +int tcp_v4_gso_send_check(struct sk_buff *skb) +{ + struct iphdr *iph; + struct tcphdr *th; + + if (!pskb_may_pull(skb, sizeof(*th))) + return -EINVAL; + + iph = skb->nh.iph; + th = skb->h.th; + + th->check = 0; + th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0); + skb->csum = offsetof(struct tcphdr, check); + skb->ip_summed = CHECKSUM_HW; + return 0; } /* diff -r 968ced1469e8 -r bcd09a8690af net/ipv4/xfrm4_output.c --- a/net/ipv4/xfrm4_output.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv4/xfrm4_output.c Tue Oct 24 06:10:42 2006 -0400 @@ -140,7 +140,7 @@ static int xfrm4_output_finish(struct sk } #endif - if (!skb_shinfo(skb)->gso_size) + if (!skb_is_gso(skb)) return xfrm4_output_finish2(skb); skb->protocol = htons(ETH_P_IP); diff -r 968ced1469e8 -r bcd09a8690af net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv6/ip6_output.c Tue Oct 24 06:10:42 2006 -0400 @@ -148,7 +148,7 @@ static int ip6_output2(struct sk_buff *s int ip6_output(struct sk_buff *skb) { - if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) || + if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) || dst_allfrag(skb->dst)) return ip6_fragment(skb, ip6_output2); else diff -r 968ced1469e8 -r bcd09a8690af net/ipv6/xfrm6_output.c --- a/net/ipv6/xfrm6_output.c Tue Oct 17 17:03:31 2006 -0400 +++ b/net/ipv6/xfrm6_output.c Tue Oct 24 06:10:42 2006 -0400 @@ -122,7 +122,7 @@ static int xfrm6_output_finish(struct sk { struct sk_buff *segs; - if (!skb_shinfo(skb)->gso_size) + if (!skb_is_gso(skb)) return xfrm6_output_finish2(skb); skb->protocol = htons(ETH_P_IP); _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |