aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_ib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_ib.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c87
1 files changed, 69 insertions, 18 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 68d72c6f7ffb..c1aad06eb4e9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -448,6 +448,13 @@ int ipoib_ib_dev_open(struct net_device *dev)
448 struct ipoib_dev_priv *priv = netdev_priv(dev); 448 struct ipoib_dev_priv *priv = netdev_priv(dev);
449 int ret; 449 int ret;
450 450
451 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) {
452 ipoib_warn(priv, "P_Key 0x%04x not found\n", priv->pkey);
453 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
454 return -1;
455 }
456 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
457
451 ret = ipoib_init_qp(dev); 458 ret = ipoib_init_qp(dev);
452 if (ret) { 459 if (ret) {
453 ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret); 460 ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret);
@@ -457,14 +464,14 @@ int ipoib_ib_dev_open(struct net_device *dev)
457 ret = ipoib_ib_post_receives(dev); 464 ret = ipoib_ib_post_receives(dev);
458 if (ret) { 465 if (ret) {
459 ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret); 466 ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);
460 ipoib_ib_dev_stop(dev); 467 ipoib_ib_dev_stop(dev, 1);
461 return -1; 468 return -1;
462 } 469 }
463 470
464 ret = ipoib_cm_dev_open(dev); 471 ret = ipoib_cm_dev_open(dev);
465 if (ret) { 472 if (ret) {
466 ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret); 473 ipoib_warn(priv, "ipoib_cm_dev_open returned %d\n", ret);
467 ipoib_ib_dev_stop(dev); 474 ipoib_ib_dev_stop(dev, 1);
468 return -1; 475 return -1;
469 } 476 }
470 477
@@ -516,7 +523,7 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush)
516 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { 523 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
517 mutex_lock(&pkey_mutex); 524 mutex_lock(&pkey_mutex);
518 set_bit(IPOIB_PKEY_STOP, &priv->flags); 525 set_bit(IPOIB_PKEY_STOP, &priv->flags);
519 cancel_delayed_work(&priv->pkey_task); 526 cancel_delayed_work(&priv->pkey_poll_task);
520 mutex_unlock(&pkey_mutex); 527 mutex_unlock(&pkey_mutex);
521 if (flush) 528 if (flush)
522 flush_workqueue(ipoib_workqueue); 529 flush_workqueue(ipoib_workqueue);
@@ -543,7 +550,7 @@ static int recvs_pending(struct net_device *dev)
543 return pending; 550 return pending;
544} 551}
545 552
546int ipoib_ib_dev_stop(struct net_device *dev) 553int ipoib_ib_dev_stop(struct net_device *dev, int flush)
547{ 554{
548 struct ipoib_dev_priv *priv = netdev_priv(dev); 555 struct ipoib_dev_priv *priv = netdev_priv(dev);
549 struct ib_qp_attr qp_attr; 556 struct ib_qp_attr qp_attr;
@@ -629,7 +636,8 @@ timeout:
629 /* Wait for all AHs to be reaped */ 636 /* Wait for all AHs to be reaped */
630 set_bit(IPOIB_STOP_REAPER, &priv->flags); 637 set_bit(IPOIB_STOP_REAPER, &priv->flags);
631 cancel_delayed_work(&priv->ah_reap_task); 638 cancel_delayed_work(&priv->ah_reap_task);
632 flush_workqueue(ipoib_workqueue); 639 if (flush)
640 flush_workqueue(ipoib_workqueue);
633 641
634 begin = jiffies; 642 begin = jiffies;
635 643
@@ -673,13 +681,24 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
673 return 0; 681 return 0;
674} 682}
675 683
676void ipoib_ib_dev_flush(struct work_struct *work) 684static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event)
677{ 685{
678 struct ipoib_dev_priv *cpriv, *priv = 686 struct ipoib_dev_priv *cpriv;
679 container_of(work, struct ipoib_dev_priv, flush_task);
680 struct net_device *dev = priv->dev; 687 struct net_device *dev = priv->dev;
688 u16 new_index;
689
690 mutex_lock(&priv->vlan_mutex);
681 691
682 if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) { 692 /*
693 * Flush any child interfaces too -- they might be up even if
694 * the parent is down.
695 */
696 list_for_each_entry(cpriv, &priv->child_intfs, list)
697 __ipoib_ib_dev_flush(cpriv, pkey_event);
698
699 mutex_unlock(&priv->vlan_mutex);
700
701 if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
683 ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); 702 ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
684 return; 703 return;
685 } 704 }
@@ -689,10 +708,32 @@ void ipoib_ib_dev_flush(struct work_struct *work)
689 return; 708 return;
690 } 709 }
691 710
711 if (pkey_event) {
712 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) {
713 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
714 ipoib_ib_dev_down(dev, 0);
715 ipoib_pkey_dev_delay_open(dev);
716 return;
717 }
718 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
719
720 /* restart QP only if P_Key index is changed */
721 if (new_index == priv->pkey_index) {
722 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
723 return;
724 }
725 priv->pkey_index = new_index;
726 }
727
692 ipoib_dbg(priv, "flushing\n"); 728 ipoib_dbg(priv, "flushing\n");
693 729
694 ipoib_ib_dev_down(dev, 0); 730 ipoib_ib_dev_down(dev, 0);
695 731
732 if (pkey_event) {
733 ipoib_ib_dev_stop(dev, 0);
734 ipoib_ib_dev_open(dev);
735 }
736
696 /* 737 /*
697 * The device could have been brought down between the start and when 738 * The device could have been brought down between the start and when
698 * we get here, don't bring it back up if it's not configured up 739 * we get here, don't bring it back up if it's not configured up
@@ -701,14 +742,24 @@ void ipoib_ib_dev_flush(struct work_struct *work)
701 ipoib_ib_dev_up(dev); 742 ipoib_ib_dev_up(dev);
702 ipoib_mcast_restart_task(&priv->restart_task); 743 ipoib_mcast_restart_task(&priv->restart_task);
703 } 744 }
745}
704 746
705 mutex_lock(&priv->vlan_mutex); 747void ipoib_ib_dev_flush(struct work_struct *work)
748{
749 struct ipoib_dev_priv *priv =
750 container_of(work, struct ipoib_dev_priv, flush_task);
706 751
707 /* Flush any child interfaces too */ 752 ipoib_dbg(priv, "Flushing %s\n", priv->dev->name);
708 list_for_each_entry(cpriv, &priv->child_intfs, list) 753 __ipoib_ib_dev_flush(priv, 0);
709 ipoib_ib_dev_flush(&cpriv->flush_task); 754}
710 755
711 mutex_unlock(&priv->vlan_mutex); 756void ipoib_pkey_event(struct work_struct *work)
757{
758 struct ipoib_dev_priv *priv =
759 container_of(work, struct ipoib_dev_priv, pkey_event_task);
760
761 ipoib_dbg(priv, "Flushing %s and restarting its QP\n", priv->dev->name);
762 __ipoib_ib_dev_flush(priv, 1);
712} 763}
713 764
714void ipoib_ib_dev_cleanup(struct net_device *dev) 765void ipoib_ib_dev_cleanup(struct net_device *dev)
@@ -736,7 +787,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
736void ipoib_pkey_poll(struct work_struct *work) 787void ipoib_pkey_poll(struct work_struct *work)
737{ 788{
738 struct ipoib_dev_priv *priv = 789 struct ipoib_dev_priv *priv =
739 container_of(work, struct ipoib_dev_priv, pkey_task.work); 790 container_of(work, struct ipoib_dev_priv, pkey_poll_task.work);
740 struct net_device *dev = priv->dev; 791 struct net_device *dev = priv->dev;
741 792
742 ipoib_pkey_dev_check_presence(dev); 793 ipoib_pkey_dev_check_presence(dev);
@@ -747,7 +798,7 @@ void ipoib_pkey_poll(struct work_struct *work)
747 mutex_lock(&pkey_mutex); 798 mutex_lock(&pkey_mutex);
748 if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) 799 if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))
749 queue_delayed_work(ipoib_workqueue, 800 queue_delayed_work(ipoib_workqueue,
750 &priv->pkey_task, 801 &priv->pkey_poll_task,
751 HZ); 802 HZ);
752 mutex_unlock(&pkey_mutex); 803 mutex_unlock(&pkey_mutex);
753 } 804 }
@@ -766,7 +817,7 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev)
766 mutex_lock(&pkey_mutex); 817 mutex_lock(&pkey_mutex);
767 clear_bit(IPOIB_PKEY_STOP, &priv->flags); 818 clear_bit(IPOIB_PKEY_STOP, &priv->flags);
768 queue_delayed_work(ipoib_workqueue, 819 queue_delayed_work(ipoib_workqueue,
769 &priv->pkey_task, 820 &priv->pkey_poll_task,
770 HZ); 821 HZ);
771 mutex_unlock(&pkey_mutex); 822 mutex_unlock(&pkey_mutex);
772 return 1; 823 return 1;