A deadlock will occur when SM with higher priority gets HANDOVER message during the state manager when it start polling the current MASTER SM.
Both sminfo_set_req() and osm_sm_state_mgr() use two locks - sm->p_lock and sm->state_lock but in reverse order. This scenario can lead to a deadlock. Signed-off-by: Alex Netes <[email protected]> --- opensm/osm_sminfo_rcv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/opensm/osm_sminfo_rcv.c b/opensm/osm_sminfo_rcv.c index eb7c17f..a0092a5 100644 --- a/opensm/osm_sminfo_rcv.c +++ b/opensm/osm_sminfo_rcv.c @@ -181,7 +181,7 @@ static void smi_rcv_process_set_request(IN osm_sm_t * sm, goto Exit; } - CL_PLOCK_EXCL_ACQUIRE(sm->p_lock); + CL_PLOCK_ACQUIRE(sm->p_lock); p_smi->guid = sm->p_subn->sm_port_guid; p_smi->act_count = cl_hton32(sm->p_subn->p_osm->stats.qp0_mads_sent); @@ -247,6 +247,8 @@ static void smi_rcv_process_set_request(IN osm_sm_t * sm, goto Exit; } + CL_PLOCK_RELEASE(sm->p_lock); + /* check legality of the needed transition in the SM state machine */ status = osm_sm_state_mgr_check_legality(sm, sm_signal); if (status != IB_SUCCESS) { @@ -260,7 +262,6 @@ static void smi_rcv_process_set_request(IN osm_sm_t * sm, OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F08: " "Error sending response (%s)\n", ib_get_err_str(status)); - CL_PLOCK_RELEASE(sm->p_lock); goto Exit; } @@ -280,10 +281,11 @@ static void smi_rcv_process_set_request(IN osm_sm_t * sm, "Received a STANDBY signal. Updating " "sm_state_mgr master_guid: 0x%016" PRIx64 "\n", cl_ntoh64(sm_smi->guid)); + CL_PLOCK_EXCL_ACQUIRE(sm->p_lock); sm->master_sm_guid = sm_smi->guid; + CL_PLOCK_RELEASE(sm->p_lock); } - CL_PLOCK_RELEASE(sm->p_lock); status = osm_sm_state_mgr_process(sm, sm_signal); if (status != IB_SUCCESS) -- 1.7.11.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
