diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 28 |
2 files changed, 25 insertions, 4 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index e0a5412b7e68..2f85a9a831b1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -78,6 +78,7 @@ enum { | |||
78 | IPOIB_FLAG_SUBINTERFACE = 4, | 78 | IPOIB_FLAG_SUBINTERFACE = 4, |
79 | IPOIB_MCAST_RUN = 5, | 79 | IPOIB_MCAST_RUN = 5, |
80 | IPOIB_STOP_REAPER = 6, | 80 | IPOIB_STOP_REAPER = 6, |
81 | IPOIB_MCAST_STARTED = 7, | ||
81 | 82 | ||
82 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 83 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
83 | 84 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ccaa0c387076..a2408d7ec598 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -533,8 +533,10 @@ void ipoib_mcast_join_task(void *dev_ptr) | |||
533 | } | 533 | } |
534 | 534 | ||
535 | if (!priv->broadcast) { | 535 | if (!priv->broadcast) { |
536 | priv->broadcast = ipoib_mcast_alloc(dev, 1); | 536 | struct ipoib_mcast *broadcast; |
537 | if (!priv->broadcast) { | 537 | |
538 | broadcast = ipoib_mcast_alloc(dev, 1); | ||
539 | if (!broadcast) { | ||
538 | ipoib_warn(priv, "failed to allocate broadcast group\n"); | 540 | ipoib_warn(priv, "failed to allocate broadcast group\n"); |
539 | mutex_lock(&mcast_mutex); | 541 | mutex_lock(&mcast_mutex); |
540 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) | 542 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) |
@@ -544,10 +546,11 @@ void ipoib_mcast_join_task(void *dev_ptr) | |||
544 | return; | 546 | return; |
545 | } | 547 | } |
546 | 548 | ||
547 | memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | 549 | spin_lock_irq(&priv->lock); |
550 | memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | ||
548 | sizeof (union ib_gid)); | 551 | sizeof (union ib_gid)); |
552 | priv->broadcast = broadcast; | ||
549 | 553 | ||
550 | spin_lock_irq(&priv->lock); | ||
551 | __ipoib_mcast_add(dev, priv->broadcast); | 554 | __ipoib_mcast_add(dev, priv->broadcast); |
552 | spin_unlock_irq(&priv->lock); | 555 | spin_unlock_irq(&priv->lock); |
553 | } | 556 | } |
@@ -601,6 +604,10 @@ int ipoib_mcast_start_thread(struct net_device *dev) | |||
601 | queue_work(ipoib_workqueue, &priv->mcast_task); | 604 | queue_work(ipoib_workqueue, &priv->mcast_task); |
602 | mutex_unlock(&mcast_mutex); | 605 | mutex_unlock(&mcast_mutex); |
603 | 606 | ||
607 | spin_lock_irq(&priv->lock); | ||
608 | set_bit(IPOIB_MCAST_STARTED, &priv->flags); | ||
609 | spin_unlock_irq(&priv->lock); | ||
610 | |||
604 | return 0; | 611 | return 0; |
605 | } | 612 | } |
606 | 613 | ||
@@ -611,6 +618,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | |||
611 | 618 | ||
612 | ipoib_dbg_mcast(priv, "stopping multicast thread\n"); | 619 | ipoib_dbg_mcast(priv, "stopping multicast thread\n"); |
613 | 620 | ||
621 | spin_lock_irq(&priv->lock); | ||
622 | clear_bit(IPOIB_MCAST_STARTED, &priv->flags); | ||
623 | spin_unlock_irq(&priv->lock); | ||
624 | |||
614 | mutex_lock(&mcast_mutex); | 625 | mutex_lock(&mcast_mutex); |
615 | clear_bit(IPOIB_MCAST_RUN, &priv->flags); | 626 | clear_bit(IPOIB_MCAST_RUN, &priv->flags); |
616 | cancel_delayed_work(&priv->mcast_task); | 627 | cancel_delayed_work(&priv->mcast_task); |
@@ -693,6 +704,14 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, | |||
693 | */ | 704 | */ |
694 | spin_lock(&priv->lock); | 705 | spin_lock(&priv->lock); |
695 | 706 | ||
707 | if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || | ||
708 | !priv->broadcast || | ||
709 | !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { | ||
710 | ++priv->stats.tx_dropped; | ||
711 | dev_kfree_skb_any(skb); | ||
712 | goto unlock; | ||
713 | } | ||
714 | |||
696 | mcast = __ipoib_mcast_find(dev, mgid); | 715 | mcast = __ipoib_mcast_find(dev, mgid); |
697 | if (!mcast) { | 716 | if (!mcast) { |
698 | /* Let's create a new send only group now */ | 717 | /* Let's create a new send only group now */ |
@@ -754,6 +773,7 @@ out: | |||
754 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); | 773 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); |
755 | } | 774 | } |
756 | 775 | ||
776 | unlock: | ||
757 | spin_unlock(&priv->lock); | 777 | spin_unlock(&priv->lock); |
758 | } | 778 | } |
759 | 779 | ||