1219820Sjeff/*
2219820Sjeff * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2007 The Regents of the University of California.
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#if HAVE_CONFIG_H
36219820Sjeff#  include <config.h>
37219820Sjeff#endif				/* HAVE_CONFIG_H */
38219820Sjeff
39219820Sjeff#ifdef ENABLE_OSM_PERF_MGR
40219820Sjeff
41219820Sjeff#include <stdlib.h>
42219820Sjeff#include <errno.h>
43219820Sjeff#include <limits.h>
44219820Sjeff#include <dlfcn.h>
45219820Sjeff#include <sys/stat.h>
46219820Sjeff
47219820Sjeff#include <opensm/osm_perfmgr_db.h>
48219820Sjeff#include <opensm/osm_perfmgr.h>
49219820Sjeff#include <opensm/osm_opensm.h>
50219820Sjeff
51219820Sjeff/** =========================================================================
52219820Sjeff */
53219820Sjeffperfmgr_db_t *perfmgr_db_construct(osm_perfmgr_t *perfmgr)
54219820Sjeff{
55219820Sjeff	perfmgr_db_t *db = malloc(sizeof(*db));
56219820Sjeff	if (!db)
57219820Sjeff		return (NULL);
58219820Sjeff
59219820Sjeff	cl_qmap_init(&(db->pc_data));
60219820Sjeff	cl_plock_construct(&(db->lock));
61219820Sjeff	cl_plock_init(&(db->lock));
62219820Sjeff	db->perfmgr = perfmgr;
63219820Sjeff	return ((void *)db);
64219820Sjeff}
65219820Sjeff
66219820Sjeff/** =========================================================================
67219820Sjeff */
68219820Sjeffvoid perfmgr_db_destroy(perfmgr_db_t * db)
69219820Sjeff{
70219820Sjeff	if (db) {
71219820Sjeff		cl_plock_destroy(&(db->lock));
72219820Sjeff		free(db);
73219820Sjeff	}
74219820Sjeff}
75219820Sjeff
76219820Sjeff/**********************************************************************
77219820Sjeff * Internal call db->lock should be held when calling
78219820Sjeff **********************************************************************/
79219820Sjeffstatic inline _db_node_t *_get(perfmgr_db_t * db, uint64_t guid)
80219820Sjeff{
81219820Sjeff	cl_map_item_t *rc = cl_qmap_get(&(db->pc_data), guid);
82219820Sjeff	const cl_map_item_t *end = cl_qmap_end(&(db->pc_data));
83219820Sjeff
84219820Sjeff	if (rc == end)
85219820Sjeff		return (NULL);
86219820Sjeff	return ((_db_node_t *) rc);
87219820Sjeff}
88219820Sjeff
89219820Sjeffstatic inline perfmgr_db_err_t bad_node_port(_db_node_t * node, uint8_t port)
90219820Sjeff{
91219820Sjeff	if (!node)
92219820Sjeff		return (PERFMGR_EVENT_DB_GUIDNOTFOUND);
93219820Sjeff	if (port == 0 || port >= node->num_ports)
94219820Sjeff		return (PERFMGR_EVENT_DB_PORTNOTFOUND);
95219820Sjeff	return (PERFMGR_EVENT_DB_SUCCESS);
96219820Sjeff}
97219820Sjeff
98219820Sjeff/** =========================================================================
99219820Sjeff */
100219820Sjeffstatic _db_node_t *__malloc_node(uint64_t guid, uint8_t num_ports, char *name)
101219820Sjeff{
102219820Sjeff	int i = 0;
103219820Sjeff	time_t cur_time = 0;
104219820Sjeff	_db_node_t *rc = malloc(sizeof(*rc));
105219820Sjeff	if (!rc)
106219820Sjeff		return (NULL);
107219820Sjeff
108219820Sjeff	rc->ports = calloc(num_ports, sizeof(_db_port_t));
109219820Sjeff	if (!rc->ports)
110219820Sjeff		goto free_rc;
111219820Sjeff	rc->num_ports = num_ports;
112219820Sjeff	rc->node_guid = guid;
113219820Sjeff
114219820Sjeff	cur_time = time(NULL);
115219820Sjeff	for (i = 0; i < num_ports; i++) {
116219820Sjeff		rc->ports[i].last_reset = cur_time;
117219820Sjeff		rc->ports[i].err_previous.time = cur_time;
118219820Sjeff		rc->ports[i].dc_previous.time = cur_time;
119219820Sjeff	}
120219820Sjeff	snprintf(rc->node_name, NODE_NAME_SIZE, "%s", name);
121219820Sjeff
122219820Sjeff	return (rc);
123219820Sjeff
124219820Sjefffree_rc:
125219820Sjeff	free(rc);
126219820Sjeff	return (NULL);
127219820Sjeff}
128219820Sjeff
129219820Sjeff/** =========================================================================
130219820Sjeff */
131219820Sjeffstatic void __free_node(_db_node_t * node)
132219820Sjeff{
133219820Sjeff	if (!node)
134219820Sjeff		return;
135219820Sjeff	if (node->ports)
136219820Sjeff		free(node->ports);
137219820Sjeff	free(node);
138219820Sjeff}
139219820Sjeff
140219820Sjeff/* insert nodes to the database */
141219820Sjeffstatic perfmgr_db_err_t __insert(perfmgr_db_t * db, _db_node_t * node)
142219820Sjeff{
143219820Sjeff	cl_map_item_t *rc = cl_qmap_insert(&(db->pc_data), node->node_guid,
144219820Sjeff					   (cl_map_item_t *) node);
145219820Sjeff
146219820Sjeff	if ((void *)rc != (void *)node)
147219820Sjeff		return (PERFMGR_EVENT_DB_FAIL);
148219820Sjeff	return (PERFMGR_EVENT_DB_SUCCESS);
149219820Sjeff}
150219820Sjeff
151219820Sjeff/**********************************************************************
152219820Sjeff **********************************************************************/
153219820Sjeffperfmgr_db_err_t
154219820Sjeffperfmgr_db_create_entry(perfmgr_db_t * db, uint64_t guid,
155219820Sjeff			uint8_t num_ports, char *name)
156219820Sjeff{
157219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
158219820Sjeff
159219820Sjeff	cl_plock_excl_acquire(&(db->lock));
160219820Sjeff	if (!_get(db, guid)) {
161219820Sjeff		_db_node_t *pc_node = __malloc_node(guid, num_ports, name);
162219820Sjeff		if (!pc_node) {
163219820Sjeff			rc = PERFMGR_EVENT_DB_NOMEM;
164219820Sjeff			goto Exit;
165219820Sjeff		}
166219820Sjeff		if (__insert(db, pc_node)) {
167219820Sjeff			__free_node(pc_node);
168219820Sjeff			rc = PERFMGR_EVENT_DB_FAIL;
169219820Sjeff			goto Exit;
170219820Sjeff		}
171219820Sjeff	}
172219820SjeffExit:
173219820Sjeff	cl_plock_release(&(db->lock));
174219820Sjeff	return (rc);
175219820Sjeff}
176219820Sjeff
177219820Sjeff/**********************************************************************
178219820Sjeff * Dump a reading vs the previous reading to stdout
179219820Sjeff **********************************************************************/
180219820Sjeffstatic inline void
181219820Sjeffdebug_dump_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num,
182219820Sjeff		       _db_port_t * port, perfmgr_db_err_reading_t * cur)
183219820Sjeff{
184219820Sjeff	osm_log_t *log = db->perfmgr->log;
185219820Sjeff
186219820Sjeff	if (!osm_log_is_active(log, OSM_LOG_DEBUG))
187219820Sjeff		return;		/* optimize this a bit */
188219820Sjeff
189219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
190219820Sjeff		"GUID 0x%" PRIx64 " Port %u:\n", guid, port_num);
191219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
192219820Sjeff		"sym %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
193219820Sjeff		cur->symbol_err_cnt, port->err_previous.symbol_err_cnt,
194219820Sjeff		port->err_total.symbol_err_cnt);
195219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
196219820Sjeff		"ler %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
197219820Sjeff		cur->link_err_recover, port->err_previous.link_err_recover,
198219820Sjeff		port->err_total.link_err_recover);
199219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
200219820Sjeff		"ld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
201219820Sjeff		cur->link_downed, port->err_previous.link_downed,
202219820Sjeff		port->err_total.link_downed);
203219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
204219820Sjeff		"re %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_err,
205219820Sjeff		port->err_previous.rcv_err, port->err_total.rcv_err);
206219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
207219820Sjeff		"rrp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
208219820Sjeff		cur->rcv_rem_phys_err, port->err_previous.rcv_rem_phys_err,
209219820Sjeff		port->err_total.rcv_rem_phys_err);
210219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
211219820Sjeff		"rsr %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
212219820Sjeff		cur->rcv_switch_relay_err,
213219820Sjeff		port->err_previous.rcv_switch_relay_err,
214219820Sjeff		port->err_total.rcv_switch_relay_err);
215219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
216219820Sjeff		"xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
217219820Sjeff		cur->xmit_discards, port->err_previous.xmit_discards,
218219820Sjeff		port->err_total.xmit_discards);
219219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
220219820Sjeff		"xce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
221219820Sjeff		cur->xmit_constraint_err,
222219820Sjeff		port->err_previous.xmit_constraint_err,
223219820Sjeff		port->err_total.xmit_constraint_err);
224219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
225219820Sjeff		"rce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
226219820Sjeff		cur->rcv_constraint_err, port->err_previous.rcv_constraint_err,
227219820Sjeff		port->err_total.rcv_constraint_err);
228219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
229219820Sjeff		"li %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
230219820Sjeff		cur->link_integrity, port->err_previous.link_integrity,
231219820Sjeff		port->err_total.link_integrity);
232219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
233219820Sjeff		"bo %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
234219820Sjeff		cur->buffer_overrun, port->err_previous.buffer_overrun,
235219820Sjeff		port->err_total.buffer_overrun);
236219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
237219820Sjeff		"vld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
238219820Sjeff		cur->vl15_dropped, port->err_previous.vl15_dropped,
239219820Sjeff		port->err_total.vl15_dropped);
240219820Sjeff}
241219820Sjeff
242219820Sjeff/**********************************************************************
243219820Sjeff * perfmgr_db_err_reading_t functions
244219820Sjeff **********************************************************************/
245219820Sjeffperfmgr_db_err_t
246219820Sjeffperfmgr_db_add_err_reading(perfmgr_db_t * db, uint64_t guid,
247219820Sjeff			   uint8_t port, perfmgr_db_err_reading_t * reading)
248219820Sjeff{
249219820Sjeff	_db_port_t *p_port = NULL;
250219820Sjeff	_db_node_t *node = NULL;
251219820Sjeff	perfmgr_db_err_reading_t *previous = NULL;
252219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
253219820Sjeff	osm_epi_pe_event_t epi_pe_data;
254219820Sjeff
255219820Sjeff	cl_plock_excl_acquire(&(db->lock));
256219820Sjeff	node = _get(db, guid);
257219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
258219820Sjeff		goto Exit;
259219820Sjeff
260219820Sjeff	p_port = &(node->ports[port]);
261219820Sjeff	previous = &(node->ports[port].err_previous);
262219820Sjeff
263219820Sjeff	debug_dump_err_reading(db, guid, port, p_port, reading);
264219820Sjeff
265219820Sjeff	epi_pe_data.time_diff_s = (reading->time - previous->time);
266219820Sjeff	osm_epi_create_port_id(&(epi_pe_data.port_id), guid, port,
267219820Sjeff			       node->node_name);
268219820Sjeff
269219820Sjeff	/* calculate changes from previous reading */
270219820Sjeff	epi_pe_data.symbol_err_cnt =
271219820Sjeff	    (reading->symbol_err_cnt - previous->symbol_err_cnt);
272219820Sjeff	p_port->err_total.symbol_err_cnt += epi_pe_data.symbol_err_cnt;
273219820Sjeff	epi_pe_data.link_err_recover =
274219820Sjeff	    (reading->link_err_recover - previous->link_err_recover);
275219820Sjeff	p_port->err_total.link_err_recover += epi_pe_data.link_err_recover;
276219820Sjeff	epi_pe_data.link_downed =
277219820Sjeff	    (reading->link_downed - previous->link_downed);
278219820Sjeff	p_port->err_total.link_downed += epi_pe_data.link_downed;
279219820Sjeff	epi_pe_data.rcv_err = (reading->rcv_err - previous->rcv_err);
280219820Sjeff	p_port->err_total.rcv_err += epi_pe_data.rcv_err;
281219820Sjeff	epi_pe_data.rcv_rem_phys_err =
282219820Sjeff	    (reading->rcv_rem_phys_err - previous->rcv_rem_phys_err);
283219820Sjeff	p_port->err_total.rcv_rem_phys_err += epi_pe_data.rcv_rem_phys_err;
284219820Sjeff	epi_pe_data.rcv_switch_relay_err =
285219820Sjeff	    (reading->rcv_switch_relay_err - previous->rcv_switch_relay_err);
286219820Sjeff	p_port->err_total.rcv_switch_relay_err +=
287219820Sjeff	    epi_pe_data.rcv_switch_relay_err;
288219820Sjeff	epi_pe_data.xmit_discards =
289219820Sjeff	    (reading->xmit_discards - previous->xmit_discards);
290219820Sjeff	p_port->err_total.xmit_discards += epi_pe_data.xmit_discards;
291219820Sjeff	epi_pe_data.xmit_constraint_err =
292219820Sjeff	    (reading->xmit_constraint_err - previous->xmit_constraint_err);
293219820Sjeff	p_port->err_total.xmit_constraint_err +=
294219820Sjeff	    epi_pe_data.xmit_constraint_err;
295219820Sjeff	epi_pe_data.rcv_constraint_err =
296219820Sjeff	    (reading->rcv_constraint_err - previous->rcv_constraint_err);
297219820Sjeff	p_port->err_total.rcv_constraint_err += epi_pe_data.rcv_constraint_err;
298219820Sjeff	epi_pe_data.link_integrity =
299219820Sjeff	    (reading->link_integrity - previous->link_integrity);
300219820Sjeff	p_port->err_total.link_integrity += epi_pe_data.link_integrity;
301219820Sjeff	epi_pe_data.buffer_overrun =
302219820Sjeff	    (reading->buffer_overrun - previous->buffer_overrun);
303219820Sjeff	p_port->err_total.buffer_overrun += epi_pe_data.buffer_overrun;
304219820Sjeff	epi_pe_data.vl15_dropped =
305219820Sjeff	    (reading->vl15_dropped - previous->vl15_dropped);
306219820Sjeff	p_port->err_total.vl15_dropped += epi_pe_data.vl15_dropped;
307219820Sjeff
308219820Sjeff	p_port->err_previous = *reading;
309219820Sjeff
310219820Sjeff	osm_opensm_report_event(db->perfmgr->osm, OSM_EVENT_ID_PORT_ERRORS,
311219820Sjeff				&epi_pe_data);
312219820Sjeff
313219820SjeffExit:
314219820Sjeff	cl_plock_release(&(db->lock));
315219820Sjeff	return (rc);
316219820Sjeff}
317219820Sjeff
318219820Sjeffperfmgr_db_err_t perfmgr_db_get_prev_err(perfmgr_db_t * db, uint64_t guid,
319219820Sjeff					 uint8_t port,
320219820Sjeff					 perfmgr_db_err_reading_t * reading)
321219820Sjeff{
322219820Sjeff	_db_node_t *node = NULL;
323219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
324219820Sjeff
325219820Sjeff	cl_plock_acquire(&(db->lock));
326219820Sjeff
327219820Sjeff	node = _get(db, guid);
328219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
329219820Sjeff		goto Exit;
330219820Sjeff
331219820Sjeff	*reading = node->ports[port].err_previous;
332219820Sjeff
333219820SjeffExit:
334219820Sjeff	cl_plock_release(&(db->lock));
335219820Sjeff	return (rc);
336219820Sjeff}
337219820Sjeff
338219820Sjeffperfmgr_db_err_t
339219820Sjeffperfmgr_db_clear_prev_err(perfmgr_db_t * db, uint64_t guid, uint8_t port)
340219820Sjeff{
341219820Sjeff	_db_node_t *node = NULL;
342219820Sjeff	perfmgr_db_err_reading_t *previous = NULL;
343219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
344219820Sjeff
345219820Sjeff	cl_plock_excl_acquire(&(db->lock));
346219820Sjeff	node = _get(db, guid);
347219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
348219820Sjeff		goto Exit;
349219820Sjeff
350219820Sjeff	previous = &(node->ports[port].err_previous);
351219820Sjeff
352219820Sjeff	memset(previous, 0, sizeof(*previous));
353219820Sjeff	node->ports[port].err_previous.time = time(NULL);
354219820Sjeff
355219820SjeffExit:
356219820Sjeff	cl_plock_release(&(db->lock));
357219820Sjeff	return (rc);
358219820Sjeff}
359219820Sjeff
360219820Sjeffstatic inline void
361219820Sjeffdebug_dump_dc_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num,
362219820Sjeff		      _db_port_t * port, perfmgr_db_data_cnt_reading_t * cur)
363219820Sjeff{
364219820Sjeff	osm_log_t *log = db->perfmgr->log;
365219820Sjeff	if (!osm_log_is_active(log, OSM_LOG_DEBUG))
366219820Sjeff		return;		/* optimize this a big */
367219820Sjeff
368219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
369219820Sjeff		"xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
370219820Sjeff		cur->xmit_data, port->dc_previous.xmit_data,
371219820Sjeff		port->dc_total.xmit_data);
372219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
373219820Sjeff		"rd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_data,
374219820Sjeff		port->dc_previous.rcv_data, port->dc_total.rcv_data);
375219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
376219820Sjeff		"xp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
377219820Sjeff		cur->xmit_pkts, port->dc_previous.xmit_pkts,
378219820Sjeff		port->dc_total.xmit_pkts);
379219820Sjeff	osm_log(log, OSM_LOG_DEBUG,
380219820Sjeff		"rp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_pkts,
381219820Sjeff		port->dc_previous.rcv_pkts, port->dc_total.rcv_pkts);
382219820Sjeff}
383219820Sjeff
384219820Sjeff/**********************************************************************
385219820Sjeff * perfmgr_db_data_cnt_reading_t functions
386219820Sjeff **********************************************************************/
387219820Sjeffperfmgr_db_err_t
388219820Sjeffperfmgr_db_add_dc_reading(perfmgr_db_t * db, uint64_t guid,
389219820Sjeff			  uint8_t port, perfmgr_db_data_cnt_reading_t * reading)
390219820Sjeff{
391219820Sjeff	_db_port_t *p_port = NULL;
392219820Sjeff	_db_node_t *node = NULL;
393219820Sjeff	perfmgr_db_data_cnt_reading_t *previous = NULL;
394219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
395219820Sjeff	osm_epi_dc_event_t epi_dc_data;
396219820Sjeff
397219820Sjeff	cl_plock_excl_acquire(&(db->lock));
398219820Sjeff	node = _get(db, guid);
399219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
400219820Sjeff		goto Exit;
401219820Sjeff
402219820Sjeff	p_port = &(node->ports[port]);
403219820Sjeff	previous = &(node->ports[port].dc_previous);
404219820Sjeff
405219820Sjeff	debug_dump_dc_reading(db, guid, port, p_port, reading);
406219820Sjeff
407219820Sjeff	epi_dc_data.time_diff_s = (reading->time - previous->time);
408219820Sjeff	osm_epi_create_port_id(&(epi_dc_data.port_id), guid, port,
409219820Sjeff			       node->node_name);
410219820Sjeff
411219820Sjeff	/* calculate changes from previous reading */
412219820Sjeff	epi_dc_data.xmit_data = (reading->xmit_data - previous->xmit_data);
413219820Sjeff	p_port->dc_total.xmit_data += epi_dc_data.xmit_data;
414219820Sjeff	epi_dc_data.rcv_data = (reading->rcv_data - previous->rcv_data);
415219820Sjeff	p_port->dc_total.rcv_data += epi_dc_data.rcv_data;
416219820Sjeff	epi_dc_data.xmit_pkts = (reading->xmit_pkts - previous->xmit_pkts);
417219820Sjeff	p_port->dc_total.xmit_pkts += epi_dc_data.xmit_pkts;
418219820Sjeff	epi_dc_data.rcv_pkts = (reading->rcv_pkts - previous->rcv_pkts);
419219820Sjeff	p_port->dc_total.rcv_pkts += epi_dc_data.rcv_pkts;
420219820Sjeff	epi_dc_data.unicast_xmit_pkts =
421219820Sjeff	    (reading->unicast_xmit_pkts - previous->unicast_xmit_pkts);
422219820Sjeff	p_port->dc_total.unicast_xmit_pkts += epi_dc_data.unicast_xmit_pkts;
423219820Sjeff	epi_dc_data.unicast_rcv_pkts =
424219820Sjeff	    (reading->unicast_rcv_pkts - previous->unicast_rcv_pkts);
425219820Sjeff	p_port->dc_total.unicast_rcv_pkts += epi_dc_data.unicast_rcv_pkts;
426219820Sjeff	epi_dc_data.multicast_xmit_pkts =
427219820Sjeff	    (reading->multicast_xmit_pkts - previous->multicast_xmit_pkts);
428219820Sjeff	p_port->dc_total.multicast_xmit_pkts += epi_dc_data.multicast_xmit_pkts;
429219820Sjeff	epi_dc_data.multicast_rcv_pkts =
430219820Sjeff	    (reading->multicast_rcv_pkts - previous->multicast_rcv_pkts);
431219820Sjeff	p_port->dc_total.multicast_rcv_pkts += epi_dc_data.multicast_rcv_pkts;
432219820Sjeff
433219820Sjeff	p_port->dc_previous = *reading;
434219820Sjeff
435219820Sjeff	osm_opensm_report_event(db->perfmgr->osm,
436219820Sjeff				OSM_EVENT_ID_PORT_DATA_COUNTERS, &epi_dc_data);
437219820Sjeff
438219820SjeffExit:
439219820Sjeff	cl_plock_release(&(db->lock));
440219820Sjeff	return (rc);
441219820Sjeff}
442219820Sjeff
443219820Sjeffperfmgr_db_err_t perfmgr_db_get_prev_dc(perfmgr_db_t * db, uint64_t guid,
444219820Sjeff					uint8_t port,
445219820Sjeff					perfmgr_db_data_cnt_reading_t * reading)
446219820Sjeff{
447219820Sjeff	_db_node_t *node = NULL;
448219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
449219820Sjeff
450219820Sjeff	cl_plock_acquire(&(db->lock));
451219820Sjeff
452219820Sjeff	node = _get(db, guid);
453219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
454219820Sjeff		goto Exit;
455219820Sjeff
456219820Sjeff	*reading = node->ports[port].dc_previous;
457219820Sjeff
458219820SjeffExit:
459219820Sjeff	cl_plock_release(&(db->lock));
460219820Sjeff	return (rc);
461219820Sjeff}
462219820Sjeff
463219820Sjeffperfmgr_db_err_t
464219820Sjeffperfmgr_db_clear_prev_dc(perfmgr_db_t * db, uint64_t guid, uint8_t port)
465219820Sjeff{
466219820Sjeff	_db_node_t *node = NULL;
467219820Sjeff	perfmgr_db_data_cnt_reading_t *previous = NULL;
468219820Sjeff	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
469219820Sjeff
470219820Sjeff	cl_plock_excl_acquire(&(db->lock));
471219820Sjeff	node = _get(db, guid);
472219820Sjeff	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
473219820Sjeff		goto Exit;
474219820Sjeff
475219820Sjeff	previous = &(node->ports[port].dc_previous);
476219820Sjeff
477219820Sjeff	memset(previous, 0, sizeof(*previous));
478219820Sjeff	node->ports[port].dc_previous.time = time(NULL);
479219820Sjeff
480219820SjeffExit:
481219820Sjeff	cl_plock_release(&(db->lock));
482219820Sjeff	return (rc);
483219820Sjeff}
484219820Sjeff
485219820Sjeffstatic void __clear_counters(cl_map_item_t * const p_map_item, void *context)
486219820Sjeff{
487219820Sjeff	_db_node_t *node = (_db_node_t *) p_map_item;
488219820Sjeff	int i = 0;
489219820Sjeff	time_t ts = time(NULL);
490219820Sjeff
491219820Sjeff	for (i = 0; i < node->num_ports; i++) {
492219820Sjeff		node->ports[i].err_total.symbol_err_cnt = 0;
493219820Sjeff		node->ports[i].err_total.link_err_recover = 0;
494219820Sjeff		node->ports[i].err_total.link_downed = 0;
495219820Sjeff		node->ports[i].err_total.rcv_err = 0;
496219820Sjeff		node->ports[i].err_total.rcv_rem_phys_err = 0;
497219820Sjeff		node->ports[i].err_total.rcv_switch_relay_err = 0;
498219820Sjeff		node->ports[i].err_total.xmit_discards = 0;
499219820Sjeff		node->ports[i].err_total.xmit_constraint_err = 0;
500219820Sjeff		node->ports[i].err_total.rcv_constraint_err = 0;
501219820Sjeff		node->ports[i].err_total.link_integrity = 0;
502219820Sjeff		node->ports[i].err_total.buffer_overrun = 0;
503219820Sjeff		node->ports[i].err_total.vl15_dropped = 0;
504219820Sjeff		node->ports[i].err_total.time = ts;
505219820Sjeff
506219820Sjeff		node->ports[i].dc_total.xmit_data = 0;
507219820Sjeff		node->ports[i].dc_total.rcv_data = 0;
508219820Sjeff		node->ports[i].dc_total.xmit_pkts = 0;
509219820Sjeff		node->ports[i].dc_total.rcv_pkts = 0;
510219820Sjeff		node->ports[i].dc_total.unicast_xmit_pkts = 0;
511219820Sjeff		node->ports[i].dc_total.unicast_rcv_pkts = 0;
512219820Sjeff		node->ports[i].dc_total.multicast_xmit_pkts = 0;
513219820Sjeff		node->ports[i].dc_total.multicast_rcv_pkts = 0;
514219820Sjeff		node->ports[i].dc_total.time = ts;
515219820Sjeff
516219820Sjeff		node->ports[i].last_reset = ts;
517219820Sjeff	}
518219820Sjeff}
519219820Sjeff
520219820Sjeff/**********************************************************************
521219820Sjeff * Clear all the counters from the db
522219820Sjeff **********************************************************************/
523219820Sjeffvoid perfmgr_db_clear_counters(perfmgr_db_t * db)
524219820Sjeff{
525219820Sjeff	cl_plock_excl_acquire(&(db->lock));
526219820Sjeff	cl_qmap_apply_func(&(db->pc_data), __clear_counters, (void *)db);
527219820Sjeff	cl_plock_release(&(db->lock));
528219820Sjeff#if 0
529219820Sjeff	if (db->db_impl->clear_counters)
530219820Sjeff		db->db_impl->clear_counters(db->db_data);
531219820Sjeff#endif
532219820Sjeff}
533219820Sjeff
534219820Sjeff/**********************************************************************
535219820Sjeff * Output a tab delimited output of the port counters
536219820Sjeff **********************************************************************/
537219820Sjeffstatic void __dump_node_mr(_db_node_t * node, FILE * fp)
538219820Sjeff{
539219820Sjeff	int i = 0;
540219820Sjeff
541219820Sjeff	fprintf(fp, "\nName\tGUID\tPort\tLast Reset\t"
542219820Sjeff		"%s\t%s\t"
543219820Sjeff		"%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
544219820Sjeff		"%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
545219820Sjeff		"%s\t%s\t%s\t%s\n",
546219820Sjeff		"symbol_err_cnt",
547219820Sjeff		"link_err_recover",
548219820Sjeff		"link_downed",
549219820Sjeff		"rcv_err",
550219820Sjeff		"rcv_rem_phys_err",
551219820Sjeff		"rcv_switch_relay_err",
552219820Sjeff		"xmit_discards",
553219820Sjeff		"xmit_constraint_err",
554219820Sjeff		"rcv_constraint_err",
555219820Sjeff		"link_int_err",
556219820Sjeff		"buf_overrun_err",
557219820Sjeff		"vl15_dropped",
558219820Sjeff		"xmit_data",
559219820Sjeff		"rcv_data",
560219820Sjeff		"xmit_pkts",
561219820Sjeff		"rcv_pkts",
562219820Sjeff		"unicast_xmit_pkts",
563219820Sjeff		"unicast_rcv_pkts",
564219820Sjeff		"multicast_xmit_pkts", "multicast_rcv_pkts");
565219820Sjeff	for (i = 1; i < node->num_ports; i++) {
566219820Sjeff		char *since = ctime(&(node->ports[i].last_reset));
567219820Sjeff		since[strlen(since) - 1] = '\0';	/* remove \n */
568219820Sjeff
569219820Sjeff		fprintf(fp,
570219820Sjeff			"%s\t0x%" PRIx64 "\t%d\t%s\t%" PRIu64 "\t%" PRIu64 "\t"
571219820Sjeff			"%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t"
572219820Sjeff			"%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64
573219820Sjeff			"\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
574219820Sjeff			"\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
575219820Sjeff			"\t%" PRIu64 "\t%" PRIu64 "\n", node->node_name,
576219820Sjeff			node->node_guid, i, since,
577219820Sjeff			node->ports[i].err_total.symbol_err_cnt,
578219820Sjeff			node->ports[i].err_total.link_err_recover,
579219820Sjeff			node->ports[i].err_total.link_downed,
580219820Sjeff			node->ports[i].err_total.rcv_err,
581219820Sjeff			node->ports[i].err_total.rcv_rem_phys_err,
582219820Sjeff			node->ports[i].err_total.rcv_switch_relay_err,
583219820Sjeff			node->ports[i].err_total.xmit_discards,
584219820Sjeff			node->ports[i].err_total.xmit_constraint_err,
585219820Sjeff			node->ports[i].err_total.rcv_constraint_err,
586219820Sjeff			node->ports[i].err_total.link_integrity,
587219820Sjeff			node->ports[i].err_total.buffer_overrun,
588219820Sjeff			node->ports[i].err_total.vl15_dropped,
589219820Sjeff			node->ports[i].dc_total.xmit_data,
590219820Sjeff			node->ports[i].dc_total.rcv_data,
591219820Sjeff			node->ports[i].dc_total.xmit_pkts,
592219820Sjeff			node->ports[i].dc_total.rcv_pkts,
593219820Sjeff			node->ports[i].dc_total.unicast_xmit_pkts,
594219820Sjeff			node->ports[i].dc_total.unicast_rcv_pkts,
595219820Sjeff			node->ports[i].dc_total.multicast_xmit_pkts,
596219820Sjeff			node->ports[i].dc_total.multicast_rcv_pkts);
597219820Sjeff	}
598219820Sjeff}
599219820Sjeff
600219820Sjeff/**********************************************************************
601219820Sjeff * Output a human readable output of the port counters
602219820Sjeff **********************************************************************/
603219820Sjeffstatic void __dump_node_hr(_db_node_t * node, FILE * fp)
604219820Sjeff{
605219820Sjeff	int i = 0;
606219820Sjeff
607219820Sjeff	fprintf(fp, "\n");
608219820Sjeff	for (i = 1; i < node->num_ports; i++) {
609219820Sjeff		char *since = ctime(&(node->ports[i].last_reset));
610219820Sjeff		since[strlen(since) - 1] = '\0';	/* remove \n */
611219820Sjeff
612219820Sjeff		fprintf(fp, "\"%s\" 0x%" PRIx64 " port %d (Since %s)\n"
613219820Sjeff			"     symbol_err_cnt       : %" PRIu64 "\n"
614219820Sjeff			"     link_err_recover     : %" PRIu64 "\n"
615219820Sjeff			"     link_downed          : %" PRIu64 "\n"
616219820Sjeff			"     rcv_err              : %" PRIu64 "\n"
617219820Sjeff			"     rcv_rem_phys_err     : %" PRIu64 "\n"
618219820Sjeff			"     rcv_switch_relay_err : %" PRIu64 "\n"
619219820Sjeff			"     xmit_discards        : %" PRIu64 "\n"
620219820Sjeff			"     xmit_constraint_err  : %" PRIu64 "\n"
621219820Sjeff			"     rcv_constraint_err   : %" PRIu64 "\n"
622219820Sjeff			"     link_integrity_err   : %" PRIu64 "\n"
623219820Sjeff			"     buf_overrun_err      : %" PRIu64 "\n"
624219820Sjeff			"     vl15_dropped         : %" PRIu64 "\n"
625219820Sjeff			"     xmit_data            : %" PRIu64 "\n"
626219820Sjeff			"     rcv_data             : %" PRIu64 "\n"
627219820Sjeff			"     xmit_pkts            : %" PRIu64 "\n"
628219820Sjeff			"     rcv_pkts             : %" PRIu64 "\n"
629219820Sjeff			"     unicast_xmit_pkts    : %" PRIu64 "\n"
630219820Sjeff			"     unicast_rcv_pkts     : %" PRIu64 "\n"
631219820Sjeff			"     multicast_xmit_pkts  : %" PRIu64 "\n"
632219820Sjeff			"     multicast_rcv_pkts   : %" PRIu64 "\n",
633219820Sjeff			node->node_name,
634219820Sjeff			node->node_guid,
635219820Sjeff			i,
636219820Sjeff			since,
637219820Sjeff			node->ports[i].err_total.symbol_err_cnt,
638219820Sjeff			node->ports[i].err_total.link_err_recover,
639219820Sjeff			node->ports[i].err_total.link_downed,
640219820Sjeff			node->ports[i].err_total.rcv_err,
641219820Sjeff			node->ports[i].err_total.rcv_rem_phys_err,
642219820Sjeff			node->ports[i].err_total.rcv_switch_relay_err,
643219820Sjeff			node->ports[i].err_total.xmit_discards,
644219820Sjeff			node->ports[i].err_total.xmit_constraint_err,
645219820Sjeff			node->ports[i].err_total.rcv_constraint_err,
646219820Sjeff			node->ports[i].err_total.link_integrity,
647219820Sjeff			node->ports[i].err_total.buffer_overrun,
648219820Sjeff			node->ports[i].err_total.vl15_dropped,
649219820Sjeff			node->ports[i].dc_total.xmit_data,
650219820Sjeff			node->ports[i].dc_total.rcv_data,
651219820Sjeff			node->ports[i].dc_total.xmit_pkts,
652219820Sjeff			node->ports[i].dc_total.rcv_pkts,
653219820Sjeff			node->ports[i].dc_total.unicast_xmit_pkts,
654219820Sjeff			node->ports[i].dc_total.unicast_rcv_pkts,
655219820Sjeff			node->ports[i].dc_total.multicast_xmit_pkts,
656219820Sjeff			node->ports[i].dc_total.multicast_rcv_pkts);
657219820Sjeff	}
658219820Sjeff}
659219820Sjeff
660219820Sjeff/* Define a context for the __db_dump callback */
661219820Sjefftypedef struct {
662219820Sjeff	FILE *fp;
663219820Sjeff	perfmgr_db_dump_t dump_type;
664219820Sjeff} dump_context_t;
665219820Sjeff
666219820Sjeff/**********************************************************************
667219820Sjeff **********************************************************************/
668219820Sjeffstatic void __db_dump(cl_map_item_t * const p_map_item, void *context)
669219820Sjeff{
670219820Sjeff	_db_node_t *node = (_db_node_t *) p_map_item;
671219820Sjeff	dump_context_t *c = (dump_context_t *) context;
672219820Sjeff	FILE *fp = c->fp;
673219820Sjeff
674219820Sjeff	switch (c->dump_type) {
675219820Sjeff	case PERFMGR_EVENT_DB_DUMP_MR:
676219820Sjeff		__dump_node_mr(node, fp);
677219820Sjeff		break;
678219820Sjeff	case PERFMGR_EVENT_DB_DUMP_HR:
679219820Sjeff	default:
680219820Sjeff		__dump_node_hr(node, fp);
681219820Sjeff		break;
682219820Sjeff	}
683219820Sjeff}
684219820Sjeff
685219820Sjeff/**********************************************************************
686219820Sjeff * print node data to fp
687219820Sjeff **********************************************************************/
688219820Sjeffvoid
689219820Sjeffperfmgr_db_print_by_name(perfmgr_db_t * db, char *nodename, FILE *fp)
690219820Sjeff{
691219820Sjeff	cl_map_item_t *item = NULL;
692219820Sjeff	_db_node_t *node = NULL;
693219820Sjeff
694219820Sjeff	cl_plock_acquire(&(db->lock));
695219820Sjeff
696219820Sjeff	/* find the node */
697219820Sjeff	item = cl_qmap_head(&(db->pc_data));
698219820Sjeff	while (item != cl_qmap_end(&(db->pc_data))) {
699219820Sjeff		node = (_db_node_t *)item;
700219820Sjeff		if (strcmp(node->node_name, nodename) == 0) {
701219820Sjeff			__dump_node_hr(node, fp);
702219820Sjeff			goto done;
703219820Sjeff		}
704219820Sjeff		item = cl_qmap_next(item);
705219820Sjeff	}
706219820Sjeff
707219820Sjeff	fprintf(fp, "Node %s not found...\n", nodename);
708219820Sjeffdone:
709219820Sjeff	cl_plock_release(&(db->lock));
710219820Sjeff}
711219820Sjeff
712219820Sjeff/**********************************************************************
713219820Sjeff * print node data to fp
714219820Sjeff **********************************************************************/
715219820Sjeffvoid
716219820Sjeffperfmgr_db_print_by_guid(perfmgr_db_t * db, uint64_t nodeguid, FILE *fp)
717219820Sjeff{
718219820Sjeff	cl_map_item_t *node = NULL;
719219820Sjeff
720219820Sjeff	cl_plock_acquire(&(db->lock));
721219820Sjeff
722219820Sjeff	node = cl_qmap_get(&(db->pc_data), nodeguid);
723219820Sjeff	if (node != cl_qmap_end(&(db->pc_data)))
724219820Sjeff		__dump_node_hr((_db_node_t *)node, fp);
725219820Sjeff	else
726219820Sjeff		fprintf(fp, "Node %"PRIx64" not found...\n", nodeguid);
727219820Sjeff
728219820Sjeff	cl_plock_release(&(db->lock));
729219820Sjeff}
730219820Sjeff
731219820Sjeff/**********************************************************************
732219820Sjeff * dump the data to the file "file"
733219820Sjeff **********************************************************************/
734219820Sjeffperfmgr_db_err_t
735219820Sjeffperfmgr_db_dump(perfmgr_db_t * db, char *file, perfmgr_db_dump_t dump_type)
736219820Sjeff{
737219820Sjeff	dump_context_t context;
738219820Sjeff
739219820Sjeff	context.fp = fopen(file, "w+");
740219820Sjeff	if (!context.fp)
741219820Sjeff		return (PERFMGR_EVENT_DB_FAIL);
742219820Sjeff	context.dump_type = dump_type;
743219820Sjeff
744219820Sjeff	cl_plock_acquire(&(db->lock));
745219820Sjeff	cl_qmap_apply_func(&(db->pc_data), __db_dump, (void *)&context);
746219820Sjeff	cl_plock_release(&(db->lock));
747219820Sjeff	fclose(context.fp);
748219820Sjeff	return (PERFMGR_EVENT_DB_SUCCESS);
749219820Sjeff}
750219820Sjeff
751219820Sjeff/**********************************************************************
752219820Sjeff * Fill in the various DB objects from their wire counter parts
753219820Sjeff **********************************************************************/
754219820Sjeffvoid
755219820Sjeffperfmgr_db_fill_err_read(ib_port_counters_t * wire_read,
756219820Sjeff			 perfmgr_db_err_reading_t * reading)
757219820Sjeff{
758219820Sjeff	reading->symbol_err_cnt = cl_ntoh16(wire_read->symbol_err_cnt);
759219820Sjeff	reading->link_err_recover = cl_ntoh16(wire_read->link_err_recover);
760219820Sjeff	reading->link_downed = wire_read->link_downed;
761219820Sjeff	reading->rcv_err = wire_read->rcv_err;
762219820Sjeff	reading->rcv_rem_phys_err = cl_ntoh16(wire_read->rcv_rem_phys_err);
763219820Sjeff	reading->rcv_switch_relay_err =
764219820Sjeff	    cl_ntoh16(wire_read->rcv_switch_relay_err);
765219820Sjeff	reading->xmit_discards = cl_ntoh16(wire_read->xmit_discards);
766219820Sjeff	reading->xmit_constraint_err =
767219820Sjeff	    cl_ntoh16(wire_read->xmit_constraint_err);
768219820Sjeff	reading->rcv_constraint_err = wire_read->rcv_constraint_err;
769219820Sjeff	reading->link_integrity =
770219820Sjeff	    PC_LINK_INT(wire_read->link_int_buffer_overrun);
771219820Sjeff	reading->buffer_overrun =
772219820Sjeff	    PC_BUF_OVERRUN(wire_read->link_int_buffer_overrun);
773219820Sjeff	reading->vl15_dropped = cl_ntoh16(wire_read->vl15_dropped);
774219820Sjeff	reading->time = time(NULL);
775219820Sjeff}
776219820Sjeff
777219820Sjeffvoid
778219820Sjeffperfmgr_db_fill_data_cnt_read_pc(ib_port_counters_t * wire_read,
779219820Sjeff				 perfmgr_db_data_cnt_reading_t * reading)
780219820Sjeff{
781219820Sjeff	reading->xmit_data = cl_ntoh32(wire_read->xmit_data);
782219820Sjeff	reading->rcv_data = cl_ntoh32(wire_read->rcv_data);
783219820Sjeff	reading->xmit_pkts = cl_ntoh32(wire_read->xmit_pkts);
784219820Sjeff	reading->rcv_pkts = cl_ntoh32(wire_read->rcv_pkts);
785219820Sjeff	reading->unicast_xmit_pkts = 0;
786219820Sjeff	reading->unicast_rcv_pkts = 0;
787219820Sjeff	reading->multicast_xmit_pkts = 0;
788219820Sjeff	reading->multicast_rcv_pkts = 0;
789219820Sjeff	reading->time = time(NULL);
790219820Sjeff}
791219820Sjeff
792219820Sjeffvoid
793219820Sjeffperfmgr_db_fill_data_cnt_read_epc(ib_port_counters_ext_t * wire_read,
794219820Sjeff				  perfmgr_db_data_cnt_reading_t * reading)
795219820Sjeff{
796219820Sjeff	reading->xmit_data = cl_ntoh64(wire_read->xmit_data);
797219820Sjeff	reading->rcv_data = cl_ntoh64(wire_read->rcv_data);
798219820Sjeff	reading->xmit_pkts = cl_ntoh64(wire_read->xmit_pkts);
799219820Sjeff	reading->rcv_pkts = cl_ntoh64(wire_read->rcv_pkts);
800219820Sjeff	reading->unicast_xmit_pkts = cl_ntoh64(wire_read->unicast_xmit_pkts);
801219820Sjeff	reading->unicast_rcv_pkts = cl_ntoh64(wire_read->unicast_rcv_pkts);
802219820Sjeff	reading->multicast_xmit_pkts =
803219820Sjeff	    cl_ntoh64(wire_read->multicast_xmit_pkts);
804219820Sjeff	reading->multicast_rcv_pkts = cl_ntoh64(wire_read->multicast_rcv_pkts);
805219820Sjeff	reading->time = time(NULL);
806219820Sjeff}
807219820Sjeff#endif				/* ENABLE_OSM_PERF_MGR */
808