diff options
author | Leonid Arsh <leonida@voltaire.com> | 2006-03-23 12:52:51 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-24 18:47:30 -0500 |
commit | 7a343d4c46bc59fe617f968e996ce2fd67c5d179 (patch) | |
tree | bc58caefafd0e1228266a0928f5d70aa5f262cf4 /drivers/infiniband | |
parent | 192daa18dd7bfcaeb092a2ef928135745f2e6883 (diff) |
IPoIB: P_Key change event handling
This patch causes the network interface to respond to P_Key change
events correctly. As a result, you'll see a child interface in the
"RUNNING" state (netif_carrier_on()) only when the corresponding P_Key
is configured by the SM. When SM removes a P_Key, the "RUNNING" state
will be disabled for the corresponding network interface. To
implement this, I added IB_EVENT_PKEY_CHANGE event handling. To
prevent flushing the device before the device is open by the "delay
open" mechanism, I added an additional device flag called
IPOIB_FLAG_INITIALIZED.
This also prevents the child network interface from trying to join to
multicast groups until the PKEY is configured. We used to get error
messages like:
ib0.f2f2: couldn't attach QP to multicast group ff12:401b:f2f2:0:0:0:ffff:ffff
in this case. To fix this, I just check IPOIB_FLAG_OPER_UP flag in
ipoib_set_mcast_list().
Signed-off-by: Leonid Arsh <leonida@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 15 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 42 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 5 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 1 |
4 files changed, 44 insertions, 19 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 1251f86ec856..b640107fb732 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -72,13 +72,14 @@ enum { | |||
72 | IPOIB_MAX_MCAST_QUEUE = 3, | 72 | IPOIB_MAX_MCAST_QUEUE = 3, |
73 | 73 | ||
74 | IPOIB_FLAG_OPER_UP = 0, | 74 | IPOIB_FLAG_OPER_UP = 0, |
75 | IPOIB_FLAG_ADMIN_UP = 1, | 75 | IPOIB_FLAG_INITIALIZED = 1, |
76 | IPOIB_PKEY_ASSIGNED = 2, | 76 | IPOIB_FLAG_ADMIN_UP = 2, |
77 | IPOIB_PKEY_STOP = 3, | 77 | IPOIB_PKEY_ASSIGNED = 3, |
78 | IPOIB_FLAG_SUBINTERFACE = 4, | 78 | IPOIB_PKEY_STOP = 4, |
79 | IPOIB_MCAST_RUN = 5, | 79 | IPOIB_FLAG_SUBINTERFACE = 5, |
80 | IPOIB_STOP_REAPER = 6, | 80 | IPOIB_MCAST_RUN = 6, |
81 | IPOIB_MCAST_STARTED = 7, | 81 | IPOIB_STOP_REAPER = 7, |
82 | IPOIB_MCAST_STARTED = 8, | ||
82 | 83 | ||
83 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 84 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
84 | 85 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f2be500f62c8..ed65202878d8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -423,13 +423,33 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
423 | clear_bit(IPOIB_STOP_REAPER, &priv->flags); | 423 | clear_bit(IPOIB_STOP_REAPER, &priv->flags); |
424 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ); | 424 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ); |
425 | 425 | ||
426 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | ||
427 | |||
426 | return 0; | 428 | return 0; |
427 | } | 429 | } |
428 | 430 | ||
431 | static void ipoib_pkey_dev_check_presence(struct net_device *dev) | ||
432 | { | ||
433 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
434 | u16 pkey_index = 0; | ||
435 | |||
436 | if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) | ||
437 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
438 | else | ||
439 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
440 | } | ||
441 | |||
429 | int ipoib_ib_dev_up(struct net_device *dev) | 442 | int ipoib_ib_dev_up(struct net_device *dev) |
430 | { | 443 | { |
431 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 444 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
432 | 445 | ||
446 | ipoib_pkey_dev_check_presence(dev); | ||
447 | |||
448 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { | ||
449 | ipoib_dbg(priv, "PKEY is not assigned.\n"); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
433 | set_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | 453 | set_bit(IPOIB_FLAG_OPER_UP, &priv->flags); |
434 | 454 | ||
435 | return ipoib_mcast_start_thread(dev); | 455 | return ipoib_mcast_start_thread(dev); |
@@ -483,6 +503,8 @@ int ipoib_ib_dev_stop(struct net_device *dev) | |||
483 | struct ipoib_tx_buf *tx_req; | 503 | struct ipoib_tx_buf *tx_req; |
484 | int i; | 504 | int i; |
485 | 505 | ||
506 | clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | ||
507 | |||
486 | /* | 508 | /* |
487 | * Move our QP to the error state and then reinitialize in | 509 | * Move our QP to the error state and then reinitialize in |
488 | * when all work requests have completed or have been flushed. | 510 | * when all work requests have completed or have been flushed. |
@@ -587,8 +609,15 @@ void ipoib_ib_dev_flush(void *_dev) | |||
587 | struct net_device *dev = (struct net_device *)_dev; | 609 | struct net_device *dev = (struct net_device *)_dev; |
588 | struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv; | 610 | struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv; |
589 | 611 | ||
590 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) | 612 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) { |
613 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); | ||
614 | return; | ||
615 | } | ||
616 | |||
617 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { | ||
618 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n"); | ||
591 | return; | 619 | return; |
620 | } | ||
592 | 621 | ||
593 | ipoib_dbg(priv, "flushing\n"); | 622 | ipoib_dbg(priv, "flushing\n"); |
594 | 623 | ||
@@ -632,17 +661,6 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
632 | * change async notification is available. | 661 | * change async notification is available. |
633 | */ | 662 | */ |
634 | 663 | ||
635 | static void ipoib_pkey_dev_check_presence(struct net_device *dev) | ||
636 | { | ||
637 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
638 | u16 pkey_index = 0; | ||
639 | |||
640 | if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) | ||
641 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
642 | else | ||
643 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
644 | } | ||
645 | |||
646 | void ipoib_pkey_poll(void *dev_ptr) | 664 | void ipoib_pkey_poll(void *dev_ptr) |
647 | { | 665 | { |
648 | struct net_device *dev = dev_ptr; | 666 | struct net_device *dev = dev_ptr; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 37da8d3dc388..53a32f65788d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -736,6 +736,11 @@ static void ipoib_set_mcast_list(struct net_device *dev) | |||
736 | { | 736 | { |
737 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 737 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
738 | 738 | ||
739 | if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) { | ||
740 | ipoib_dbg(priv, "IPOIB_FLAG_OPER_UP not set"); | ||
741 | return; | ||
742 | } | ||
743 | |||
739 | queue_work(ipoib_workqueue, &priv->restart_task); | 744 | queue_work(ipoib_workqueue, &priv->restart_task); |
740 | } | 745 | } |
741 | 746 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index a35b798b8128..5f0388027b25 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -252,6 +252,7 @@ void ipoib_event(struct ib_event_handler *handler, | |||
252 | container_of(handler, struct ipoib_dev_priv, event_handler); | 252 | container_of(handler, struct ipoib_dev_priv, event_handler); |
253 | 253 | ||
254 | if (record->event == IB_EVENT_PORT_ERR || | 254 | if (record->event == IB_EVENT_PORT_ERR || |
255 | record->event == IB_EVENT_PKEY_CHANGE || | ||
255 | record->event == IB_EVENT_PORT_ACTIVE || | 256 | record->event == IB_EVENT_PORT_ACTIVE || |
256 | record->event == IB_EVENT_LID_CHANGE || | 257 | record->event == IB_EVENT_LID_CHANGE || |
257 | record->event == IB_EVENT_SM_CHANGE) { | 258 | record->event == IB_EVENT_SM_CHANGE) { |