|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Abstract:
|
|
Packit Service |
54dbc3 |
* Implementation of osm_sm_t.
|
|
Packit Service |
54dbc3 |
* This object represents the SM Receiver object.
|
|
Packit Service |
54dbc3 |
* This object is part of the opensm family of objects.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <stdlib.h>
|
|
Packit Service |
54dbc3 |
#include <string.h>
|
|
Packit Service |
54dbc3 |
#include <iba/ib_types.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_qmap.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_passivelock.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_debug.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_thread.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_file_ids.h>
|
|
Packit Service |
54dbc3 |
#define FILE_ID OSM_FILE_SM_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_sm.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_madw.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_log.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_node.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_msgdef.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_perfmgr.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#define OSM_SM_INITIAL_TID_VALUE 0x1233
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
extern void osm_lft_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_mft_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_nd_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_ni_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_pkey_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_pi_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_gi_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_slvl_rcv_process(IN void *context, IN void *p_data);
|
|
Packit Service |
54dbc3 |
extern void osm_sminfo_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_si_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_trap_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_vla_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
extern void osm_mlnx_epi_rcv_process(IN void *context, IN void *data);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
extern void osm_state_mgr_process(IN osm_sm_t * sm, IN osm_signal_t signal);
|
|
Packit Service |
54dbc3 |
extern void osm_sm_state_mgr_polling_callback(IN void *context);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void sm_process(osm_sm_t * sm, osm_signal_t signal)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
#ifdef ENABLE_OSM_PERF_MGR
|
|
Packit Service |
54dbc3 |
if (signal == OSM_SIGNAL_PERFMGR_SWEEP)
|
|
Packit Service |
54dbc3 |
osm_perfmgr_process(&sm->p_subn->p_osm->perfmgr);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
#endif
|
|
Packit Service |
54dbc3 |
osm_state_mgr_process(sm, signal);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void sm_sweeper(IN void *p_ptr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
osm_sm_t * p_sm = p_ptr;
|
|
Packit Service |
54dbc3 |
unsigned signals, i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (p_sm->thread_state == OSM_THREAD_STATE_RUN) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Wait on the event with a timeout.
|
|
Packit Service |
54dbc3 |
* Sweeps may be initiated "off schedule" by simply
|
|
Packit Service |
54dbc3 |
* signaling the event.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
status = cl_event_wait_on(&p_sm->signal_event,
|
|
Packit Service |
54dbc3 |
EVENT_NO_TIMEOUT, TRUE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (status == CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Off schedule sweep signalled\n");
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E01: "
|
|
Packit Service |
54dbc3 |
"Event wait failed (%s)\n",
|
|
Packit Service |
54dbc3 |
CL_STATUS_MSG(status));
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_exit_flag)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_acquire(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
signals = p_sm->signal_mask;
|
|
Packit Service |
54dbc3 |
p_sm->signal_mask = 0;
|
|
Packit Service |
54dbc3 |
cl_spinlock_release(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; signals; signals >>= 1, i++)
|
|
Packit Service |
54dbc3 |
if (signals & 1)
|
|
Packit Service |
54dbc3 |
sm_process(p_sm, i);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void sm_sweep(void *arg)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_sm_t *sm = arg;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* do the sweep only if we are in MASTER state */
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER ||
|
|
Packit Service |
54dbc3 |
sm->p_subn->sm_state == IB_SMINFO_STATE_DISCOVERING)
|
|
Packit Service |
54dbc3 |
osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
|
|
Packit Service |
54dbc3 |
cl_timer_start(&sm->sweep_timer, sm->p_subn->opt.sweep_interval * 1000);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void sweep_fail_process(IN void *context, IN void *p_data)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_sm_t *sm = context;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "light sweep failed\n");
|
|
Packit Service |
54dbc3 |
sm->p_subn->force_heavy_sweep = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_construct(IN osm_sm_t * p_sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
memset(p_sm, 0, sizeof(*p_sm));
|
|
Packit Service |
54dbc3 |
p_sm->thread_state = OSM_THREAD_STATE_NONE;
|
|
Packit Service |
54dbc3 |
p_sm->sm_trans_id = OSM_SM_INITIAL_TID_VALUE;
|
|
Packit Service |
54dbc3 |
cl_spinlock_construct(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
cl_spinlock_construct(&p_sm->state_lock);
|
|
Packit Service |
54dbc3 |
cl_timer_construct(&p_sm->polling_timer);
|
|
Packit Service |
54dbc3 |
cl_event_construct(&p_sm->signal_event);
|
|
Packit Service |
54dbc3 |
cl_event_construct(&p_sm->subnet_up_event);
|
|
Packit Service |
54dbc3 |
cl_event_wheel_construct(&p_sm->trap_aging_tracker);
|
|
Packit Service |
54dbc3 |
cl_thread_construct(&p_sm->sweeper);
|
|
Packit Service |
54dbc3 |
osm_sm_mad_ctrl_construct(&p_sm->mad_ctrl);
|
|
Packit Service |
54dbc3 |
osm_lid_mgr_construct(&p_sm->lid_mgr);
|
|
Packit Service |
54dbc3 |
osm_ucast_mgr_construct(&p_sm->ucast_mgr);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_shutdown(IN osm_sm_t * p_sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
boolean_t signal_event = FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Signal our threads that we're leaving.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_sm->thread_state != OSM_THREAD_STATE_NONE)
|
|
Packit Service |
54dbc3 |
signal_event = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->thread_state = OSM_THREAD_STATE_EXIT;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Don't trigger unless event has been initialized.
|
|
Packit Service |
54dbc3 |
* Destroy the thread before we tear down the other objects.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (signal_event)
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_sm->signal_event);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_timer_stop(&p_sm->polling_timer);
|
|
Packit Service |
54dbc3 |
cl_timer_stop(&p_sm->sweep_timer);
|
|
Packit Service |
54dbc3 |
cl_thread_destroy(&p_sm->sweeper);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Always destroy controllers before the corresponding
|
|
Packit Service |
54dbc3 |
* receiver to guarantee that all callbacks from the
|
|
Packit Service |
54dbc3 |
* dispatcher are complete.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
osm_sm_mad_ctrl_destroy(&p_sm->mad_ctrl);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->ni_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->pi_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->gi_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->si_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->nd_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->lft_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->mft_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->sm_info_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->trap_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->slvl_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->vla_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->pkey_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->mlnx_epi_disp_h);
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_sm->sweep_fail_disp_h);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_destroy(IN osm_sm_t * p_sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
osm_lid_mgr_destroy(&p_sm->lid_mgr);
|
|
Packit Service |
54dbc3 |
osm_ucast_mgr_destroy(&p_sm->ucast_mgr);
|
|
Packit Service |
54dbc3 |
cl_event_wheel_destroy(&p_sm->trap_aging_tracker);
|
|
Packit Service |
54dbc3 |
cl_timer_destroy(&p_sm->sweep_timer);
|
|
Packit Service |
54dbc3 |
cl_timer_destroy(&p_sm->polling_timer);
|
|
Packit Service |
54dbc3 |
cl_event_destroy(&p_sm->signal_event);
|
|
Packit Service |
54dbc3 |
cl_event_destroy(&p_sm->subnet_up_event);
|
|
Packit Service |
54dbc3 |
cl_spinlock_destroy(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
cl_spinlock_destroy(&p_sm->state_lock);
|
|
Packit Service |
54dbc3 |
free(p_sm->mlids_req);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log_v2(p_sm->p_log, OSM_LOG_SYS, FILE_ID, "Exiting SM\n"); /* Format Waived */
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_sm_init(IN osm_sm_t * p_sm, IN osm_subn_t * p_subn,
|
|
Packit Service |
54dbc3 |
IN osm_db_t * p_db, IN osm_vendor_t * p_vendor,
|
|
Packit Service |
54dbc3 |
IN osm_mad_pool_t * p_mad_pool,
|
|
Packit Service |
54dbc3 |
IN osm_vl15_t * p_vl15, IN osm_log_t * p_log,
|
|
Packit Service |
54dbc3 |
IN osm_stats_t * p_stats,
|
|
Packit Service |
54dbc3 |
IN cl_dispatcher_t * p_disp, IN cl_plock_t * p_lock)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->p_subn = p_subn;
|
|
Packit Service |
54dbc3 |
p_sm->p_db = p_db;
|
|
Packit Service |
54dbc3 |
p_sm->p_vendor = p_vendor;
|
|
Packit Service |
54dbc3 |
p_sm->p_mad_pool = p_mad_pool;
|
|
Packit Service |
54dbc3 |
p_sm->p_vl15 = p_vl15;
|
|
Packit Service |
54dbc3 |
p_sm->p_log = p_log;
|
|
Packit Service |
54dbc3 |
p_sm->p_disp = p_disp;
|
|
Packit Service |
54dbc3 |
p_sm->p_lock = p_lock;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_spinlock_init(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_spinlock_init(&p_sm->state_lock);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_event_init(&p_sm->signal_event, FALSE);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_event_init(&p_sm->subnet_up_event, FALSE);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_timer_init(&p_sm->sweep_timer, sm_sweep, p_sm);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_timer_init(&p_sm->polling_timer,
|
|
Packit Service |
54dbc3 |
osm_sm_state_mgr_polling_callback, p_sm);
|
|
Packit Service |
54dbc3 |
if (status != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->mlids_req_max = 0;
|
|
Packit Service |
54dbc3 |
p_sm->mlids_req = malloc((IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO +
|
|
Packit Service |
54dbc3 |
1) * sizeof(p_sm->mlids_req[0]));
|
|
Packit Service |
54dbc3 |
if (!p_sm->mlids_req)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
memset(p_sm->mlids_req, 0,
|
|
Packit Service |
54dbc3 |
(IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO +
|
|
Packit Service |
54dbc3 |
1) * sizeof(p_sm->mlids_req[0]));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_sm_mad_ctrl_init(&p_sm->mad_ctrl, p_sm->p_subn,
|
|
Packit Service |
54dbc3 |
p_sm->p_mad_pool, p_sm->p_vl15,
|
|
Packit Service |
54dbc3 |
p_sm->p_vendor,
|
|
Packit Service |
54dbc3 |
p_log, p_stats, p_lock, p_disp);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_event_wheel_init(&p_sm->trap_aging_tracker);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_lid_mgr_init(&p_sm->lid_mgr, p_sm);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_ucast_mgr_init(&p_sm->ucast_mgr, p_sm);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit Service |
54dbc3 |
p_sm->sweep_fail_disp_h = cl_disp_register(p_disp,
|
|
Packit Service |
54dbc3 |
OSM_MSG_LIGHT_SWEEP_FAIL,
|
|
Packit Service |
54dbc3 |
sweep_fail_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->sweep_fail_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->ni_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_INFO,
|
|
Packit Service |
54dbc3 |
osm_ni_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->ni_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->pi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PORT_INFO,
|
|
Packit Service |
54dbc3 |
osm_pi_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->pi_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->gi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_GUID_INFO,
|
|
Packit Service |
54dbc3 |
osm_gi_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->gi_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->si_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SWITCH_INFO,
|
|
Packit Service |
54dbc3 |
osm_si_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->si_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->nd_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_DESC,
|
|
Packit Service |
54dbc3 |
osm_nd_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->nd_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->lft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LFT,
|
|
Packit Service |
54dbc3 |
osm_lft_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->lft_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->mft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_MFT,
|
|
Packit Service |
54dbc3 |
osm_mft_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->mft_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->sm_info_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SM_INFO,
|
|
Packit Service |
54dbc3 |
osm_sminfo_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->sm_info_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->trap_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NOTICE,
|
|
Packit Service |
54dbc3 |
osm_trap_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->trap_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->slvl_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SLVL,
|
|
Packit Service |
54dbc3 |
osm_slvl_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->slvl_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->vla_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_VL_ARB,
|
|
Packit Service |
54dbc3 |
osm_vla_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->vla_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->pkey_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PKEY,
|
|
Packit Service |
54dbc3 |
osm_pkey_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->pkey_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sm->mlnx_epi_disp_h = cl_disp_register(p_disp,
|
|
Packit Service |
54dbc3 |
OSM_MSG_MAD_MLNX_EXT_PORT_INFO,
|
|
Packit Service |
54dbc3 |
osm_mlnx_epi_rcv_process, p_sm);
|
|
Packit Service |
54dbc3 |
if (p_sm->mlnx_epi_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_subn->sm_state = p_subn->opt.sm_inactive ?
|
|
Packit Service |
54dbc3 |
IB_SMINFO_STATE_NOTACTIVE : IB_SMINFO_STATE_DISCOVERING;
|
|
Packit Service |
54dbc3 |
osm_report_sm_state(p_sm);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Now that the component objects are initialized, start
|
|
Packit Service |
54dbc3 |
* the sweeper thread if the user wants sweeping.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_sm->thread_state = OSM_THREAD_STATE_RUN;
|
|
Packit Service |
54dbc3 |
status = cl_thread_init(&p_sm->sweeper, sm_sweeper, p_sm,
|
|
Packit Service |
54dbc3 |
"opensm sweeper");
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_sm->p_subn->opt.sweep_interval)
|
|
Packit Service |
54dbc3 |
cl_timer_start(&p_sm->sweep_timer,
|
|
Packit Service |
54dbc3 |
p_sm->p_subn->opt.sweep_interval * 1000);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_signal(osm_sm_t * p_sm, osm_signal_t signal)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_spinlock_acquire(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
p_sm->signal_mask |= 1 << signal;
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_sm->signal_event);
|
|
Packit Service |
54dbc3 |
cl_spinlock_release(&p_sm->signal_lock);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_sweep(IN osm_sm_t * p_sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
osm_sm_signal(p_sm, OSM_SIGNAL_SWEEP);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_sm_bind(IN osm_sm_t * p_sm, IN ib_net64_t port_guid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_sm_mad_ctrl_bind(&p_sm->mad_ctrl, port_guid);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E10: "
|
|
Packit Service |
54dbc3 |
"SM MAD Controller bind failed (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_sm_reroute_mlid(osm_sm_t * sm, ib_net16_t mlid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
mlid = cl_ntoh16(mlid) - IB_LID_MCAST_START_HO;
|
|
Packit Service |
54dbc3 |
sm->mlids_req[mlid] = 1;
|
|
Packit Service |
54dbc3 |
if (sm->mlids_req_max < mlid)
|
|
Packit Service |
54dbc3 |
sm->mlids_req_max = mlid;
|
|
Packit Service |
54dbc3 |
osm_sm_signal(sm, OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST);
|
|
Packit Service |
54dbc3 |
OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "rerouting requested for MLID 0x%x\n",
|
|
Packit Service |
54dbc3 |
mlid + IB_LID_MCAST_START_HO);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_set_sm_priority(osm_sm_t * sm, uint8_t priority)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint8_t old_pri = sm->p_subn->opt.sm_priority;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
sm->p_subn->opt.sm_priority = priority;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (old_pri < priority &&
|
|
Packit Service |
54dbc3 |
sm->p_subn->sm_state == IB_SMINFO_STATE_STANDBY)
|
|
Packit Service |
54dbc3 |
osm_send_trap144(sm, TRAP_144_MASK_SM_PRIORITY_CHANGE);
|
|
Packit Service |
54dbc3 |
}
|