aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-02 13:49:21 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-02 13:49:21 -0500
commitb3613118eb30a589d971e4eccbbb2a1314f5dfd4 (patch)
tree868c1ee59e1b5c19a4f2e43716400d0001a994e5 /drivers/infiniband/ulp
parent7505afe28c16a8d386624930a018d0052c75d687 (diff)
parent5983fe2b29df5885880d7fa3b91aca306c7564ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c13
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c20
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c13
3 files changed, 29 insertions, 17 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 0ef9af94997d..4115be54ba3b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -57,21 +57,24 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
57 struct ib_pd *pd, struct ib_ah_attr *attr) 57 struct ib_pd *pd, struct ib_ah_attr *attr)
58{ 58{
59 struct ipoib_ah *ah; 59 struct ipoib_ah *ah;
60 struct ib_ah *vah;
60 61
61 ah = kmalloc(sizeof *ah, GFP_KERNEL); 62 ah = kmalloc(sizeof *ah, GFP_KERNEL);
62 if (!ah) 63 if (!ah)
63 return NULL; 64 return ERR_PTR(-ENOMEM);
64 65
65 ah->dev = dev; 66 ah->dev = dev;
66 ah->last_send = 0; 67 ah->last_send = 0;
67 kref_init(&ah->ref); 68 kref_init(&ah->ref);
68 69
69 ah->ah = ib_create_ah(pd, attr); 70 vah = ib_create_ah(pd, attr);
70 if (IS_ERR(ah->ah)) { 71 if (IS_ERR(vah)) {
71 kfree(ah); 72 kfree(ah);
72 ah = NULL; 73 ah = (struct ipoib_ah *)vah;
73 } else 74 } else {
75 ah->ah = vah;
74 ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah); 76 ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);
77 }
75 78
76 return ah; 79 return ah;
77} 80}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 57ae9b9265e3..d3ed89ca4852 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -432,7 +432,7 @@ static void path_rec_completion(int status,
432 432
433 spin_lock_irqsave(&priv->lock, flags); 433 spin_lock_irqsave(&priv->lock, flags);
434 434
435 if (ah) { 435 if (!IS_ERR_OR_NULL(ah)) {
436 path->pathrec = *pathrec; 436 path->pathrec = *pathrec;
437 437
438 old_ah = path->ah; 438 old_ah = path->ah;
@@ -555,6 +555,7 @@ static int path_rec_start(struct net_device *dev,
555 return 0; 555 return 0;
556} 556}
557 557
558/* called with rcu_read_lock */
558static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) 559static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
559{ 560{
560 struct ipoib_dev_priv *priv = netdev_priv(dev); 561 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -636,6 +637,7 @@ err_drop:
636 spin_unlock_irqrestore(&priv->lock, flags); 637 spin_unlock_irqrestore(&priv->lock, flags);
637} 638}
638 639
640/* called with rcu_read_lock */
639static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) 641static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
640{ 642{
641 struct ipoib_dev_priv *priv = netdev_priv(skb->dev); 643 struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
@@ -720,13 +722,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
720 struct neighbour *n = NULL; 722 struct neighbour *n = NULL;
721 unsigned long flags; 723 unsigned long flags;
722 724
725 rcu_read_lock();
723 if (likely(skb_dst(skb))) 726 if (likely(skb_dst(skb)))
724 n = dst_get_neighbour(skb_dst(skb)); 727 n = dst_get_neighbour(skb_dst(skb));
725 728
726 if (likely(n)) { 729 if (likely(n)) {
727 if (unlikely(!*to_ipoib_neigh(n))) { 730 if (unlikely(!*to_ipoib_neigh(n))) {
728 ipoib_path_lookup(skb, dev); 731 ipoib_path_lookup(skb, dev);
729 return NETDEV_TX_OK; 732 goto unlock;
730 } 733 }
731 734
732 neigh = *to_ipoib_neigh(n); 735 neigh = *to_ipoib_neigh(n);
@@ -749,17 +752,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
749 ipoib_neigh_free(dev, neigh); 752 ipoib_neigh_free(dev, neigh);
750 spin_unlock_irqrestore(&priv->lock, flags); 753 spin_unlock_irqrestore(&priv->lock, flags);
751 ipoib_path_lookup(skb, dev); 754 ipoib_path_lookup(skb, dev);
752 return NETDEV_TX_OK; 755 goto unlock;
753 } 756 }
754 757
755 if (ipoib_cm_get(neigh)) { 758 if (ipoib_cm_get(neigh)) {
756 if (ipoib_cm_up(neigh)) { 759 if (ipoib_cm_up(neigh)) {
757 ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); 760 ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
758 return NETDEV_TX_OK; 761 goto unlock;
759 } 762 }
760 } else if (neigh->ah) { 763 } else if (neigh->ah) {
761 ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha)); 764 ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha));
762 return NETDEV_TX_OK; 765 goto unlock;
763 } 766 }
764 767
765 if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { 768 if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
@@ -793,13 +796,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
793 phdr->hwaddr + 4); 796 phdr->hwaddr + 4);
794 dev_kfree_skb_any(skb); 797 dev_kfree_skb_any(skb);
795 ++dev->stats.tx_dropped; 798 ++dev->stats.tx_dropped;
796 return NETDEV_TX_OK; 799 goto unlock;
797 } 800 }
798 801
799 unicast_arp_send(skb, dev, phdr); 802 unicast_arp_send(skb, dev, phdr);
800 } 803 }
801 } 804 }
802 805unlock:
806 rcu_read_unlock();
803 return NETDEV_TX_OK; 807 return NETDEV_TX_OK;
804} 808}
805 809
@@ -837,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
837 dst = skb_dst(skb); 841 dst = skb_dst(skb);
838 n = NULL; 842 n = NULL;
839 if (dst) 843 if (dst)
840 n = dst_get_neighbour(dst); 844 n = dst_get_neighbour_raw(dst);
841 if ((!dst || !n) && daddr) { 845 if ((!dst || !n) && daddr) {
842 struct ipoib_pseudoheader *phdr = 846 struct ipoib_pseudoheader *phdr =
843 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); 847 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 1b7a97686356..873bff97e69e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -240,8 +240,11 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
240 av.grh.dgid = mcast->mcmember.mgid; 240 av.grh.dgid = mcast->mcmember.mgid;
241 241
242 ah = ipoib_create_ah(dev, priv->pd, &av); 242 ah = ipoib_create_ah(dev, priv->pd, &av);
243 if (!ah) { 243 if (IS_ERR(ah)) {
244 ipoib_warn(priv, "ib_address_create failed\n"); 244 ipoib_warn(priv, "ib_address_create failed %ld\n",
245 -PTR_ERR(ah));
246 /* use original error */
247 return PTR_ERR(ah);
245 } else { 248 } else {
246 spin_lock_irq(&priv->lock); 249 spin_lock_irq(&priv->lock);
247 mcast->ah = ah; 250 mcast->ah = ah;
@@ -266,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
266 269
267 skb->dev = dev; 270 skb->dev = dev;
268 if (dst) 271 if (dst)
269 n = dst_get_neighbour(dst); 272 n = dst_get_neighbour_raw(dst);
270 if (!dst || !n) { 273 if (!dst || !n) {
271 /* put pseudoheader back on for next time */ 274 /* put pseudoheader back on for next time */
272 skb_push(skb, sizeof (struct ipoib_pseudoheader)); 275 skb_push(skb, sizeof (struct ipoib_pseudoheader));
@@ -722,6 +725,8 @@ out:
722 if (mcast && mcast->ah) { 725 if (mcast && mcast->ah) {
723 struct dst_entry *dst = skb_dst(skb); 726 struct dst_entry *dst = skb_dst(skb);
724 struct neighbour *n = NULL; 727 struct neighbour *n = NULL;
728
729 rcu_read_lock();
725 if (dst) 730 if (dst)
726 n = dst_get_neighbour(dst); 731 n = dst_get_neighbour(dst);
727 if (n && !*to_ipoib_neigh(n)) { 732 if (n && !*to_ipoib_neigh(n)) {
@@ -734,7 +739,7 @@ out:
734 list_add_tail(&neigh->list, &mcast->neigh_list); 739 list_add_tail(&neigh->list, &mcast->neigh_list);
735 } 740 }
736 } 741 }
737 742 rcu_read_unlock();
738 spin_unlock_irqrestore(&priv->lock, flags); 743 spin_unlock_irqrestore(&priv->lock, flags);
739 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); 744 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
740 return; 745 return;