IB/hfi1: Harden state transition to Armed and Active

There is a window that allows other threads to read state of
'host_link_state' as a new, before the hardware actual state is set.
This patch closes the window by indicating a new state only after
hardware transition is complete.

Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Alex Estrin <alex.estrin@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Alex Estrin
2017-07-29 08:43:20 -07:00
committed by Doug Ledford
parent f13a6e5e2e
commit 5efd40cad4

View File

@@ -10602,16 +10602,15 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
break; break;
} }
ppd->host_link_state = HLS_UP_ARMED;
set_logical_state(dd, LSTATE_ARMED); set_logical_state(dd, LSTATE_ARMED);
ret = wait_logical_linkstate(ppd, IB_PORT_ARMED, 1000); ret = wait_logical_linkstate(ppd, IB_PORT_ARMED, 1000);
if (ret) { if (ret) {
/* logical state didn't change, stay at init */
ppd->host_link_state = HLS_UP_INIT;
dd_dev_err(dd, dd_dev_err(dd,
"%s: logical state did not change to ARMED\n", "%s: logical state did not change to ARMED\n",
__func__); __func__);
break;
} }
ppd->host_link_state = HLS_UP_ARMED;
/* /*
* The simulator does not currently implement SMA messages, * The simulator does not currently implement SMA messages,
* so neighbor_normal is not set. Set it here when we first * so neighbor_normal is not set. Set it here when we first
@@ -10624,18 +10623,16 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
if (ppd->host_link_state != HLS_UP_ARMED) if (ppd->host_link_state != HLS_UP_ARMED)
goto unexpected; goto unexpected;
ppd->host_link_state = HLS_UP_ACTIVE;
set_logical_state(dd, LSTATE_ACTIVE); set_logical_state(dd, LSTATE_ACTIVE);
ret = wait_logical_linkstate(ppd, IB_PORT_ACTIVE, 1000); ret = wait_logical_linkstate(ppd, IB_PORT_ACTIVE, 1000);
if (ret) { if (ret) {
/* logical state didn't change, stay at armed */
ppd->host_link_state = HLS_UP_ARMED;
dd_dev_err(dd, dd_dev_err(dd,
"%s: logical state did not change to ACTIVE\n", "%s: logical state did not change to ACTIVE\n",
__func__); __func__);
} else { } else {
/* tell all engines to go running */ /* tell all engines to go running */
sdma_all_running(dd); sdma_all_running(dd);
ppd->host_link_state = HLS_UP_ACTIVE;
/* Signal the IB layer that the port has went active */ /* Signal the IB layer that the port has went active */
event.device = &dd->verbs_dev.rdi.ibdev; event.device = &dd->verbs_dev.rdi.ibdev;