void osm_nd_rcv_process(IN void *context, IN void *data)
{
	osm_sm_t *sm = context;
	osm_madw_t *p_madw = data;
	ib_node_desc_t *p_nd;
	ib_smp_t *p_smp;
	osm_node_t *p_node;
	ib_net64_t node_guid;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	CL_ASSERT(p_madw);

	p_smp = osm_madw_get_smp_ptr(p_madw);
	if (ib_smp_get_status(p_smp)) {
		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
			"MAD status 0x%x received\n",
			cl_ntoh16(ib_smp_get_status(p_smp)));
		goto Exit;
	}

	p_nd = ib_smp_get_payload_ptr(p_smp);

	/* Acquire the node object and add the node description. */
	node_guid = osm_madw_get_nd_context_ptr(p_madw)->node_guid;
	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
	p_node = osm_get_node_by_guid(sm->p_subn, node_guid);
	if (!p_node)
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0B01: "
			"NodeDescription received for nonexistent node "
			"0x%" PRIx64 "\n", cl_ntoh64(node_guid));
	else
		nd_rcv_process_nd(sm, p_node, p_nd);

	CL_PLOCK_RELEASE(sm->p_lock);
Exit:
	OSM_LOG_EXIT(sm->p_log);
}
/**********************************************************************
   Lock must be held on entry to this function.
   Return 1 if the caller is expected to send a change_detected event.
   this can not be done internally as the event needs the lock...
**********************************************************************/
static boolean_t si_rcv_process_existing(IN osm_sm_t * sm,
					 IN osm_node_t * p_node,
					 IN const osm_madw_t * p_madw)
{
	osm_switch_t *p_sw = p_node->sw;
	ib_switch_info_t *p_si;
	osm_si_context_t *p_si_context;
	ib_smp_t *p_smp;
	boolean_t is_change_detected = FALSE;

	OSM_LOG_ENTER(sm->p_log);

	CL_ASSERT(p_madw);

	p_smp = osm_madw_get_smp_ptr(p_madw);
	p_si = ib_smp_get_payload_ptr(p_smp);
	p_si_context = osm_madw_get_si_context_ptr(p_madw);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Received logical %cetResp()\n",
		p_si_context->set_method ? 'S' : 'G');

	osm_switch_set_switch_info(p_sw, p_si);

	if (p_si_context->light_sweep == TRUE && !p_si_context->set_method) {
		/* If state changed bit is on the mad was returned with an
		   error - signal a change to the state manager. */
		if (ib_smp_get_status(p_smp) != 0) {
			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
				"GetResp() received with error in light sweep. "
				"Commencing heavy sweep\n");
			is_change_detected = TRUE;
		} else if (ib_switch_info_get_state_change(p_si)) {
			osm_dump_switch_info_v2(sm->p_log, p_si, FILE_ID, OSM_LOG_DEBUG);
			is_change_detected = TRUE;
		}
	}

	OSM_LOG_EXIT(sm->p_log);
	return is_change_detected;
}
Esempio n. 3
0
void osm_ni_rcv_process(IN void *context, IN void *data)
{
	osm_sm_t *sm = context;
	osm_madw_t *p_madw = data;
	ib_node_info_t *p_ni;
	ib_smp_t *p_smp;
	osm_node_t *p_node;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	CL_ASSERT(p_madw);

	p_smp = osm_madw_get_smp_ptr(p_madw);
	p_ni = ib_smp_get_payload_ptr(p_smp);

	CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_NODE_INFO);

	if (PF(p_ni->node_guid == 0)) {
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D16: "
			"Got Zero Node GUID! Found on the directed route:\n");
		osm_dump_smp_dr_path_v2(sm->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
		goto Exit;
	}

	if (PF(p_ni->port_guid == 0)) {
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D17: "
			"Got Zero Port GUID! Found on the directed route:\n");
		osm_dump_smp_dr_path_v2(sm->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
		goto Exit;
	}

	if (ib_smp_get_status(p_smp)) {
		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
			"MAD status 0x%x received\n",
			cl_ntoh16(ib_smp_get_status(p_smp)));
		goto Exit;
	}

	/*
	   Determine if this node has already been discovered,
	   and process accordingly.
	   During processing of this node, hold the shared lock.
	 */

	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
	p_node = osm_get_node_by_guid(sm->p_subn, p_ni->node_guid);

	osm_dump_node_info_v2(sm->p_log, p_ni, FILE_ID, OSM_LOG_DEBUG);

	if (!p_node)
		ni_rcv_process_new(sm, p_madw);
	else
		ni_rcv_process_existing(sm, p_node, p_madw);

	CL_PLOCK_RELEASE(sm->p_lock);

Exit:
	OSM_LOG_EXIT(sm->p_log);
}
Esempio n. 4
0
/****f* opensm: SM/__osm_sm_mad_ctrl_rcv_callback
 * NAME
 * __osm_sm_mad_ctrl_rcv_callback
 *
 * DESCRIPTION
 * This is the callback from the transport layer for received MADs.
 *
 * SYNOPSIS
 */
static void
__osm_sm_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,
			       IN void *bind_context,
			       IN osm_madw_t * p_req_madw)
{
	osm_sm_mad_ctrl_t *p_ctrl = (osm_sm_mad_ctrl_t *) bind_context;
	ib_smp_t *p_smp;
	ib_net16_t status;

	OSM_LOG_ENTER(p_ctrl->p_log);

	CL_ASSERT(p_madw);

	/*
	   A MAD was received from the wire, possibly in response to a request.
	 */
	cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd);

	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs received\n",
		p_ctrl->p_stats->qp0_mads_rcvd);

	p_smp = osm_madw_get_smp_ptr(p_madw);

	/* if we are closing down simply do nothing */
	if (osm_exit_flag) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR,
			"Ignoring received mad - since we are exiting\n");

		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_DEBUG);

		/* retire the mad or put it back */
		if (ib_smp_is_response(p_smp) ||
		    (p_smp->method == IB_MAD_METHOD_TRAP_REPRESS)) {
			CL_ASSERT(p_madw->resp_expected == FALSE);
			__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
		} else if (p_madw->resp_expected == TRUE)
			__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
		else
			osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);

		goto Exit;
	}

	if (osm_log_is_active(p_ctrl->p_log, OSM_LOG_FRAMES))
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_FRAMES);

	if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
		status = ib_smp_get_status(p_smp);
	else
		status = p_smp->status;

	if (status != 0) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3111: "
			"Error status = 0x%X\n", status);
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
	}

	switch (p_smp->method) {
	case IB_MAD_METHOD_GET_RESP:
		CL_ASSERT(p_req_madw != NULL);
		__osm_sm_mad_ctrl_process_get_resp(p_ctrl, p_madw, p_req_madw);
		break;

	case IB_MAD_METHOD_GET:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_get(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_TRAP:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_trap(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_SET:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_set(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_SEND:
	case IB_MAD_METHOD_REPORT:
	case IB_MAD_METHOD_REPORT_RESP:
	case IB_MAD_METHOD_TRAP_REPRESS:
	default:
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3112: "
			"Unsupported method = 0x%X\n", p_smp->method);
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
}