diff options
author | Todd Rimmer <todd.rimmer@qlogic.com> | 2012-05-02 14:35:18 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-05-14 15:38:28 -0400 |
commit | 4ccf28a26c981bcc6f938a7ea293a623d2d66d7b (patch) | |
tree | 63eb2386d413a526ca8458d6f4508c0562a51cc9 /drivers/infiniband | |
parent | bb77a077232e78476d7bc39c080f9e6685cbfd3c (diff) |
IB/qib: Correct ordering of reregister vs. port active events
When a port first goes active with SMA Set(PortInfo) and reregister
bit set, the driver sends up the reregister event followed by a port
active event.
The problem is that in response to reregister event most apps try to
issue a SA query of some sort, but that fails because port is not
active.
The qib driver needs to a trivial change to correct this behavior.
This issue has been there for a while; however the recent serdes work
has probably made the delay between the reregister event and the
active event larger and hence opened the race far enough so that its
being seen more often.
The patch also changes the clientrereg local to a u8 and saves off the
rereg bit into it. The code following the nested subn_get_portinfo()
now restores that bit per o14-12.2.1 with a logical OR from that copy.
Reviewed-by: Ram Vepa <ram.vepa@qlogic.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_mad.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index c4ff788823b5..9292c76380fd 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c | |||
@@ -631,7 +631,7 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, | |||
631 | struct qib_devdata *dd; | 631 | struct qib_devdata *dd; |
632 | struct qib_pportdata *ppd; | 632 | struct qib_pportdata *ppd; |
633 | struct qib_ibport *ibp; | 633 | struct qib_ibport *ibp; |
634 | char clientrereg = 0; | 634 | u8 clientrereg = (pip->clientrereg_resv_subnetto & 0x80); |
635 | unsigned long flags; | 635 | unsigned long flags; |
636 | u16 lid, smlid; | 636 | u16 lid, smlid; |
637 | u8 lwe; | 637 | u8 lwe; |
@@ -781,12 +781,6 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, | |||
781 | 781 | ||
782 | ibp->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; | 782 | ibp->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; |
783 | 783 | ||
784 | if (pip->clientrereg_resv_subnetto & 0x80) { | ||
785 | clientrereg = 1; | ||
786 | event.event = IB_EVENT_CLIENT_REREGISTER; | ||
787 | ib_dispatch_event(&event); | ||
788 | } | ||
789 | |||
790 | /* | 784 | /* |
791 | * Do the port state change now that the other link parameters | 785 | * Do the port state change now that the other link parameters |
792 | * have been set. | 786 | * have been set. |
@@ -844,10 +838,15 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, | |||
844 | smp->status |= IB_SMP_INVALID_FIELD; | 838 | smp->status |= IB_SMP_INVALID_FIELD; |
845 | } | 839 | } |
846 | 840 | ||
841 | if (clientrereg) { | ||
842 | event.event = IB_EVENT_CLIENT_REREGISTER; | ||
843 | ib_dispatch_event(&event); | ||
844 | } | ||
845 | |||
847 | ret = subn_get_portinfo(smp, ibdev, port); | 846 | ret = subn_get_portinfo(smp, ibdev, port); |
848 | 847 | ||
849 | if (clientrereg) | 848 | /* restore re-reg bit per o14-12.2.1 */ |
850 | pip->clientrereg_resv_subnetto |= 0x80; | 849 | pip->clientrereg_resv_subnetto |= clientrereg; |
851 | 850 | ||
852 | goto get_only; | 851 | goto get_only; |
853 | 852 | ||