1219820Sjeff/*
2219820Sjeff * Copyright (c) 2007 The Regents of the University of California.
3219820Sjeff * Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved.
4219820Sjeff *
5219820Sjeff * This software is available to you under a choice of one of two
6219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
7219820Sjeff * General Public License (GPL) Version 2, available from the file
8219820Sjeff * COPYING in the main directory of this source tree, or the
9219820Sjeff * OpenIB.org BSD license below:
10219820Sjeff *
11219820Sjeff *     Redistribution and use in source and binary forms, with or
12219820Sjeff *     without modification, are permitted provided that the following
13219820Sjeff *     conditions are met:
14219820Sjeff *
15219820Sjeff *      - Redistributions of source code must retain the above
16219820Sjeff *        copyright notice, this list of conditions and the following
17219820Sjeff *        disclaimer.
18219820Sjeff *
19219820Sjeff *      - Redistributions in binary form must reproduce the above
20219820Sjeff *        copyright notice, this list of conditions and the following
21219820Sjeff *        disclaimer in the documentation and/or other materials
22219820Sjeff *        provided with the distribution.
23219820Sjeff *
24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31219820Sjeff * SOFTWARE.
32219820Sjeff *
33219820Sjeff */
34219820Sjeff
35219820Sjeff#ifndef _OSM_PERFMGR_H_
36219820Sjeff#define _OSM_PERFMGR_H_
37219820Sjeff
38219820Sjeff#if HAVE_CONFIG_H
39219820Sjeff#  include <config.h>
40219820Sjeff#endif				/* HAVE_CONFIG_H */
41219820Sjeff
42219820Sjeff#ifdef ENABLE_OSM_PERF_MGR
43219820Sjeff
44219820Sjeff#include <iba/ib_types.h>
45219820Sjeff#include <complib/cl_passivelock.h>
46219820Sjeff#include <complib/cl_event.h>
47219820Sjeff#include <complib/cl_timer.h>
48219820Sjeff#include <opensm/osm_subnet.h>
49219820Sjeff#include <opensm/osm_log.h>
50219820Sjeff#include <opensm/osm_perfmgr_db.h>
51219820Sjeff#include <opensm/osm_sm.h>
52219820Sjeff#include <opensm/osm_base.h>
53219820Sjeff#include <opensm/osm_event_plugin.h>
54219820Sjeff
55219820Sjeff#ifdef __cplusplus
56219820Sjeffextern "C" {
57219820Sjeff#endif				/* __cplusplus */
58219820Sjeff
59219820Sjeff/****h* OpenSM/PerfMgr
60219820Sjeff* NAME
61219820Sjeff*	PerfMgr
62219820Sjeff*
63219820Sjeff* DESCRIPTION
64219820Sjeff*       Performance manager thread which takes care of polling the fabric for
65219820Sjeff*       Port counters values.
66219820Sjeff*
67219820Sjeff*	The PerfMgr object is thread safe.
68219820Sjeff*
69219820Sjeff* AUTHOR
70219820Sjeff*	Ira Weiny, LLNL
71219820Sjeff*
72219820Sjeff*********/
73219820Sjeff
74219820Sjeff#define OSM_PERFMGR_DEFAULT_SWEEP_TIME_S 180
75219820Sjeff#define OSM_PERFMGR_DEFAULT_DUMP_FILE "opensm_port_counters.log"
76219820Sjeff#define OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES 500
77219820Sjeff
78219820Sjeff/****s* OpenSM: PerfMgr/osm_perfmgr_state_t */
79219820Sjefftypedef enum {
80219820Sjeff	PERFMGR_STATE_DISABLE,
81219820Sjeff	PERFMGR_STATE_ENABLED,
82219820Sjeff	PERFMGR_STATE_NO_DB
83219820Sjeff} osm_perfmgr_state_t;
84219820Sjeff
85219820Sjeff/****s* OpenSM: PerfMgr/osm_perfmgr_sweep_state_t */
86219820Sjefftypedef enum {
87219820Sjeff	PERFMGR_SWEEP_SLEEP,
88219820Sjeff	PERFMGR_SWEEP_ACTIVE,
89219820Sjeff	PERFMGR_SWEEP_SUSPENDED
90219820Sjeff} osm_perfmgr_sweep_state_t;
91219820Sjeff
92219820Sjeff/* Redirection information */
93219820Sjefftypedef struct redir {
94219820Sjeff	ib_net16_t redir_lid;
95219820Sjeff	ib_net32_t redir_qp;
96219820Sjeff} redir_t;
97219820Sjeff
98219820Sjeff/* Node to store information about which nodes we are monitoring */
99219820Sjefftypedef struct _monitored_node {
100219820Sjeff	cl_map_item_t map_item;
101219820Sjeff	struct _monitored_node *next;
102219820Sjeff	uint64_t guid;
103219820Sjeff	char *name;
104219820Sjeff	uint32_t redir_tbl_size;
105219820Sjeff	redir_t redir_port[1];	/* redirection on a per port basis */
106219820Sjeff} __monitored_node_t;
107219820Sjeff
108219820Sjeffstruct osm_opensm;
109219820Sjeff/****s* OpenSM: PerfMgr/osm_perfmgr_t
110219820Sjeff*  This object should be treated as opaque and should
111219820Sjeff*  be manipulated only through the provided functions.
112219820Sjeff*/
113219820Sjefftypedef struct osm_perfmgr {
114219820Sjeff	cl_event_t sig_sweep;
115219820Sjeff	cl_timer_t sweep_timer;
116219820Sjeff	struct osm_opensm *osm;
117219820Sjeff	osm_subn_t *subn;
118219820Sjeff	osm_sm_t *sm;
119219820Sjeff	cl_plock_t *lock;
120219820Sjeff	osm_log_t *log;
121219820Sjeff	osm_mad_pool_t *mad_pool;
122219820Sjeff	atomic32_t trans_id;
123219820Sjeff	osm_vendor_t *vendor;
124219820Sjeff	osm_bind_handle_t bind_handle;
125219820Sjeff	cl_disp_reg_handle_t pc_disp_h;
126219820Sjeff	osm_perfmgr_state_t state;
127219820Sjeff	osm_perfmgr_sweep_state_t sweep_state;
128219820Sjeff	uint16_t sweep_time_s;
129219820Sjeff	perfmgr_db_t *db;
130219820Sjeff	atomic32_t outstanding_queries;	/* this along with sig_query */
131219820Sjeff	cl_event_t sig_query;	/* will throttle our querys */
132219820Sjeff	uint32_t max_outstanding_queries;
133219820Sjeff	cl_qmap_t monitored_map;	/* map the nodes we are tracking */
134219820Sjeff	__monitored_node_t *remove_list;
135219820Sjeff} osm_perfmgr_t;
136219820Sjeff/*
137219820Sjeff* FIELDS
138219820Sjeff*	subn
139219820Sjeff*	      Subnet object for this subnet.
140219820Sjeff*
141219820Sjeff*	log
142219820Sjeff*	      Pointer to the log object.
143219820Sjeff*
144219820Sjeff*	mad_pool
145219820Sjeff*		Pointer to the MAD pool.
146219820Sjeff*
147219820Sjeff*	mad_ctrl
148219820Sjeff*		Mad Controller
149219820Sjeff*********/
150219820Sjeff
151219820Sjeff/****f* OpenSM: Creation Functions */
152219820Sjeffvoid osm_perfmgr_shutdown(osm_perfmgr_t * const p_perfmgr);
153219820Sjeffvoid osm_perfmgr_destroy(osm_perfmgr_t * const p_perfmgr);
154219820Sjeff
155219820Sjeff/****f* OpenSM: Inline accessor functions */
156219820Sjeffinline static void osm_perfmgr_set_state(osm_perfmgr_t * p_perfmgr,
157219820Sjeff					 osm_perfmgr_state_t state)
158219820Sjeff{
159219820Sjeff	p_perfmgr->state = state;
160219820Sjeff	if (state == PERFMGR_STATE_ENABLED)
161219820Sjeff		osm_sm_signal(p_perfmgr->sm, OSM_SIGNAL_PERFMGR_SWEEP);
162219820Sjeff}
163219820Sjeff
164219820Sjeffinline static osm_perfmgr_state_t osm_perfmgr_get_state(osm_perfmgr_t
165219820Sjeff							  * p_perfmgr)
166219820Sjeff{
167219820Sjeff	return (p_perfmgr->state);
168219820Sjeff}
169219820Sjeff
170219820Sjeffinline static char *osm_perfmgr_get_state_str(osm_perfmgr_t * p_perfmgr)
171219820Sjeff{
172219820Sjeff	switch (p_perfmgr->state) {
173219820Sjeff	case PERFMGR_STATE_DISABLE:
174219820Sjeff		return ("Disabled");
175219820Sjeff		break;
176219820Sjeff	case PERFMGR_STATE_ENABLED:
177219820Sjeff		return ("Enabled");
178219820Sjeff		break;
179219820Sjeff	case PERFMGR_STATE_NO_DB:
180219820Sjeff		return ("No Database");
181219820Sjeff		break;
182219820Sjeff	}
183219820Sjeff	return ("UNKNOWN");
184219820Sjeff}
185219820Sjeff
186219820Sjeffinline static char *osm_perfmgr_get_sweep_state_str(osm_perfmgr_t * perfmgr)
187219820Sjeff{
188219820Sjeff	switch (perfmgr->sweep_state) {
189219820Sjeff	case PERFMGR_SWEEP_SLEEP:
190219820Sjeff		return ("Sleeping");
191219820Sjeff		break;
192219820Sjeff	case PERFMGR_SWEEP_ACTIVE:
193219820Sjeff		return ("Active");
194219820Sjeff		break;
195219820Sjeff	case PERFMGR_SWEEP_SUSPENDED:
196219820Sjeff		return ("Suspended");
197219820Sjeff		break;
198219820Sjeff	}
199219820Sjeff	return ("UNKNOWN");
200219820Sjeff}
201219820Sjeff
202219820Sjeffinline static void osm_perfmgr_set_sweep_time_s(osm_perfmgr_t * p_perfmgr,
203219820Sjeff						uint16_t time_s)
204219820Sjeff{
205219820Sjeff	p_perfmgr->sweep_time_s = time_s;
206219820Sjeff	osm_sm_signal(p_perfmgr->sm, OSM_SIGNAL_PERFMGR_SWEEP);
207219820Sjeff}
208219820Sjeff
209219820Sjeffinline static uint16_t osm_perfmgr_get_sweep_time_s(osm_perfmgr_t * p_perfmgr)
210219820Sjeff{
211219820Sjeff	return (p_perfmgr->sweep_time_s);
212219820Sjeff}
213219820Sjeff
214219820Sjeffvoid osm_perfmgr_clear_counters(osm_perfmgr_t * p_perfmgr);
215219820Sjeffvoid osm_perfmgr_dump_counters(osm_perfmgr_t * p_perfmgr,
216219820Sjeff			       perfmgr_db_dump_t dump_type);
217219820Sjeffvoid osm_perfmgr_print_counters(osm_perfmgr_t *pm, char *nodename,
218219820Sjeff				FILE *fp);
219219820Sjeff
220219820Sjeffib_api_status_t osm_perfmgr_bind(osm_perfmgr_t * const p_perfmgr,
221219820Sjeff				 const ib_net64_t port_guid);
222219820Sjeff
223219820Sjeffvoid osm_perfmgr_process(osm_perfmgr_t * pm);
224219820Sjeff
225219820Sjeff/****f* OpenSM: PerfMgr/osm_perfmgr_init */
226219820Sjeffib_api_status_t osm_perfmgr_init(osm_perfmgr_t * const perfmgr,
227219820Sjeff				 struct osm_opensm *osm,
228219820Sjeff				 const osm_subn_opt_t * const p_opt);
229219820Sjeff/*
230219820Sjeff* PARAMETERS
231219820Sjeff*	perfmgr
232219820Sjeff*		[in] Pointer to an osm_perfmgr_t object to initialize.
233219820Sjeff*
234219820Sjeff*	osm
235219820Sjeff*		[in] Pointer to the OpenSM object.
236219820Sjeff*
237219820Sjeff*	p_opt
238219820Sjeff*		[in] Starting options
239219820Sjeff*
240219820Sjeff* RETURN VALUES
241219820Sjeff*	IB_SUCCESS if the PerfMgr object was initialized successfully.
242219820Sjeff*********/
243219820Sjeff
244219820Sjeff#ifdef __cplusplus
245219820Sjeff}
246219820Sjeff#endif				/* __cplusplus */
247219820Sjeff
248219820Sjeff#endif				/* ENABLE_OSM_PERF_MGR */
249219820Sjeff
250219820Sjeff#endif				/* _OSM_PERFMGR_H_ */
251