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 <[EMAIL PROTECTED]>
---
 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

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to