summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-02-10 17:18:46 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-02-10 17:18:46 -0500
commit8df54d622a120058ee8bec38743c9b8f091c8e58 (patch)
tree559dc9788cff370bed7b36d61f77708ff4efbaa7 /drivers/infiniband
parent612b8507c5d545feed2437b3d2239929cac7688d (diff)
parent70620c46ac2b45c24b0f22002fdf5ddd1f7daf81 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Quoth David: 1) GRO MAC header comparisons were ethernet specific, breaking other link types. This required a multi-faceted fix to cure the originally noted case (Infiniband), because IPoIB was lying about it's actual hard header length. Thanks to Eric Dumazet, Roland Dreier, and others. 2) Fix build failure when INET_UDP_DIAG is built in and ipv6 is modular. From Anisse Astier. 3) Off by ones and other bug fixes in netprio_cgroup from Neil Horman. 4) ipv4 TCP reset generation needs to respect any network interface binding from the socket, otherwise route lookups might give a different result than all the other segments received. From Shawn Lu. 5) Fix unintended regression in ipv4 proxy ARP responses, from Thomas Graf. 6) Fix SKB under-allocation bug in sh_eth, from Yoshihiro Shimoda. 7) Revert skge PCI mapping changes that are causing crashes for some folks, from Stephen Hemminger. 8) IPV4 route lookups fill in the wildcarded fields of the given flow lookup key passed in, which is fine most of the time as this is exactly what the caller's want. However there are a few cases that want to retain the original flow key values afterwards, so handle those cases properly. Fix from Julian Anastasov. 9) IGB/IXGBE VF lookup bug fixes from Greg Rose. 10) Properly null terminate filename passed to ethtool flash device method, from Ben Hutchings. 11) S3 resume fix in via-velocity from David Lv. 12) Fix double SKB free during xmit failure in CAIF, from Dmitry Tarnyagin. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (72 commits) net: Don't proxy arp respond if iif == rt->dst.dev if private VLAN is disabled ipv4: Fix wrong order of ip_rt_get_source() and update iph->daddr. netprio_cgroup: fix wrong memory access when NETPRIO_CGROUP=m netprio_cgroup: don't allocate prio table when a device is registered netprio_cgroup: fix an off-by-one bug bna: fix error handling of bnad_get_flash_partition_by_offset() isdn: type bug in isdn_net_header() net: Make qdisc_skb_cb upper size bound explicit. ixgbe: ethtool: stats user buffer overrun ixgbe: dcb: up2tc mapping lost on disable/enable CEE DCB state ixgbe: do not update real num queues when netdev is going away ixgbe: Fix broken dependency on MAX_SKB_FRAGS being related to page size ixgbe: Fix case of Tx Hang in PF with 32 VFs ixgbe: fix vf lookup igb: fix vf lookup e1000: add dropped DMA receive enable back in for WoL gro: more generic L2 header check IPoIB: Stop lying about hard_header_len and use skb->cb to stash LL addresses zd1211rw: firmware needs duration_id set to zero for non-pspoll frames net: enable TC35815 for MIPS again ...
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c55
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c10
3 files changed, 24 insertions, 47 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index b3cc1e062b17..86df632ea612 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -44,6 +44,7 @@
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45 45
46#include <net/neighbour.h> 46#include <net/neighbour.h>
47#include <net/sch_generic.h>
47 48
48#include <linux/atomic.h> 49#include <linux/atomic.h>
49 50
@@ -117,8 +118,9 @@ struct ipoib_header {
117 u16 reserved; 118 u16 reserved;
118}; 119};
119 120
120struct ipoib_pseudoheader { 121struct ipoib_cb {
121 u8 hwaddr[INFINIBAND_ALEN]; 122 struct qdisc_skb_cb qdisc_cb;
123 u8 hwaddr[INFINIBAND_ALEN];
122}; 124};
123 125
124/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ 126/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 3514ca05deea..3974c290b667 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -653,7 +653,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct neighbour *n, struct n
653} 653}
654 654
655static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, 655static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
656 struct ipoib_pseudoheader *phdr) 656 struct ipoib_cb *cb)
657{ 657{
658 struct ipoib_dev_priv *priv = netdev_priv(dev); 658 struct ipoib_dev_priv *priv = netdev_priv(dev);
659 struct ipoib_path *path; 659 struct ipoib_path *path;
@@ -661,17 +661,15 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
661 661
662 spin_lock_irqsave(&priv->lock, flags); 662 spin_lock_irqsave(&priv->lock, flags);
663 663
664 path = __path_find(dev, phdr->hwaddr + 4); 664 path = __path_find(dev, cb->hwaddr + 4);
665 if (!path || !path->valid) { 665 if (!path || !path->valid) {
666 int new_path = 0; 666 int new_path = 0;
667 667
668 if (!path) { 668 if (!path) {
669 path = path_rec_create(dev, phdr->hwaddr + 4); 669 path = path_rec_create(dev, cb->hwaddr + 4);
670 new_path = 1; 670 new_path = 1;
671 } 671 }
672 if (path) { 672 if (path) {
673 /* put pseudoheader back on for next time */
674 skb_push(skb, sizeof *phdr);
675 __skb_queue_tail(&path->queue, skb); 673 __skb_queue_tail(&path->queue, skb);
676 674
677 if (!path->query && path_rec_start(dev, path)) { 675 if (!path->query && path_rec_start(dev, path)) {
@@ -695,12 +693,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
695 be16_to_cpu(path->pathrec.dlid)); 693 be16_to_cpu(path->pathrec.dlid));
696 694
697 spin_unlock_irqrestore(&priv->lock, flags); 695 spin_unlock_irqrestore(&priv->lock, flags);
698 ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); 696 ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
699 return; 697 return;
700 } else if ((path->query || !path_rec_start(dev, path)) && 698 } else if ((path->query || !path_rec_start(dev, path)) &&
701 skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { 699 skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
702 /* put pseudoheader back on for next time */
703 skb_push(skb, sizeof *phdr);
704 __skb_queue_tail(&path->queue, skb); 700 __skb_queue_tail(&path->queue, skb);
705 } else { 701 } else {
706 ++dev->stats.tx_dropped; 702 ++dev->stats.tx_dropped;
@@ -774,16 +770,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
774 dev_kfree_skb_any(skb); 770 dev_kfree_skb_any(skb);
775 } 771 }
776 } else { 772 } else {
777 struct ipoib_pseudoheader *phdr = 773 struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
778 (struct ipoib_pseudoheader *) skb->data;
779 skb_pull(skb, sizeof *phdr);
780 774
781 if (phdr->hwaddr[4] == 0xff) { 775 if (cb->hwaddr[4] == 0xff) {
782 /* Add in the P_Key for multicast*/ 776 /* Add in the P_Key for multicast*/
783 phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; 777 cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
784 phdr->hwaddr[9] = priv->pkey & 0xff; 778 cb->hwaddr[9] = priv->pkey & 0xff;
785 779
786 ipoib_mcast_send(dev, phdr->hwaddr + 4, skb); 780 ipoib_mcast_send(dev, cb->hwaddr + 4, skb);
787 } else { 781 } else {
788 /* unicast GID -- should be ARP or RARP reply */ 782 /* unicast GID -- should be ARP or RARP reply */
789 783
@@ -792,14 +786,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
792 ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n", 786 ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
793 skb_dst(skb) ? "neigh" : "dst", 787 skb_dst(skb) ? "neigh" : "dst",
794 be16_to_cpup((__be16 *) skb->data), 788 be16_to_cpup((__be16 *) skb->data),
795 IPOIB_QPN(phdr->hwaddr), 789 IPOIB_QPN(cb->hwaddr),
796 phdr->hwaddr + 4); 790 cb->hwaddr + 4);
797 dev_kfree_skb_any(skb); 791 dev_kfree_skb_any(skb);
798 ++dev->stats.tx_dropped; 792 ++dev->stats.tx_dropped;
799 goto unlock; 793 goto unlock;
800 } 794 }
801 795
802 unicast_arp_send(skb, dev, phdr); 796 unicast_arp_send(skb, dev, cb);
803 } 797 }
804 } 798 }
805unlock: 799unlock:
@@ -825,8 +819,6 @@ static int ipoib_hard_header(struct sk_buff *skb,
825 const void *daddr, const void *saddr, unsigned len) 819 const void *daddr, const void *saddr, unsigned len)
826{ 820{
827 struct ipoib_header *header; 821 struct ipoib_header *header;
828 struct dst_entry *dst;
829 struct neighbour *n;
830 822
831 header = (struct ipoib_header *) skb_push(skb, sizeof *header); 823 header = (struct ipoib_header *) skb_push(skb, sizeof *header);
832 824
@@ -834,18 +826,13 @@ static int ipoib_hard_header(struct sk_buff *skb,
834 header->reserved = 0; 826 header->reserved = 0;
835 827
836 /* 828 /*
837 * If we don't have a neighbour structure, stuff the 829 * If we don't have a dst_entry structure, stuff the
838 * destination address onto the front of the skb so we can 830 * destination address into skb->cb so we can figure out where
839 * figure out where to send the packet later. 831 * to send the packet later.
840 */ 832 */
841 dst = skb_dst(skb); 833 if (!skb_dst(skb)) {
842 n = NULL; 834 struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
843 if (dst) 835 memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
844 n = dst_get_neighbour_noref_raw(dst);
845 if ((!dst || !n) && daddr) {
846 struct ipoib_pseudoheader *phdr =
847 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
848 memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
849 } 836 }
850 837
851 return 0; 838 return 0;
@@ -1021,11 +1008,7 @@ static void ipoib_setup(struct net_device *dev)
1021 1008
1022 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 1009 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1023 1010
1024 /* 1011 dev->hard_header_len = IPOIB_ENCAP_LEN;
1025 * We add in INFINIBAND_ALEN to allow for the destination
1026 * address "pseudoheader" for skbs without neighbour struct.
1027 */
1028 dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
1029 dev->addr_len = INFINIBAND_ALEN; 1012 dev->addr_len = INFINIBAND_ALEN;
1030 dev->type = ARPHRD_INFINIBAND; 1013 dev->type = ARPHRD_INFINIBAND;
1031 dev->tx_queue_len = ipoib_sendq_size * 2; 1014 dev->tx_queue_len = ipoib_sendq_size * 2;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index f7ff9dd66cda..20ebc6fd1bb9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -262,21 +262,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
262 netif_tx_lock_bh(dev); 262 netif_tx_lock_bh(dev);
263 while (!skb_queue_empty(&mcast->pkt_queue)) { 263 while (!skb_queue_empty(&mcast->pkt_queue)) {
264 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 264 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
265 struct dst_entry *dst = skb_dst(skb);
266 struct neighbour *n = NULL;
267 265
268 netif_tx_unlock_bh(dev); 266 netif_tx_unlock_bh(dev);
269 267
270 skb->dev = dev; 268 skb->dev = dev;
271 if (dst)
272 n = dst_get_neighbour_noref_raw(dst);
273 if (!dst || !n) {
274 /* put pseudoheader back on for next time */
275 skb_push(skb, sizeof (struct ipoib_pseudoheader));
276 }
277
278 if (dev_queue_xmit(skb)) 269 if (dev_queue_xmit(skb))
279 ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n"); 270 ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
271
280 netif_tx_lock_bh(dev); 272 netif_tx_lock_bh(dev);
281 } 273 }
282 netif_tx_unlock_bh(dev); 274 netif_tx_unlock_bh(dev);