config root man

Current Path : /usr/src/contrib/ofed/management/opensm/opensm/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //usr/src/contrib/ofed/management/opensm/opensm/osm_sa_mad_ctrl.c

/*
 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

/*
 * Abstract:
 *    Implementation of osm_sa_mad_ctrl_t.
 * This object is part of the SA object.
 */

#if HAVE_CONFIG_H
#  include <config.h>
#endif				/* HAVE_CONFIG_H */

#include <string.h>
#include <complib/cl_debug.h>
#include <iba/ib_types.h>
#include <vendor/osm_vendor_api.h>
#include <opensm/osm_sa_mad_ctrl.h>
#include <opensm/osm_msgdef.h>
#include <opensm/osm_helper.h>
#include <opensm/osm_sa.h>

/****f* opensm: SA/__osm_sa_mad_ctrl_disp_done_callback
 * NAME
 * __osm_sa_mad_ctrl_disp_done_callback
 *
 * DESCRIPTION
 * This function is the Dispatcher callback that indicates
 * a received MAD has been processed by the recipient.
 *
 * SYNOPSIS
 */
static void
__osm_sa_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
{
	osm_sa_mad_ctrl_t *const p_ctrl = (osm_sa_mad_ctrl_t *) context;
	osm_madw_t *const p_madw = (osm_madw_t *) p_data;

	OSM_LOG_ENTER(p_ctrl->p_log);

	CL_ASSERT(p_madw);
	/*
	   Return the MAD & wrapper to the pool.
	 */
	osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
	OSM_LOG_EXIT(p_ctrl->p_log);
}

/************/

/****f* opensm: SA/__osm_sa_mad_ctrl_process
 * NAME
 * __osm_sa_mad_ctrl_process
 *
 * DESCRIPTION
 * This function handles known methods for received MADs.
 *
 * SYNOPSIS
 */
static void
__osm_sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * const p_ctrl,
			  IN osm_madw_t * p_madw)
{
	ib_sa_mad_t *p_sa_mad;
	cl_status_t status;
	cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
	uint64_t last_dispatched_msg_queue_time_msec;
	uint32_t num_messages;

	OSM_LOG_ENTER(p_ctrl->p_log);

	/*
	   If the dispatcher is showing us that it is overloaded
	   there is no point in placing the request in. We should instead provide
	   immediate response - IB_RESOURCE_BUSY
	   But how do we know?
	   The dispatcher reports back the number of outstanding messages and the
	   time the last message stayed in the queue.
	   HACK: Actually, we cannot send a mad from within the receive callback;
	   thus - we will just drop it.
	 */
	cl_disp_get_queue_status(p_ctrl->h_disp,
				 &num_messages,
				 &last_dispatched_msg_queue_time_msec);
	if ((num_messages > 1) &&
	    (p_ctrl->p_subn->opt.max_msg_fifo_timeout) &&
	    (last_dispatched_msg_queue_time_msec >
	     p_ctrl->p_subn->opt.max_msg_fifo_timeout)) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_INFO,
			/*             "Responding BUSY status since the dispatcher is already" */
			"Dropping MAD since the dispatcher is already"
			" overloaded with %u messages and queue time of:"
			"%" PRIu64 "[msec]\n",
			num_messages, last_dispatched_msg_queue_time_msec);

		/* send a busy response */
		/* osm_sa_send_error(p_ctrl->p_resp, p_madw, IB_RESOURCE_BUSY); */

		/* return the request to the pool */
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);

		goto Exit;
	}

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);

	/*
	   Note that attr_id (like the rest of the MAD) is in
	   network byte order.
	 */
	switch (p_sa_mad->attr_id) {
	case IB_MAD_ATTR_CLASS_PORT_INFO:
		msg_id = OSM_MSG_MAD_CLASS_PORT_INFO;
		break;

	case IB_MAD_ATTR_NODE_RECORD:
		msg_id = OSM_MSG_MAD_NODE_RECORD;
		break;

	case IB_MAD_ATTR_PORTINFO_RECORD:
		msg_id = OSM_MSG_MAD_PORTINFO_RECORD;
		break;

	case IB_MAD_ATTR_LINK_RECORD:
		msg_id = OSM_MSG_MAD_LINK_RECORD;
		break;

	case IB_MAD_ATTR_SMINFO_RECORD:
		msg_id = OSM_MSG_MAD_SMINFO_RECORD;
		break;

	case IB_MAD_ATTR_SERVICE_RECORD:
		msg_id = OSM_MSG_MAD_SERVICE_RECORD;
		break;

	case IB_MAD_ATTR_PATH_RECORD:
		msg_id = OSM_MSG_MAD_PATH_RECORD;
		break;

	case IB_MAD_ATTR_MCMEMBER_RECORD:
		msg_id = OSM_MSG_MAD_MCMEMBER_RECORD;
		break;

	case IB_MAD_ATTR_INFORM_INFO:
		msg_id = OSM_MSG_MAD_INFORM_INFO;
		break;

	case IB_MAD_ATTR_VLARB_RECORD:
		msg_id = OSM_MSG_MAD_VL_ARB_RECORD;
		break;

	case IB_MAD_ATTR_SLVL_RECORD:
		msg_id = OSM_MSG_MAD_SLVL_TBL_RECORD;
		break;

	case IB_MAD_ATTR_PKEY_TBL_RECORD:
		msg_id = OSM_MSG_MAD_PKEY_TBL_RECORD;
		break;

	case IB_MAD_ATTR_LFT_RECORD:
		msg_id = OSM_MSG_MAD_LFT_RECORD;
		break;

	case IB_MAD_ATTR_GUIDINFO_RECORD:
		msg_id = OSM_MSG_MAD_GUIDINFO_RECORD;
		break;

	case IB_MAD_ATTR_INFORM_INFO_RECORD:
		msg_id = OSM_MSG_MAD_INFORM_INFO_RECORD;
		break;

	case IB_MAD_ATTR_SWITCH_INFO_RECORD:
		msg_id = OSM_MSG_MAD_SWITCH_INFO_RECORD;
		break;

	case IB_MAD_ATTR_MFT_RECORD:
		msg_id = OSM_MSG_MAD_MFT_RECORD;
		break;

#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
	case IB_MAD_ATTR_MULTIPATH_RECORD:
		msg_id = OSM_MSG_MAD_MULTIPATH_RECORD;
		break;
#endif

	default:
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A01: "
			"Unsupported attribute = 0x%X\n",
			cl_ntoh16(p_sa_mad->attr_id));
		osm_dump_sa_mad(p_ctrl->p_log, p_sa_mad, OSM_LOG_ERROR);
	}

	if (msg_id != CL_DISP_MSGID_NONE) {
		/*
		   Post this MAD to the dispatcher for asynchronous
		   processing by the appropriate controller.
		 */

		OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
			"Posting Dispatcher message %s\n",
			osm_get_disp_msg_str(msg_id));

		status = cl_disp_post(p_ctrl->h_disp,
				      msg_id,
				      p_madw,
				      __osm_sa_mad_ctrl_disp_done_callback,
				      p_ctrl);

		if (status != CL_SUCCESS) {
			OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A02: "
				"Dispatcher post message failed (%s) for attribute = 0x%X\n",
				CL_STATUS_MSG(status),
				cl_ntoh16(p_sa_mad->attr_id));

			osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
			goto Exit;
		}
	} else {
		/*
		   There is an unknown MAD attribute type for which there is
		   no recipient.  Simply retire the MAD here.
		 */
		cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
	}

Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
}

/*
 * PARAMETERS
 *
 * RETURN VALUES
 *
 * NOTES
 *
 * SEE ALSO
 *********/

/****f* opensm: SA/__osm_sa_mad_ctrl_rcv_callback
 * NAME
 * __osm_sa_mad_ctrl_rcv_callback
 *
 * DESCRIPTION
 * This is the callback from the transport layer for received MADs.
 *
 * SYNOPSIS
 */
static void
__osm_sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,
			       IN void *bind_context,
			       IN osm_madw_t * p_req_madw)
{
	osm_sa_mad_ctrl_t *p_ctrl = (osm_sa_mad_ctrl_t *) bind_context;
	ib_sa_mad_t *p_sa_mad;

	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->sa_mads_rcvd);

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

	/*
	 * C15-0.1.3 requires not responding to any MAD if the SM is
	 * not in active state!
	 * We will not respond if the sm_state is not MASTER, or if the
	 * first_time_master_sweep flag (of the subnet) is TRUE - this
	 * flag indicates that the master still didn't finish its first
	 * sweep, so the subnet is not up and stable yet.
	 */
	if (p_ctrl->p_subn->sm_state != IB_SMINFO_STATE_MASTER) {
		cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
		OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
			"Received SA MAD while SM not MASTER. MAD ignored\n");
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}
	if (p_ctrl->p_subn->first_time_master_sweep == TRUE) {
		cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
		OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
			"Received SA MAD while SM in first sweep. MAD ignored\n");
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);

	if (osm_log_is_active(p_ctrl->p_log, OSM_LOG_FRAMES))
		osm_dump_sa_mad(p_ctrl->p_log, p_sa_mad, OSM_LOG_FRAMES);

	/*
	 * C15-0.1.5 - Table 185: SA Header - p884
	 * SM_key should be either 0 or match the current SM_Key
	 * otherwise discard the MAD.
	 */
	if ((p_sa_mad->sm_key != 0) &&
	    (p_sa_mad->sm_key != p_ctrl->p_subn->opt.sa_key)) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A04: "
			"Non-Zero SA MAD SM_Key: 0x%" PRIx64 " != SM_Key: 0x%"
			PRIx64 "; MAD ignored\n", cl_ntoh64(p_sa_mad->sm_key),
			cl_ntoh64(p_ctrl->p_subn->opt.sa_key)
		    );
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}

	switch (p_sa_mad->method) {
	case IB_MAD_METHOD_REPORT_RESP:
		/* we do not really do anything with report represses -
		   just retire the transaction */
		OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
			"Received Report Repress. Retiring the transaction\n");

		if (p_req_madw)
			osm_mad_pool_put(p_ctrl->p_mad_pool, p_req_madw);
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);

		break;

	case IB_MAD_METHOD_GET:
	case IB_MAD_METHOD_GETTABLE:
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
	case IB_MAD_METHOD_GETMULTI:
#endif
	case IB_MAD_METHOD_SET:
	case IB_MAD_METHOD_DELETE:
		__osm_sa_mad_ctrl_process(p_ctrl, p_madw);
		break;

	default:
		cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A05: "
			"Unsupported method = 0x%X\n", p_sa_mad->method);
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
}

/*
 * PARAMETERS
 *
 * RETURN VALUES
 *
 * NOTES
 *
 * SEE ALSO
 *********/

/****f* opensm: SA/__osm_sa_mad_ctrl_send_err_callback
 * NAME
 * __osm_sa_mad_ctrl_send_err_callback
 *
 * DESCRIPTION
 * This is the callback from the transport layer for send errors
 * on MADs that were expecting a response.
 *
 * SYNOPSIS
 */
static void
__osm_sa_mad_ctrl_send_err_callback(IN void *bind_context,
				    IN osm_madw_t * p_madw)
{
	osm_sa_mad_ctrl_t *p_ctrl = (osm_sa_mad_ctrl_t *) bind_context;
	cl_status_t status;

	OSM_LOG_ENTER(p_ctrl->p_log);

	OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A06: "
		"MAD transaction completed in error\n");

	/*
	   We should never be here since the SA never originates a request.
	   Unless we generated a Report(Notice)
	 */

	CL_ASSERT(p_madw);

	/*
	   An error occurred.  No response was received to a request MAD.
	   Retire the original request MAD.
	 */

	osm_dump_sa_mad(p_ctrl->p_log, osm_madw_get_sa_mad_ptr(p_madw),
			OSM_LOG_ERROR);

	/*  __osm_sm_mad_ctrl_update_wire_stats( p_ctrl ); */

	if (osm_madw_get_err_msg(p_madw) != CL_DISP_MSGID_NONE) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
			"Posting Dispatcher message %s\n",
			osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));

		status = cl_disp_post(p_ctrl->h_disp,
				      osm_madw_get_err_msg(p_madw),
				      p_madw,
				      __osm_sa_mad_ctrl_disp_done_callback,
				      p_ctrl);
		if (status != CL_SUCCESS) {
			OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A07: "
				"Dispatcher post message failed (%s)\n",
				CL_STATUS_MSG(status));
		}
	} else {
		/*
		   No error message was provided, just retire the MAD.
		 */
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
	}

	OSM_LOG_EXIT(p_ctrl->p_log);
}

/*
 * PARAMETERS
 *
 * RETURN VALUES
 *
 * NOTES
 *
 * SEE ALSO
 *********/

/**********************************************************************
 **********************************************************************/
void osm_sa_mad_ctrl_construct(IN osm_sa_mad_ctrl_t * const p_ctrl)
{
	CL_ASSERT(p_ctrl);
	memset(p_ctrl, 0, sizeof(*p_ctrl));
	p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
}

/**********************************************************************
 **********************************************************************/
void osm_sa_mad_ctrl_destroy(IN osm_sa_mad_ctrl_t * const p_ctrl)
{
	CL_ASSERT(p_ctrl);
	cl_disp_unregister(p_ctrl->h_disp);
}

/**********************************************************************
 **********************************************************************/
ib_api_status_t
osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * const p_ctrl,
		     IN osm_sa_t * sa,
		     IN osm_mad_pool_t * const p_mad_pool,
		     IN osm_vendor_t * const p_vendor,
		     IN osm_subn_t * const p_subn,
		     IN osm_log_t * const p_log,
		     IN osm_stats_t * const p_stats,
		     IN cl_dispatcher_t * const p_disp)
{
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_log);

	osm_sa_mad_ctrl_construct(p_ctrl);

	p_ctrl->sa = sa;
	p_ctrl->p_log = p_log;
	p_ctrl->p_disp = p_disp;
	p_ctrl->p_mad_pool = p_mad_pool;
	p_ctrl->p_vendor = p_vendor;
	p_ctrl->p_stats = p_stats;
	p_ctrl->p_subn = p_subn;

	p_ctrl->h_disp = cl_disp_register(p_disp,
					  CL_DISP_MSGID_NONE, NULL, p_ctrl);

	if (p_ctrl->h_disp == CL_DISP_INVALID_HANDLE) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A08: "
			"Dispatcher registration failed\n");
		status = IB_INSUFFICIENT_RESOURCES;
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_log);
	return (status);
}

/**********************************************************************
 **********************************************************************/
ib_api_status_t
osm_sa_mad_ctrl_bind(IN osm_sa_mad_ctrl_t * const p_ctrl,
		     IN const ib_net64_t port_guid)
{
	osm_bind_info_t bind_info;
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_ctrl->p_log);

	if (p_ctrl->h_bind != OSM_BIND_INVALID_HANDLE) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A09: "
			"Multiple binds not allowed\n");
		status = IB_ERROR;
		goto Exit;
	}

	bind_info.class_version = 2;
	bind_info.is_responder = TRUE;
	bind_info.is_report_processor = FALSE;
	bind_info.is_trap_processor = FALSE;
	bind_info.mad_class = IB_MCLASS_SUBN_ADM;
	bind_info.port_guid = port_guid;
	bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
	bind_info.send_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;

	OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
		"Binding to port GUID 0x%" PRIx64 "\n", cl_ntoh64(port_guid));

	p_ctrl->h_bind = osm_vendor_bind(p_ctrl->p_vendor,
					 &bind_info,
					 p_ctrl->p_mad_pool,
					 __osm_sa_mad_ctrl_rcv_callback,
					 __osm_sa_mad_ctrl_send_err_callback,
					 p_ctrl);

	if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
		status = IB_ERROR;
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A10: "
			"Vendor specific bind failed (%s)\n",
			ib_get_err_str(status));
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
	return (status);
}

/**********************************************************************
 **********************************************************************/
ib_api_status_t osm_sa_mad_ctrl_unbind(IN osm_sa_mad_ctrl_t * const p_ctrl)
{
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_ctrl->p_log);

	if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A11: "
			"No previous bind\n");
		status = IB_ERROR;
		goto Exit;
	}

	osm_vendor_unbind(p_ctrl->h_bind);
Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
	return (status);
}

Man Man