[ofa-general] [PATCH] opensm/perfmgr: PerfMgr for SM standby and inactive states
Sasha Khapyorsky
sashak at voltaire.com
Wed Aug 29 09:30:26 PDT 2007
It supports PerfMgr when OpenSM is in standby or inactive states.
For those cases PerfMgr will run its own fabric discovery (SMP based)
yet. I think in a future this code should be merged with "regular" SM
discovery.
Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
opensm/include/opensm/osm_base.h | 3 +-
opensm/include/opensm/osm_perfmgr.h | 7 +-
opensm/include/opensm/osm_stats.h | 8 +-
opensm/opensm/main.c | 6 +-
opensm/opensm/osm_helper.c | 3 +-
opensm/opensm/osm_perfmgr.c | 379 +++++++++++++++++++++++++++++------
opensm/opensm/osm_sm.c | 14 ++-
opensm/opensm/osm_sm_mad_ctrl.c | 3 +
8 files changed, 350 insertions(+), 73 deletions(-)
diff --git a/opensm/include/opensm/osm_base.h b/opensm/include/opensm/osm_base.h
index 61100e6..e635dcb 100644
--- a/opensm/include/opensm/osm_base.h
+++ b/opensm/include/opensm/osm_base.h
@@ -736,7 +736,8 @@ typedef enum _osm_sm_state {
#define OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST 9
#define OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED 10
#define OSM_SIGNAL_EXIT_STBY 11
-#define OSM_SIGNAL_MAX 12
+#define OSM_SIGNAL_PERFMGR_SWEEP 12
+#define OSM_SIGNAL_MAX 13
typedef uintn_t osm_signal_t;
/***********/
diff --git a/opensm/include/opensm/osm_perfmgr.h b/opensm/include/opensm/osm_perfmgr.h
index 6f0971b..4bf5d28 100644
--- a/opensm/include/opensm/osm_perfmgr.h
+++ b/opensm/include/opensm/osm_perfmgr.h
@@ -44,7 +44,7 @@
#include <iba/ib_types.h>
#include <complib/cl_passivelock.h>
#include <complib/cl_event.h>
-#include <complib/cl_thread.h>
+#include <complib/cl_timer.h>
#include <opensm/osm_subnet.h>
#include <opensm/osm_req.h>
#include <opensm/osm_log.h>
@@ -110,9 +110,8 @@ typedef struct _monitored_node {
* be manipulated only through the provided functions.
*/
typedef struct _osm_perfmgr {
- osm_thread_state_t thread_state;
cl_event_t sig_sweep;
- cl_thread_t sweeper;
+ cl_timer_t sweep_timer;
osm_subn_t *subn;
osm_sm_t *sm;
cl_plock_t *lock;
@@ -223,6 +222,8 @@ void osm_perfmgr_dump_counters(osm_perfmgr_t * p_perfmgr,
ib_api_status_t osm_perfmgr_bind(osm_perfmgr_t * const p_perfmgr,
const ib_net64_t port_guid);
+void osm_perfmgr_process(osm_perfmgr_t * pm);
+
/****f* OpenSM: PerfMgr/osm_perfmgr_init */
ib_api_status_t osm_perfmgr_init(osm_perfmgr_t * const perfmgr,
osm_subn_t * const subn,
diff --git a/opensm/include/opensm/osm_stats.h b/opensm/include/opensm/osm_stats.h
index 2d2fa14..ca7fa2f 100644
--- a/opensm/include/opensm/osm_stats.h
+++ b/opensm/include/opensm/osm_stats.h
@@ -48,6 +48,9 @@
#ifndef _OSM_STATS_H_
#define _OSM_STATS_H_
+#ifdef ENABLE_OSM_PERF_MGR
+#include <pthread.h>
+#endif
#include <opensm/osm_base.h>
#include <complib/cl_atomic.h>
@@ -90,7 +93,10 @@ typedef struct _osm_stats {
atomic32_t sa_mads_outstanding;
atomic32_t sa_mads_rcvd;
atomic32_t sa_mads_sent;
-
+#ifdef ENABLE_OSM_PERF_MGR
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#endif
} osm_stats_t;
/*
* FIELDS
diff --git a/opensm/opensm/main.c b/opensm/opensm/main.c
index eab64c0..08d654e 100644
--- a/opensm/opensm/main.c
+++ b/opensm/opensm/main.c
@@ -1080,10 +1080,14 @@ int main(int argc, char *argv[])
sleep(exitTimeout);
#endif
- if (osm.mad_pool.mads_out)
+ if (osm.mad_pool.mads_out) {
fprintf(stdout,
"There are still %u MADs out. Forcing the exit of the OpenSM application...\n",
osm.mad_pool.mads_out);
+#ifdef ENABLE_OSM_PERF_MGR
+ pthread_cond_signal(&osm.stats.cond);
+#endif
+ }
Exit:
osm_opensm_destroy(&osm);
diff --git a/opensm/opensm/osm_helper.c b/opensm/opensm/osm_helper.c
index 5dd3955..ff3da40 100644
--- a/opensm/opensm/osm_helper.c
+++ b/opensm/opensm/osm_helper.c
@@ -2111,7 +2111,8 @@ const char *const __osm_sm_signal_str[] = {
"OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST", /* 9 */
"OSM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED", /* 10 */
"OSM_SIGNAL_EXIT_STBY", /* 11 */
- "UNKNOWN SIGNAL!!" /* 12 */
+ "OSM_SIGNAL_PERFMGR_SWEEP", /* 12 */
+ "UNKNOWN SIGNAL!!" /* 13 */
};
/**********************************************************************
diff --git a/opensm/opensm/osm_perfmgr.c b/opensm/opensm/osm_perfmgr.c
index c1d2db4..ff3cab1 100644
--- a/opensm/opensm/osm_perfmgr.c
+++ b/opensm/opensm/osm_perfmgr.c
@@ -59,6 +59,7 @@
#include <opensm/osm_perfmgr.h>
#include <opensm/osm_log.h>
#include <opensm/osm_node.h>
+#include <opensm/osm_opensm.h>
#include <complib/cl_thread.h>
#include <vendor/osm_vendor_api.h>
#include <float.h>
@@ -550,83 +551,324 @@ __osm_perfmgr_query_counters(cl_map_item_t * const p_map_item, void *context)
}
/**********************************************************************
- * Main PerfMgr Thread.
- * Loop continuously and query the performance counters.
+ * Discovery stuff.
+ * Basically this code should not be here, but merged with main OpenSM
**********************************************************************/
-void __osm_perfmgr_sweeper(void *p_ptr)
+static int sweep_hop_1(osm_sm_t * sm)
{
- osm_perfmgr_t *const pm = (osm_perfmgr_t *) p_ptr;
+ ib_api_status_t status = IB_SUCCESS;
+ osm_bind_handle_t h_bind;
+ osm_madw_context_t context;
+ osm_node_t *p_node;
+ osm_port_t *p_port;
+ osm_physp_t *p_physp;
+ osm_dr_path_t *p_dr_path;
+ osm_dr_path_t hop_1_path;
+ ib_net64_t port_guid;
+ uint8_t port_num;
+ uint8_t path_array[IB_SUBNET_PATH_HOPS_MAX];
+ uint8_t num_ports;
+ osm_physp_t *p_ext_physp;
+
+ port_guid = sm->p_subn->sm_port_guid;
+
+ p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
+ if (!p_port) {
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "sweep_hop_1: ERR 4C81: No SM port object\n");
+ return -1;
+ }
- OSM_LOG_ENTER(pm->log, __osm_pm_sweeper);
+ p_node = p_port->p_node;
+ port_num = ib_node_info_get_local_port_num(&p_node->node_info);
- if (pm->thread_state == OSM_THREAD_STATE_INIT)
- pm->thread_state = OSM_THREAD_STATE_RUN;
+ osm_log(sm->p_log, OSM_LOG_DEBUG,
+ "sweep_hop_1: Probing hop 1 on local port %u\n", port_num);
- __init_monitored_nodes(pm);
+ p_physp = osm_node_get_physp_ptr(p_node, port_num);
+
+ CL_ASSERT(osm_physp_is_valid(p_physp));
+
+ p_dr_path = osm_physp_get_dr_path_ptr(p_physp);
+ h_bind = osm_dr_path_get_bind_handle(p_dr_path);
+
+ CL_ASSERT(h_bind != OSM_BIND_INVALID_HANDLE);
+
+ memset(path_array, 0, sizeof(path_array));
+ /* the hop_1 operations depend on the type of our node.
+ * Currently - legal nodes that can host SM are SW and CA */
+ switch (osm_node_get_type(p_node)) {
+ case IB_NODE_TYPE_CA:
+ case IB_NODE_TYPE_ROUTER:
+ memset(&context, 0, sizeof(context));
+ context.ni_context.node_guid = osm_node_get_node_guid(p_node);
+ context.ni_context.port_num = port_num;
+
+ path_array[1] = port_num;
+
+ osm_dr_path_init(&hop_1_path, h_bind, 1, path_array);
+ status = osm_req_get(&sm->req,
+ &hop_1_path,
+ IB_MAD_ATTR_NODE_INFO, 0,
+ CL_DISP_MSGID_NONE, &context);
+
+ if (status != IB_SUCCESS)
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "sweep_hop_1: ERR 4C82: "
+ "Request for NodeInfo failed\n");
+ break;
- while (pm->thread_state == OSM_THREAD_STATE_RUN) {
- /* do the sweep only if in MASTER state
- * AND we have been activated.
- * FIXME put something in here to try and reduce the load on the system
- * when it is not IDLE.
- if (pm->sm->state_mgr.state != OSM_SM_STATE_IDLE)
+ case IB_NODE_TYPE_SWITCH:
+ /* Need to go over all the ports of the switch, and send a node_info
+ * from them. This doesn't include the port 0 of the switch, which
+ * hosts the SM.
+ * Note: We'll send another switchInfo on port 0, since if no ports
+ * are connected, we still want to get some response, and have the
+ * subnet come up.
*/
- if (pm->subn->sm_state == IB_SMINFO_STATE_MASTER &&
- pm->state == PERFMGR_STATE_ENABLED) {
+ num_ports = osm_node_get_num_physp(p_node);
+ for (port_num = 0; port_num < num_ports; port_num++) {
+ /* go through the port only if the port is not DOWN */
+ p_ext_physp = osm_node_get_physp_ptr(p_node, port_num);
+ if (ib_port_info_get_port_state
+ (&p_ext_physp->port_info) <= IB_LINK_DOWN)
+ continue;
+
+ memset(&context, 0, sizeof(context));
+ context.ni_context.node_guid =
+ osm_node_get_node_guid(p_node);
+ context.ni_context.port_num = port_num;
+
+ path_array[1] = port_num;
+
+ osm_dr_path_init(&hop_1_path, h_bind, 1, path_array);
+ status = osm_req_get(&sm->req, &hop_1_path,
+ IB_MAD_ATTR_NODE_INFO, 0,
+ CL_DISP_MSGID_NONE, &context);
+
+ if (status != IB_SUCCESS)
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "sweep_hop_1: ERR 4C82: "
+ "Request for NodeInfo failed\n");
+ }
+ break;
+
+ default:
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "sweep_hop_1: ERR 4C83: Unknown node type %d\n",
+ osm_node_get_type(p_node));
+ }
+
+ return (status);
+}
+
+static unsigned is_sm_port_down(osm_sm_t *const sm)
+{
+ ib_net64_t port_guid;
+ osm_port_t *p_port;
+
+ port_guid = sm->p_subn->sm_port_guid;
+ if (port_guid == 0)
+ return 1;
+
+ CL_PLOCK_ACQUIRE(sm->p_lock);
+ p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
+ if (!p_port) {
+ CL_PLOCK_RELEASE(sm->p_lock);
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "is_sm_port_down: ERR 4C85: "
+ "SM port with GUID:%016" PRIx64 " is unknown\n",
+ cl_ntoh64(port_guid));
+ return 1;
+ }
+ CL_PLOCK_RELEASE(sm->p_lock);
+
+ return osm_physp_get_port_state(p_port->p_physp) == IB_LINK_DOWN;
+}
+
+static int sweep_hop_0(osm_sm_t *const sm)
+{
+ ib_api_status_t status;
+ osm_dr_path_t dr_path;
+ osm_bind_handle_t h_bind;
+ uint8_t path_array[IB_SUBNET_PATH_HOPS_MAX];
+
+ memset(path_array, 0, sizeof(path_array));
+
+ h_bind = osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl);
+ if (h_bind == OSM_BIND_INVALID_HANDLE) {
+ osm_log(sm->p_log, OSM_LOG_DEBUG,
+ "sweep_hop_0: No bound ports.\n");
+ return -1;
+ }
+
+ osm_dr_path_init(&dr_path, h_bind, 0, path_array);
+ status = osm_req_get(&sm->req,
+ &dr_path, IB_MAD_ATTR_NODE_INFO, 0,
+ CL_DISP_MSGID_NONE, NULL);
+
+ if (status != IB_SUCCESS)
+ osm_log(sm->p_log, OSM_LOG_ERROR,
+ "sweep_hop_0: ERR 4C86: Request for NodeInfo failed\n");
+
+ return (status);
+}
+
+static int wait_for_pending_transactions(osm_stats_t *stats)
+{
+ pthread_mutex_lock(&stats->mutex);
+ while (stats->qp0_mads_outstanding && !osm_exit_flag)
+ pthread_cond_wait(&stats->cond, &stats->mutex);
+ pthread_mutex_unlock(&stats->mutex);
+ return 0;
+}
+
+static void reset_node_count(cl_map_item_t * const p_map_item, void *cxt)
+{
+ osm_node_t *p_node = (osm_node_t *) p_map_item;
+ p_node->discovery_count = 0;
+}
+
+static void reset_port_count(cl_map_item_t * const p_map_item, void *cxt)
+{
+ osm_port_t *p_port = (osm_port_t *) p_map_item;
+ p_port->discovery_count = 0;
+}
+
+static void reset_switch_count(cl_map_item_t * const p_map_item, void *cxt)
+{
+ osm_switch_t *p_sw = (osm_switch_t *) p_map_item;
+ p_sw->discovery_count = 0;
+ p_sw->need_update = 0;
+}
+
+static int perfmgr_discovery(osm_opensm_t *osm)
+{
+ unsigned signals = osm->sm.signal_mask;
+ int ret;
+
+ CL_PLOCK_ACQUIRE(&osm->lock);
+ cl_qmap_apply_func(&osm->subn.node_guid_tbl, reset_node_count, NULL);
+ cl_qmap_apply_func(&osm->subn.port_guid_tbl, reset_port_count, NULL);
+ cl_qmap_apply_func(&osm->subn.sw_guid_tbl, reset_switch_count, NULL);
+ CL_PLOCK_RELEASE(&osm->lock);
+
+ osm->subn.in_sweep_hop_0 = TRUE;
+
+ ret = sweep_hop_0(&osm->sm);
+ if (ret)
+ goto _exit;
+
+ wait_for_pending_transactions(&osm->stats);
+
+ if (is_sm_port_down(&osm->sm)) {
+ osm_log(&osm->log, OSM_LOG_VERBOSE,
+ "SM port is down\n");
+ goto _drop;
+ }
+
+ osm->subn.in_sweep_hop_0 = FALSE;
+
+ ret = sweep_hop_1(&osm->sm);
+ if (ret)
+ goto _exit;
+
+ wait_for_pending_transactions(&osm->stats);
+
+ _drop:
+ osm_drop_mgr_process(&osm->sm.drop_mgr);
+
+ _exit:
+ /* dirty hack: cleanup signal mask -
+ * this will not be needed later with both discoveries merged */
+ cl_spinlock_acquire(&osm->sm.signal_lock);
+ osm->sm.signal_mask &= ~(OSM_SIGNAL_NO_PENDING_TRANSACTIONS|
+ OSM_SIGNAL_CHANGE_DETECTED);
+ osm->sm.signal_mask |= signals;
+ cl_spinlock_release(&osm->sm.signal_lock);
+ return ret;
+}
+
+/**********************************************************************
+ * Main PerfMgr processor - query the performance counters.
+ **********************************************************************/
+void osm_perfmgr_process(osm_perfmgr_t *pm)
+{
#if ENABLE_OSM_PERF_MGR_PROFILE
- struct timeval before, after;
- gettimeofday(&before, NULL);
+ struct timeval before, after;
#endif
- pm->sweep_state = PERFMGR_SWEEP_ACTIVE;
- /* With the global lock held collect the node guids */
- /* FIXME we should be able to track SA notices
- * and not have to sweep the node_guid_tbl each pass
- */
- osm_log(pm->log, OSM_LOG_VERBOSE,
- "Gathering PerfMgr stats\n");
- cl_plock_acquire(pm->lock);
- cl_qmap_apply_func(&(pm->subn->node_guid_tbl),
- __collect_guids, (void *)pm);
- cl_plock_release(pm->lock);
- /* then for each node query their counters */
- cl_qmap_apply_func(&(pm->monitored_map),
- __osm_perfmgr_query_counters,
- (void *)pm);
+ if (pm->state != PERFMGR_STATE_ENABLED)
+ return;
+
+ if (pm->sm->state_mgr.state != OSM_SM_STATE_IDLE &&
+ pm->sm->state_mgr.state != OSM_SM_STATE_STANDBY)
+ return;
- /* Clean out any nodes found to be removed during the
- * sweep
- */
- __remove_marked_nodes(pm);
+ if (pm->sm->state_mgr.state == OSM_SM_STATE_STANDBY ||
+ (pm->sm->state_mgr.state == OSM_SM_STATE_IDLE &&
+ pm->subn->sm_state == IB_SMINFO_STATE_NOTACTIVE))
+ perfmgr_discovery(pm->subn->p_osm);
#if ENABLE_OSM_PERF_MGR_PROFILE
- /* spin on outstanding queries */
- while (pm->outstanding_queries > 0)
- cl_event_wait_on(&pm->sig_sweep, 1000, TRUE);
-
- gettimeofday(&after, NULL);
- diff_time(&before, &after, &after);
- osm_log(pm->log, OSM_LOG_INFO,
- "PerfMgr total sweep time : %ld.%06ld s\n"
- " fastest mad : %g us\n"
- " slowest mad : %g us\n"
- " average mad : %g us\n"
- ,
- after.tv_sec, after.tv_usec,
- perfmgr_mad_stats.fastest_us,
- perfmgr_mad_stats.slowest_us,
- perfmgr_mad_stats.avg_us);
- perfmgr_clear_mad_stats();
+ gettimeofday(&before, NULL);
#endif
- }
+ pm->sweep_state = PERFMGR_SWEEP_ACTIVE;
+ /* With the global lock held collect the node guids */
+ /* FIXME we should be able to track SA notices
+ * and not have to sweep the node_guid_tbl each pass
+ */
+ osm_log(pm->log, OSM_LOG_VERBOSE,
+ "Gathering PerfMgr stats\n");
+ cl_plock_acquire(pm->lock);
+ cl_qmap_apply_func(&(pm->subn->node_guid_tbl),
+ __collect_guids, (void *)pm);
+ cl_plock_release(pm->lock);
- pm->sweep_state = PERFMGR_SWEEP_SLEEP;
+ /* then for each node query their counters */
+ cl_qmap_apply_func(&(pm->monitored_map),
+ __osm_perfmgr_query_counters, (void *)pm);
- /* Wait for a forced sweep or period timeout. */
- cl_event_wait_on(&pm->sig_sweep, pm->sweep_time_s * 1000000, TRUE);
- }
+ /* Clean out any nodes found to be removed during the
+ * sweep
+ */
+ __remove_marked_nodes(pm);
- OSM_LOG_EXIT(pm->log);
+#if ENABLE_OSM_PERF_MGR_PROFILE
+ /* spin on outstanding queries */
+ while (pm->outstanding_queries > 0)
+ cl_event_wait_on(&pm->sig_sweep, 1000, TRUE);
+
+ gettimeofday(&after, NULL);
+ diff_time(&before, &after, &after);
+ osm_log(pm->log, OSM_LOG_INFO,
+ "PerfMgr total sweep time : %ld.%06ld s\n"
+ " fastest mad : %g us\n"
+ " slowest mad : %g us\n"
+ " average mad : %g us\n",
+ after.tv_sec, after.tv_usec,
+ perfmgr_mad_stats.fastest_us,
+ perfmgr_mad_stats.slowest_us,
+ perfmgr_mad_stats.avg_us);
+ perfmgr_clear_mad_stats();
+#endif
+
+ pm->sweep_state = PERFMGR_SWEEP_SLEEP;
+}
+
+/**********************************************************************
+ * PerfMgr timer - loop continuously and signal SM to run PerfMgr
+ * processor.
+ **********************************************************************/
+static void perfmgr_sweep(void *arg)
+{
+ osm_perfmgr_t * pm = arg;
+
+ __init_monitored_nodes(pm);
+
+ if (pm->state == PERFMGR_STATE_ENABLED)
+ osm_sm_signal(pm->sm, OSM_SIGNAL_PERFMGR_SWEEP);
+ cl_timer_start(&pm->sweep_timer, pm->sweep_time_s * 1000);
}
/**********************************************************************
@@ -634,6 +876,7 @@ void __osm_perfmgr_sweeper(void *p_ptr)
void osm_perfmgr_shutdown(osm_perfmgr_t * const pm)
{
OSM_LOG_ENTER(pm->log, osm_perfmgr_shutdown);
+ cl_timer_stop(&pm->sweep_timer);
osm_perfmgr_mad_unbind(pm);
OSM_LOG_EXIT(pm->log);
}
@@ -645,6 +888,9 @@ void osm_perfmgr_destroy(osm_perfmgr_t * const pm)
OSM_LOG_ENTER(pm->log, osm_perfmgr_destroy);
free(pm->event_db_dump_file);
perfmgr_db_destroy(pm->db);
+ cl_timer_destroy(&pm->sweep_timer);
+ pthread_cond_destroy(&pm->subn->p_osm->stats.cond);
+ pthread_mutex_destroy(&pm->subn->p_osm->stats.mutex);
OSM_LOG_EXIT(pm->log);
}
@@ -1033,6 +1279,13 @@ osm_perfmgr_init(osm_perfmgr_t * const pm,
pm->max_outstanding_queries = p_opt->perfmgr_max_outstanding_queries;
pm->event_plugin = event_plugin;
+ pthread_mutex_init(&subn->p_osm->stats.mutex, NULL);
+ pthread_cond_init(&subn->p_osm->stats.cond, NULL);
+
+ status = cl_timer_init(&pm->sweep_timer, perfmgr_sweep, pm);
+ if (status != IB_SUCCESS)
+ goto Exit;
+
pm->db = perfmgr_db_construct(pm->log, pm->event_plugin);
if (!pm->db) {
pm->state = PERFMGR_STATE_NO_DB;
@@ -1044,11 +1297,7 @@ osm_perfmgr_init(osm_perfmgr_t * const pm,
if (pm->pc_disp_h == CL_DISP_INVALID_HANDLE)
goto Exit;
- pm->thread_state = OSM_THREAD_STATE_INIT;
- status = cl_thread_init(&pm->sweeper, __osm_perfmgr_sweeper, pm,
- "PerfMgr sweeper");
- if (status != IB_SUCCESS)
- goto Exit;
+ cl_timer_start(&pm->sweep_timer, pm->sweep_time_s * 1000);
Exit:
OSM_LOG_EXIT(log);
diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
index 154ac8e..c13f7ab 100644
--- a/opensm/opensm/osm_sm.c
+++ b/opensm/opensm/osm_sm.c
@@ -63,11 +63,23 @@
#include <opensm/osm_msgdef.h>
#include <opensm/osm_mcast_mgr.h>
#include <opensm/osm_mcm_info.h>
+#include <opensm/osm_perfmgr.h>
+#include <opensm/osm_opensm.h>
#define OSM_SM_INITIAL_TID_VALUE 0x1233
/**********************************************************************
**********************************************************************/
+static void osm_sm_process(osm_sm_t *sm, osm_signal_t signal)
+{
+#ifdef ENABLE_OSM_PERF_MGR
+ if (signal == OSM_SIGNAL_PERFMGR_SWEEP)
+ osm_perfmgr_process(&sm->p_subn->p_osm->perfmgr);
+ else
+#endif
+ osm_state_mgr_process(&sm->state_mgr, signal);
+}
+
static void __osm_sm_sweeper(IN void *p_ptr)
{
ib_api_status_t status;
@@ -104,7 +116,7 @@ static void __osm_sm_sweeper(IN void *p_ptr)
for (i = 0 ; signals ; signals >>= 1 , i++)
if (signals&1)
- osm_state_mgr_process(&p_sm->state_mgr, i);
+ osm_sm_process(p_sm, i);
}
OSM_LOG_EXIT(p_sm->p_log);
diff --git a/opensm/opensm/osm_sm_mad_ctrl.c b/opensm/opensm/osm_sm_mad_ctrl.c
index 2ed973d..9df5f86 100644
--- a/opensm/opensm/osm_sm_mad_ctrl.c
+++ b/opensm/opensm/osm_sm_mad_ctrl.c
@@ -106,6 +106,9 @@ __osm_sm_mad_ctrl_retire_trans_mad(IN osm_sm_mad_ctrl_t * const p_ctrl,
"__osm_sm_mad_ctrl_retire_trans_mad: "
"signal OSM_SIGNAL_NO_PENDING_TRANSACTIONS\n");
+#ifdef ENABLE_OSM_PERF_MGR
+ pthread_cond_signal(&p_ctrl->p_stats->cond);
+#endif
osm_sm_signal(&p_ctrl->p_subn->p_osm->sm,
OSM_SIGNAL_NO_PENDING_TRANSACTIONS);
}
--
1.5.3.rc2.38.g11308
More information about the general
mailing list