/********************************************************************** * * FUNCTION * cs_psema * * DESCRIPTION * Decrement a semaphore (wait or take operation) * * INPUTS * handle - A pointer to a semaphore object filled in by the * cs_sema_create() call. * * OUTPUTS * Status_t - On success VSTATUS_OK is returned, otherwise * the cause of the error. * * RESPONSIBLE ENGINEER: * CS Developers. * * HISTORY * * NAME DATE REMARKS * MGR 03/14/02 Initial creation of function. * MGR 04/18/02 PR1728. vs_psema should return VSTATUS_AGAIN * error code, if thread has been killed. * **********************************************************************/ Status_t cs_psema_wait (Sema_t *handle, int timeout) { Status_t rc=VSTATUS_OK; IB_ENTER (function, (unint)handle, 0U, 0U, 0U); /* Validate handle */ if (handle == (Sema_t *) 0) { IB_LOG_ERROR0 ("NULL handle pointer"); IB_EXIT (function, VSTATUS_ILLPARM); return VSTATUS_ILLPARM; } if (handle->magic != SEMAPHORE_MAGIC) { IB_LOG_ERRORX ("Invalid semaphore specified:", handle->magic); IB_EXIT (function, VSTATUS_NXIO); return VSTATUS_NXIO; } if (timeout == CS_SEMA_WAIT_FOREVER) { return(cs_psema(handle)); } else { #ifdef __VXWORKS__ if (ERROR == semTake(handle->semId, timeout*sysClkRateGet())) { IB_LOG_WARN0("Timed out trying to take semaphore"); rc = VSTATUS_NXIO; } else { handle->count--; } #elif defined (__LINUX__) // LINUX USER SEMA int i=0, rc=-1; do { rc = sem_trywait((sem_t *)&handle->osdSema); ++i; (void)vs_thread_sleep(VTIMER_1S); } while (i<timeout && rc); if (rc != 0) { IB_LOG_WARN0("Timed out trying to take semaphore"); rc = VSTATUS_NXIO; } #endif } IB_EXIT (function, rc); return rc; }
// This requires the caller to have invoked pm_initialize_config prior to this // call. // It completes PM initialization and then starts the actual PM. void unified_sm_pm(uint32_t argc, uint8_t ** argv) { mai_set_default_pkey(STL_DEFAULT_FM_PKEY); if (pm_config.debug_rmpp) if3RmppDebugOn(); IB_LOG_INFO("Device: ", pm_config.hca); IB_LOG_INFO("Port: ", pm_config.port); pm_compute_pool_size(); // compute sizes for PM resources if (!pm_config.start) { IB_LOG_WARN0("PM not configured to start"); } else { (void)sm_wait_ready(VIEO_PM_MOD_ID); (void)pm_main(); } }
Status_t sm_check_Master() { Status_t status; STL_SM_INFO theirSmInfo; STL_PORT_INFO portInfo; uint8_t path[64]; static uint32_t fsmCheckMasterFailed=0; // count of fails to check master static uint32_t fsmMultMaxFail = 1; // multiplier for sm_config.master_ping_max_fail IB_ENTER(__func__, 0, 0, 0, 0); (void)memset((void *)path, 0, 64); if ((status = SM_Get_PortInfo(fd_sminfo, 1<<24, path, &portInfo)) != VSTATUS_OK) { IB_LOG_ERRORRC("failed to get master SM Lid from my PortInfo, rc:", status); // having a local problem // reset count, must be healthy before we can consider becoming master fsmCheckMasterFailed = 0; goto stay_standby; } if (portInfo.LID == 0 || portInfo.MasterSMLID == 0 || portInfo.PortStates.s.PortState != IB_PORT_ACTIVE ) { if (smDebugPerf) { if (portInfo.PortStates.s.PortState != IB_PORT_ACTIVE) { IB_LOG_INFINI_INFO("our portInfo indicates state not active; portState=", (int)portInfo.PortStates.s.PortState); } else if (portInfo.MasterSMLID == 0) { IB_LOG_INFINI_INFOX("our portInfo smLid is not set yet; Lid=", portInfo.LID); } } // stay in standby until link comes up if (portInfo.PortStates.s.PortState > IB_PORT_DOWN) { IB_LOG_WARN0("Switching to DISCOVERY state; Local port uninitialized"); goto discovering; } goto stay_standby; } // make sure we aren't trying to talk to ourself during the handover window if (portInfo.LID == portInfo.MasterSMLID) { // we're talking to ourself. if a master SM doesn't come along and // reprogram our SM LID in the timeout period, attempt a discovery. // Since for large fabrics, the master can take some time to program // our LID, use a higher upper limit for failure count to give the // master enough time to program our SM LID. fsmMultMaxFail = 2; if (++fsmCheckMasterFailed >= fsmMultMaxFail * sm_config.master_ping_max_fail) { IB_LOG_WARN0("Switching to DISCOVERY state; Timed out waiting for SM LID to get reprogrammed"); goto discovering; } if (smDebugPerf) { IB_LOG_INFINI_INFOX("our portInfo smLid is not set yet; smLid=", portInfo.MasterSMLID); } goto stay_standby; // not yet at threshold } sm_topop->slid = portInfo.LID; sm_topop->dlid = portInfo.MasterSMLID; if ((status = SM_Get_SMInfo(fd_sminfo, 0, NULL, &theirSmInfo)) != VSTATUS_OK) { if (++fsmCheckMasterFailed >= fsmMultMaxFail * sm_config.master_ping_max_fail) { IB_LOG_WARNX("Switching to DISCOVERY state; Failed to get SmInfo from master SM at LID:", portInfo.MasterSMLID); goto discovering; } else { IB_LOG_INFINI_INFO_FMT(__func__, "failed to get SmInfo from master SM at LID[0x%X], retry count=%d", portInfo.MasterSMLID, fsmCheckMasterFailed); goto stay_standby; // not yet at threshold } } sm_saw_another_sm = TRUE; /* * PR 105313 - restart results in 2 standby SMs * Must check the state we get back to make sure master is still master */ if (theirSmInfo.u.s.SMStateCurrent != SM_STATE_MASTER) { IB_LOG_WARN_FMT(__func__, "SmInfo from SM at SMLID[0x%X] indicates SM is no longer master, switching to DISCOVERY state", portInfo.MasterSMLID); goto discovering; } // all OK, save data about master, reset fail count and threshold sm_topop->sm_count = theirSmInfo.ActCount; sm_topop->sm_key = theirSmInfo.SM_Key; fsmCheckMasterFailed = 0; fsmMultMaxFail = 1; if (smDebugPerf) { IB_LOG_INFINI_INFO_FMT(__func__, "Master SM["FMT_U64"] at LID=0x%x has priority[%d] and smKey ["FMT_U64"]", theirSmInfo.PortGUID, portInfo.MasterSMLID, theirSmInfo.u.s.Priority, theirSmInfo.SM_Key); } stay_standby: status = VSTATUS_OK; done: IB_EXIT(__func__, status); return(status); discovering: // reset count and threshold in case stay standby fsmCheckMasterFailed = 0; fsmMultMaxFail = 1; status = VSTATUS_BAD; goto done; }