static void
__osm_pi_rcv_set_sm(IN osm_sm_t * sm,
		    IN osm_physp_t * const p_physp)
{
	osm_bind_handle_t h_bind;
	osm_dr_path_t *p_dr_path;

	OSM_LOG_ENTER(sm->p_log);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
		"Setting IS_SM bit in port attributes\n");

	p_dr_path = osm_physp_get_dr_path_ptr(p_physp);
	h_bind = osm_dr_path_get_bind_handle(p_dr_path);

	/*
	   The 'IS_SM' bit isn't already set, so set it.
	 */
	osm_vendor_set_sm(h_bind, TRUE);

	OSM_LOG_EXIT(sm->p_log);
}
Exemple #2
0
ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
					 IN osm_sm_signal_t signal)
{
	ib_api_status_t status = IB_SUCCESS;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	/*
	 * The state lock prevents many race conditions from screwing
	 * up the state transition process.
	 */
	cl_spinlock_acquire(&sm->state_lock);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
		"Received signal %s in state %s\n",
		osm_get_sm_mgr_signal_str(signal),
		osm_get_sm_mgr_state_str(sm->p_subn->sm_state));

	switch (sm->p_subn->sm_state) {
	case IB_SMINFO_STATE_DISCOVERING:
		switch (signal) {
		case OSM_SM_SIGNAL_DISCOVERY_COMPLETED:
			/*
			 * Update the state of the SM to MASTER
			 */
			/* Turn on the first_time_master_sweep flag */
			sm->p_subn->first_time_master_sweep = TRUE;
			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
			osm_report_sm_state(sm);
			/*
			 * Make sure to set the subnet master_sm_base_lid
			 * to the sm_base_lid value
			 */
			sm->p_subn->master_sm_base_lid =
			    sm->p_subn->sm_base_lid;
			break;
		case OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
			/*
			 * Finished all discovery actions - move to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			/*
			 * Since another SM is doing the LFT config - we should not
			 * ignore the results of it
			 */
			sm->p_subn->ignore_existing_lfts = FALSE;

			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * Do nothing. We will discover it later on. If we already discovered
			 * this SM, and got the HANDOVER - this means the remote SM is of
			 * lower priority. In this case we will stop polling it (since it is
			 * a lower priority SM in STANDBY state).
			 */
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_STANDBY:
		switch (signal) {
		case OSM_SM_SIGNAL_POLLING_TIMEOUT:
		case OSM_SM_SIGNAL_DISCOVER:
			/*
			 * case 1: Polling timeout occured - this means that the Master SM
			 * is no longer alive.
			 * case 2: Got a signal to move to DISCOVERING
			 * Move to DISCOVERING state and start sweeping
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_DISCOVERING;
			osm_report_sm_state(sm);
			sm->p_subn->coming_out_of_standby = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_DISABLE:
			/*
			 * Update the state to NOT_ACTIVE
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_NOTACTIVE;
			osm_report_sm_state(sm);
			osm_vendor_set_sm(sm->mad_ctrl.h_bind, FALSE);
			break;
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * Update the state to MASTER, and start sweeping
			 * OPTIONAL: send ACKNOWLEDGE
			 */
			/* Turn on the first_time_master_sweep flag */
			sm->p_subn->first_time_master_sweep = TRUE;
			/*
			 * Turn on the force_heavy_sweep - we want a
			 * heavy sweep to occur on the first sweep of this SM.
			 */
			sm->p_subn->force_heavy_sweep = TRUE;

			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
			osm_report_sm_state(sm);
			/*
			 * Make sure to set the subnet master_sm_base_lid
			 * to the sm_base_lid value
			 */
			sm->p_subn->master_sm_base_lid =
			    sm->p_subn->sm_base_lid;
			sm->p_subn->coming_out_of_standby = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_ACKNOWLEDGE:
			/*
			 * Do nothing - already moved to STANDBY
			 */
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_NOTACTIVE:
		switch (signal) {
		case OSM_SM_SIGNAL_STANDBY:
			/*
			 * Update the state to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			sm_state_mgr_start_polling(sm);
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_MASTER:
		switch (signal) {
		case OSM_SM_SIGNAL_POLLING_TIMEOUT:
			/*
			 * We received a polling timeout - this means that we
			 * waited for a remote master sm to send us a handover,
			 * but didn't get it, and didn't get a response from
			 * that remote sm.
			 * We want to force a heavy sweep - hopefully this
			 * occurred because the remote sm died, and we'll find
			 * this out and configure the subnet after a heavy sweep.
			 * We also want to clear the p_polling_sm object - since
			 * we are done polling on that remote sm - we are
			 * sweeping again.
			 */
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * If we received a handover in a master state - then we
			 * want to force a heavy sweep. This means that either
			 * we are in a sweep currently - in this case - no
			 * change, or we are in idle state - since we
			 * recognized a master SM before - so we want to make a
			 * heavy sweep and reconfigure the new subnet.
			 * We also want to clear the p_polling_sm object - since
			 * we are done polling on that remote sm - we got a
			 * handover from it.
			 */
			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
				"Forcing heavy sweep. "
				"Received OSM_SM_SIGNAL_HANDOVER or OSM_SM_SIGNAL_POLLING_TIMEOUT\n");
			sm->p_polling_sm = NULL;
			sm->p_subn->force_heavy_sweep = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_HANDOVER_SENT:
			/*
			 * Just sent a HANDOVER signal - move to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_WAIT_FOR_HANDOVER:
			/*
			 * We found a remote master SM, and we are waiting for
			 * it to handover the mastership to us. Need to start
			 * polling that SM, to make sure it is alive, if it
			 * isn't - then we should move back to discovering,
			 * since something must have happened to it.
			 */
			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_DISCOVER:
			sm->p_subn->sm_state = IB_SMINFO_STATE_DISCOVERING;
			osm_report_sm_state(sm);
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	default:
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3208: "
			"Invalid state %s\n",
			osm_get_sm_mgr_state_str(sm->p_subn->sm_state));

	}

	cl_spinlock_release(&sm->state_lock);

	OSM_LOG_EXIT(sm->p_log);
	return status;
}