]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/opensm/opensm/osm_perfmgr_db.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / management / opensm / opensm / osm_perfmgr_db.c
1 /*
2  * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2007 The Regents of the University of California.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  *
33  */
34
35 #if HAVE_CONFIG_H
36 #  include <config.h>
37 #endif                          /* HAVE_CONFIG_H */
38
39 #ifdef ENABLE_OSM_PERF_MGR
40
41 #include <stdlib.h>
42 #include <errno.h>
43 #include <limits.h>
44 #include <dlfcn.h>
45 #include <sys/stat.h>
46
47 #include <opensm/osm_perfmgr_db.h>
48 #include <opensm/osm_perfmgr.h>
49 #include <opensm/osm_opensm.h>
50
51 /** =========================================================================
52  */
53 perfmgr_db_t *perfmgr_db_construct(osm_perfmgr_t *perfmgr)
54 {
55         perfmgr_db_t *db = malloc(sizeof(*db));
56         if (!db)
57                 return (NULL);
58
59         cl_qmap_init(&(db->pc_data));
60         cl_plock_construct(&(db->lock));
61         cl_plock_init(&(db->lock));
62         db->perfmgr = perfmgr;
63         return ((void *)db);
64 }
65
66 /** =========================================================================
67  */
68 void perfmgr_db_destroy(perfmgr_db_t * db)
69 {
70         if (db) {
71                 cl_plock_destroy(&(db->lock));
72                 free(db);
73         }
74 }
75
76 /**********************************************************************
77  * Internal call db->lock should be held when calling
78  **********************************************************************/
79 static inline _db_node_t *_get(perfmgr_db_t * db, uint64_t guid)
80 {
81         cl_map_item_t *rc = cl_qmap_get(&(db->pc_data), guid);
82         const cl_map_item_t *end = cl_qmap_end(&(db->pc_data));
83
84         if (rc == end)
85                 return (NULL);
86         return ((_db_node_t *) rc);
87 }
88
89 static inline perfmgr_db_err_t bad_node_port(_db_node_t * node, uint8_t port)
90 {
91         if (!node)
92                 return (PERFMGR_EVENT_DB_GUIDNOTFOUND);
93         if (port == 0 || port >= node->num_ports)
94                 return (PERFMGR_EVENT_DB_PORTNOTFOUND);
95         return (PERFMGR_EVENT_DB_SUCCESS);
96 }
97
98 /** =========================================================================
99  */
100 static _db_node_t *__malloc_node(uint64_t guid, uint8_t num_ports, char *name)
101 {
102         int i = 0;
103         time_t cur_time = 0;
104         _db_node_t *rc = malloc(sizeof(*rc));
105         if (!rc)
106                 return (NULL);
107
108         rc->ports = calloc(num_ports, sizeof(_db_port_t));
109         if (!rc->ports)
110                 goto free_rc;
111         rc->num_ports = num_ports;
112         rc->node_guid = guid;
113
114         cur_time = time(NULL);
115         for (i = 0; i < num_ports; i++) {
116                 rc->ports[i].last_reset = cur_time;
117                 rc->ports[i].err_previous.time = cur_time;
118                 rc->ports[i].dc_previous.time = cur_time;
119         }
120         snprintf(rc->node_name, NODE_NAME_SIZE, "%s", name);
121
122         return (rc);
123
124 free_rc:
125         free(rc);
126         return (NULL);
127 }
128
129 /** =========================================================================
130  */
131 static void __free_node(_db_node_t * node)
132 {
133         if (!node)
134                 return;
135         if (node->ports)
136                 free(node->ports);
137         free(node);
138 }
139
140 /* insert nodes to the database */
141 static perfmgr_db_err_t __insert(perfmgr_db_t * db, _db_node_t * node)
142 {
143         cl_map_item_t *rc = cl_qmap_insert(&(db->pc_data), node->node_guid,
144                                            (cl_map_item_t *) node);
145
146         if ((void *)rc != (void *)node)
147                 return (PERFMGR_EVENT_DB_FAIL);
148         return (PERFMGR_EVENT_DB_SUCCESS);
149 }
150
151 /**********************************************************************
152  **********************************************************************/
153 perfmgr_db_err_t
154 perfmgr_db_create_entry(perfmgr_db_t * db, uint64_t guid,
155                         uint8_t num_ports, char *name)
156 {
157         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
158
159         cl_plock_excl_acquire(&(db->lock));
160         if (!_get(db, guid)) {
161                 _db_node_t *pc_node = __malloc_node(guid, num_ports, name);
162                 if (!pc_node) {
163                         rc = PERFMGR_EVENT_DB_NOMEM;
164                         goto Exit;
165                 }
166                 if (__insert(db, pc_node)) {
167                         __free_node(pc_node);
168                         rc = PERFMGR_EVENT_DB_FAIL;
169                         goto Exit;
170                 }
171         }
172 Exit:
173         cl_plock_release(&(db->lock));
174         return (rc);
175 }
176
177 /**********************************************************************
178  * Dump a reading vs the previous reading to stdout
179  **********************************************************************/
180 static inline void
181 debug_dump_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num,
182                        _db_port_t * port, perfmgr_db_err_reading_t * cur)
183 {
184         osm_log_t *log = db->perfmgr->log;
185
186         if (!osm_log_is_active(log, OSM_LOG_DEBUG))
187                 return;         /* optimize this a bit */
188
189         osm_log(log, OSM_LOG_DEBUG,
190                 "GUID 0x%" PRIx64 " Port %u:\n", guid, port_num);
191         osm_log(log, OSM_LOG_DEBUG,
192                 "sym %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
193                 cur->symbol_err_cnt, port->err_previous.symbol_err_cnt,
194                 port->err_total.symbol_err_cnt);
195         osm_log(log, OSM_LOG_DEBUG,
196                 "ler %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
197                 cur->link_err_recover, port->err_previous.link_err_recover,
198                 port->err_total.link_err_recover);
199         osm_log(log, OSM_LOG_DEBUG,
200                 "ld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
201                 cur->link_downed, port->err_previous.link_downed,
202                 port->err_total.link_downed);
203         osm_log(log, OSM_LOG_DEBUG,
204                 "re %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_err,
205                 port->err_previous.rcv_err, port->err_total.rcv_err);
206         osm_log(log, OSM_LOG_DEBUG,
207                 "rrp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
208                 cur->rcv_rem_phys_err, port->err_previous.rcv_rem_phys_err,
209                 port->err_total.rcv_rem_phys_err);
210         osm_log(log, OSM_LOG_DEBUG,
211                 "rsr %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
212                 cur->rcv_switch_relay_err,
213                 port->err_previous.rcv_switch_relay_err,
214                 port->err_total.rcv_switch_relay_err);
215         osm_log(log, OSM_LOG_DEBUG,
216                 "xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
217                 cur->xmit_discards, port->err_previous.xmit_discards,
218                 port->err_total.xmit_discards);
219         osm_log(log, OSM_LOG_DEBUG,
220                 "xce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
221                 cur->xmit_constraint_err,
222                 port->err_previous.xmit_constraint_err,
223                 port->err_total.xmit_constraint_err);
224         osm_log(log, OSM_LOG_DEBUG,
225                 "rce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
226                 cur->rcv_constraint_err, port->err_previous.rcv_constraint_err,
227                 port->err_total.rcv_constraint_err);
228         osm_log(log, OSM_LOG_DEBUG,
229                 "li %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
230                 cur->link_integrity, port->err_previous.link_integrity,
231                 port->err_total.link_integrity);
232         osm_log(log, OSM_LOG_DEBUG,
233                 "bo %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
234                 cur->buffer_overrun, port->err_previous.buffer_overrun,
235                 port->err_total.buffer_overrun);
236         osm_log(log, OSM_LOG_DEBUG,
237                 "vld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
238                 cur->vl15_dropped, port->err_previous.vl15_dropped,
239                 port->err_total.vl15_dropped);
240 }
241
242 /**********************************************************************
243  * perfmgr_db_err_reading_t functions
244  **********************************************************************/
245 perfmgr_db_err_t
246 perfmgr_db_add_err_reading(perfmgr_db_t * db, uint64_t guid,
247                            uint8_t port, perfmgr_db_err_reading_t * reading)
248 {
249         _db_port_t *p_port = NULL;
250         _db_node_t *node = NULL;
251         perfmgr_db_err_reading_t *previous = NULL;
252         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
253         osm_epi_pe_event_t epi_pe_data;
254
255         cl_plock_excl_acquire(&(db->lock));
256         node = _get(db, guid);
257         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
258                 goto Exit;
259
260         p_port = &(node->ports[port]);
261         previous = &(node->ports[port].err_previous);
262
263         debug_dump_err_reading(db, guid, port, p_port, reading);
264
265         epi_pe_data.time_diff_s = (reading->time - previous->time);
266         osm_epi_create_port_id(&(epi_pe_data.port_id), guid, port,
267                                node->node_name);
268
269         /* calculate changes from previous reading */
270         epi_pe_data.symbol_err_cnt =
271             (reading->symbol_err_cnt - previous->symbol_err_cnt);
272         p_port->err_total.symbol_err_cnt += epi_pe_data.symbol_err_cnt;
273         epi_pe_data.link_err_recover =
274             (reading->link_err_recover - previous->link_err_recover);
275         p_port->err_total.link_err_recover += epi_pe_data.link_err_recover;
276         epi_pe_data.link_downed =
277             (reading->link_downed - previous->link_downed);
278         p_port->err_total.link_downed += epi_pe_data.link_downed;
279         epi_pe_data.rcv_err = (reading->rcv_err - previous->rcv_err);
280         p_port->err_total.rcv_err += epi_pe_data.rcv_err;
281         epi_pe_data.rcv_rem_phys_err =
282             (reading->rcv_rem_phys_err - previous->rcv_rem_phys_err);
283         p_port->err_total.rcv_rem_phys_err += epi_pe_data.rcv_rem_phys_err;
284         epi_pe_data.rcv_switch_relay_err =
285             (reading->rcv_switch_relay_err - previous->rcv_switch_relay_err);
286         p_port->err_total.rcv_switch_relay_err +=
287             epi_pe_data.rcv_switch_relay_err;
288         epi_pe_data.xmit_discards =
289             (reading->xmit_discards - previous->xmit_discards);
290         p_port->err_total.xmit_discards += epi_pe_data.xmit_discards;
291         epi_pe_data.xmit_constraint_err =
292             (reading->xmit_constraint_err - previous->xmit_constraint_err);
293         p_port->err_total.xmit_constraint_err +=
294             epi_pe_data.xmit_constraint_err;
295         epi_pe_data.rcv_constraint_err =
296             (reading->rcv_constraint_err - previous->rcv_constraint_err);
297         p_port->err_total.rcv_constraint_err += epi_pe_data.rcv_constraint_err;
298         epi_pe_data.link_integrity =
299             (reading->link_integrity - previous->link_integrity);
300         p_port->err_total.link_integrity += epi_pe_data.link_integrity;
301         epi_pe_data.buffer_overrun =
302             (reading->buffer_overrun - previous->buffer_overrun);
303         p_port->err_total.buffer_overrun += epi_pe_data.buffer_overrun;
304         epi_pe_data.vl15_dropped =
305             (reading->vl15_dropped - previous->vl15_dropped);
306         p_port->err_total.vl15_dropped += epi_pe_data.vl15_dropped;
307
308         p_port->err_previous = *reading;
309
310         osm_opensm_report_event(db->perfmgr->osm, OSM_EVENT_ID_PORT_ERRORS,
311                                 &epi_pe_data);
312
313 Exit:
314         cl_plock_release(&(db->lock));
315         return (rc);
316 }
317
318 perfmgr_db_err_t perfmgr_db_get_prev_err(perfmgr_db_t * db, uint64_t guid,
319                                          uint8_t port,
320                                          perfmgr_db_err_reading_t * reading)
321 {
322         _db_node_t *node = NULL;
323         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
324
325         cl_plock_acquire(&(db->lock));
326
327         node = _get(db, guid);
328         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
329                 goto Exit;
330
331         *reading = node->ports[port].err_previous;
332
333 Exit:
334         cl_plock_release(&(db->lock));
335         return (rc);
336 }
337
338 perfmgr_db_err_t
339 perfmgr_db_clear_prev_err(perfmgr_db_t * db, uint64_t guid, uint8_t port)
340 {
341         _db_node_t *node = NULL;
342         perfmgr_db_err_reading_t *previous = NULL;
343         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
344
345         cl_plock_excl_acquire(&(db->lock));
346         node = _get(db, guid);
347         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
348                 goto Exit;
349
350         previous = &(node->ports[port].err_previous);
351
352         memset(previous, 0, sizeof(*previous));
353         node->ports[port].err_previous.time = time(NULL);
354
355 Exit:
356         cl_plock_release(&(db->lock));
357         return (rc);
358 }
359
360 static inline void
361 debug_dump_dc_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num,
362                       _db_port_t * port, perfmgr_db_data_cnt_reading_t * cur)
363 {
364         osm_log_t *log = db->perfmgr->log;
365         if (!osm_log_is_active(log, OSM_LOG_DEBUG))
366                 return;         /* optimize this a big */
367
368         osm_log(log, OSM_LOG_DEBUG,
369                 "xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
370                 cur->xmit_data, port->dc_previous.xmit_data,
371                 port->dc_total.xmit_data);
372         osm_log(log, OSM_LOG_DEBUG,
373                 "rd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_data,
374                 port->dc_previous.rcv_data, port->dc_total.rcv_data);
375         osm_log(log, OSM_LOG_DEBUG,
376                 "xp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
377                 cur->xmit_pkts, port->dc_previous.xmit_pkts,
378                 port->dc_total.xmit_pkts);
379         osm_log(log, OSM_LOG_DEBUG,
380                 "rp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_pkts,
381                 port->dc_previous.rcv_pkts, port->dc_total.rcv_pkts);
382 }
383
384 /**********************************************************************
385  * perfmgr_db_data_cnt_reading_t functions
386  **********************************************************************/
387 perfmgr_db_err_t
388 perfmgr_db_add_dc_reading(perfmgr_db_t * db, uint64_t guid,
389                           uint8_t port, perfmgr_db_data_cnt_reading_t * reading)
390 {
391         _db_port_t *p_port = NULL;
392         _db_node_t *node = NULL;
393         perfmgr_db_data_cnt_reading_t *previous = NULL;
394         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
395         osm_epi_dc_event_t epi_dc_data;
396
397         cl_plock_excl_acquire(&(db->lock));
398         node = _get(db, guid);
399         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
400                 goto Exit;
401
402         p_port = &(node->ports[port]);
403         previous = &(node->ports[port].dc_previous);
404
405         debug_dump_dc_reading(db, guid, port, p_port, reading);
406
407         epi_dc_data.time_diff_s = (reading->time - previous->time);
408         osm_epi_create_port_id(&(epi_dc_data.port_id), guid, port,
409                                node->node_name);
410
411         /* calculate changes from previous reading */
412         epi_dc_data.xmit_data = (reading->xmit_data - previous->xmit_data);
413         p_port->dc_total.xmit_data += epi_dc_data.xmit_data;
414         epi_dc_data.rcv_data = (reading->rcv_data - previous->rcv_data);
415         p_port->dc_total.rcv_data += epi_dc_data.rcv_data;
416         epi_dc_data.xmit_pkts = (reading->xmit_pkts - previous->xmit_pkts);
417         p_port->dc_total.xmit_pkts += epi_dc_data.xmit_pkts;
418         epi_dc_data.rcv_pkts = (reading->rcv_pkts - previous->rcv_pkts);
419         p_port->dc_total.rcv_pkts += epi_dc_data.rcv_pkts;
420         epi_dc_data.unicast_xmit_pkts =
421             (reading->unicast_xmit_pkts - previous->unicast_xmit_pkts);
422         p_port->dc_total.unicast_xmit_pkts += epi_dc_data.unicast_xmit_pkts;
423         epi_dc_data.unicast_rcv_pkts =
424             (reading->unicast_rcv_pkts - previous->unicast_rcv_pkts);
425         p_port->dc_total.unicast_rcv_pkts += epi_dc_data.unicast_rcv_pkts;
426         epi_dc_data.multicast_xmit_pkts =
427             (reading->multicast_xmit_pkts - previous->multicast_xmit_pkts);
428         p_port->dc_total.multicast_xmit_pkts += epi_dc_data.multicast_xmit_pkts;
429         epi_dc_data.multicast_rcv_pkts =
430             (reading->multicast_rcv_pkts - previous->multicast_rcv_pkts);
431         p_port->dc_total.multicast_rcv_pkts += epi_dc_data.multicast_rcv_pkts;
432
433         p_port->dc_previous = *reading;
434
435         osm_opensm_report_event(db->perfmgr->osm,
436                                 OSM_EVENT_ID_PORT_DATA_COUNTERS, &epi_dc_data);
437
438 Exit:
439         cl_plock_release(&(db->lock));
440         return (rc);
441 }
442
443 perfmgr_db_err_t perfmgr_db_get_prev_dc(perfmgr_db_t * db, uint64_t guid,
444                                         uint8_t port,
445                                         perfmgr_db_data_cnt_reading_t * reading)
446 {
447         _db_node_t *node = NULL;
448         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
449
450         cl_plock_acquire(&(db->lock));
451
452         node = _get(db, guid);
453         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
454                 goto Exit;
455
456         *reading = node->ports[port].dc_previous;
457
458 Exit:
459         cl_plock_release(&(db->lock));
460         return (rc);
461 }
462
463 perfmgr_db_err_t
464 perfmgr_db_clear_prev_dc(perfmgr_db_t * db, uint64_t guid, uint8_t port)
465 {
466         _db_node_t *node = NULL;
467         perfmgr_db_data_cnt_reading_t *previous = NULL;
468         perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
469
470         cl_plock_excl_acquire(&(db->lock));
471         node = _get(db, guid);
472         if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
473                 goto Exit;
474
475         previous = &(node->ports[port].dc_previous);
476
477         memset(previous, 0, sizeof(*previous));
478         node->ports[port].dc_previous.time = time(NULL);
479
480 Exit:
481         cl_plock_release(&(db->lock));
482         return (rc);
483 }
484
485 static void __clear_counters(cl_map_item_t * const p_map_item, void *context)
486 {
487         _db_node_t *node = (_db_node_t *) p_map_item;
488         int i = 0;
489         time_t ts = time(NULL);
490
491         for (i = 0; i < node->num_ports; i++) {
492                 node->ports[i].err_total.symbol_err_cnt = 0;
493                 node->ports[i].err_total.link_err_recover = 0;
494                 node->ports[i].err_total.link_downed = 0;
495                 node->ports[i].err_total.rcv_err = 0;
496                 node->ports[i].err_total.rcv_rem_phys_err = 0;
497                 node->ports[i].err_total.rcv_switch_relay_err = 0;
498                 node->ports[i].err_total.xmit_discards = 0;
499                 node->ports[i].err_total.xmit_constraint_err = 0;
500                 node->ports[i].err_total.rcv_constraint_err = 0;
501                 node->ports[i].err_total.link_integrity = 0;
502                 node->ports[i].err_total.buffer_overrun = 0;
503                 node->ports[i].err_total.vl15_dropped = 0;
504                 node->ports[i].err_total.time = ts;
505
506                 node->ports[i].dc_total.xmit_data = 0;
507                 node->ports[i].dc_total.rcv_data = 0;
508                 node->ports[i].dc_total.xmit_pkts = 0;
509                 node->ports[i].dc_total.rcv_pkts = 0;
510                 node->ports[i].dc_total.unicast_xmit_pkts = 0;
511                 node->ports[i].dc_total.unicast_rcv_pkts = 0;
512                 node->ports[i].dc_total.multicast_xmit_pkts = 0;
513                 node->ports[i].dc_total.multicast_rcv_pkts = 0;
514                 node->ports[i].dc_total.time = ts;
515
516                 node->ports[i].last_reset = ts;
517         }
518 }
519
520 /**********************************************************************
521  * Clear all the counters from the db
522  **********************************************************************/
523 void perfmgr_db_clear_counters(perfmgr_db_t * db)
524 {
525         cl_plock_excl_acquire(&(db->lock));
526         cl_qmap_apply_func(&(db->pc_data), __clear_counters, (void *)db);
527         cl_plock_release(&(db->lock));
528 #if 0
529         if (db->db_impl->clear_counters)
530                 db->db_impl->clear_counters(db->db_data);
531 #endif
532 }
533
534 /**********************************************************************
535  * Output a tab delimited output of the port counters
536  **********************************************************************/
537 static void __dump_node_mr(_db_node_t * node, FILE * fp)
538 {
539         int i = 0;
540
541         fprintf(fp, "\nName\tGUID\tPort\tLast Reset\t"
542                 "%s\t%s\t"
543                 "%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
544                 "%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
545                 "%s\t%s\t%s\t%s\n",
546                 "symbol_err_cnt",
547                 "link_err_recover",
548                 "link_downed",
549                 "rcv_err",
550                 "rcv_rem_phys_err",
551                 "rcv_switch_relay_err",
552                 "xmit_discards",
553                 "xmit_constraint_err",
554                 "rcv_constraint_err",
555                 "link_int_err",
556                 "buf_overrun_err",
557                 "vl15_dropped",
558                 "xmit_data",
559                 "rcv_data",
560                 "xmit_pkts",
561                 "rcv_pkts",
562                 "unicast_xmit_pkts",
563                 "unicast_rcv_pkts",
564                 "multicast_xmit_pkts", "multicast_rcv_pkts");
565         for (i = 1; i < node->num_ports; i++) {
566                 char *since = ctime(&(node->ports[i].last_reset));
567                 since[strlen(since) - 1] = '\0';        /* remove \n */
568
569                 fprintf(fp,
570                         "%s\t0x%" PRIx64 "\t%d\t%s\t%" PRIu64 "\t%" PRIu64 "\t"
571                         "%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t"
572                         "%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64
573                         "\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
574                         "\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
575                         "\t%" PRIu64 "\t%" PRIu64 "\n", node->node_name,
576                         node->node_guid, i, since,
577                         node->ports[i].err_total.symbol_err_cnt,
578                         node->ports[i].err_total.link_err_recover,
579                         node->ports[i].err_total.link_downed,
580                         node->ports[i].err_total.rcv_err,
581                         node->ports[i].err_total.rcv_rem_phys_err,
582                         node->ports[i].err_total.rcv_switch_relay_err,
583                         node->ports[i].err_total.xmit_discards,
584                         node->ports[i].err_total.xmit_constraint_err,
585                         node->ports[i].err_total.rcv_constraint_err,
586                         node->ports[i].err_total.link_integrity,
587                         node->ports[i].err_total.buffer_overrun,
588                         node->ports[i].err_total.vl15_dropped,
589                         node->ports[i].dc_total.xmit_data,
590                         node->ports[i].dc_total.rcv_data,
591                         node->ports[i].dc_total.xmit_pkts,
592                         node->ports[i].dc_total.rcv_pkts,
593                         node->ports[i].dc_total.unicast_xmit_pkts,
594                         node->ports[i].dc_total.unicast_rcv_pkts,
595                         node->ports[i].dc_total.multicast_xmit_pkts,
596                         node->ports[i].dc_total.multicast_rcv_pkts);
597         }
598 }
599
600 /**********************************************************************
601  * Output a human readable output of the port counters
602  **********************************************************************/
603 static void __dump_node_hr(_db_node_t * node, FILE * fp)
604 {
605         int i = 0;
606
607         fprintf(fp, "\n");
608         for (i = 1; i < node->num_ports; i++) {
609                 char *since = ctime(&(node->ports[i].last_reset));
610                 since[strlen(since) - 1] = '\0';        /* remove \n */
611
612                 fprintf(fp, "\"%s\" 0x%" PRIx64 " port %d (Since %s)\n"
613                         "     symbol_err_cnt       : %" PRIu64 "\n"
614                         "     link_err_recover     : %" PRIu64 "\n"
615                         "     link_downed          : %" PRIu64 "\n"
616                         "     rcv_err              : %" PRIu64 "\n"
617                         "     rcv_rem_phys_err     : %" PRIu64 "\n"
618                         "     rcv_switch_relay_err : %" PRIu64 "\n"
619                         "     xmit_discards        : %" PRIu64 "\n"
620                         "     xmit_constraint_err  : %" PRIu64 "\n"
621                         "     rcv_constraint_err   : %" PRIu64 "\n"
622                         "     link_integrity_err   : %" PRIu64 "\n"
623                         "     buf_overrun_err      : %" PRIu64 "\n"
624                         "     vl15_dropped         : %" PRIu64 "\n"
625                         "     xmit_data            : %" PRIu64 "\n"
626                         "     rcv_data             : %" PRIu64 "\n"
627                         "     xmit_pkts            : %" PRIu64 "\n"
628                         "     rcv_pkts             : %" PRIu64 "\n"
629                         "     unicast_xmit_pkts    : %" PRIu64 "\n"
630                         "     unicast_rcv_pkts     : %" PRIu64 "\n"
631                         "     multicast_xmit_pkts  : %" PRIu64 "\n"
632                         "     multicast_rcv_pkts   : %" PRIu64 "\n",
633                         node->node_name,
634                         node->node_guid,
635                         i,
636                         since,
637                         node->ports[i].err_total.symbol_err_cnt,
638                         node->ports[i].err_total.link_err_recover,
639                         node->ports[i].err_total.link_downed,
640                         node->ports[i].err_total.rcv_err,
641                         node->ports[i].err_total.rcv_rem_phys_err,
642                         node->ports[i].err_total.rcv_switch_relay_err,
643                         node->ports[i].err_total.xmit_discards,
644                         node->ports[i].err_total.xmit_constraint_err,
645                         node->ports[i].err_total.rcv_constraint_err,
646                         node->ports[i].err_total.link_integrity,
647                         node->ports[i].err_total.buffer_overrun,
648                         node->ports[i].err_total.vl15_dropped,
649                         node->ports[i].dc_total.xmit_data,
650                         node->ports[i].dc_total.rcv_data,
651                         node->ports[i].dc_total.xmit_pkts,
652                         node->ports[i].dc_total.rcv_pkts,
653                         node->ports[i].dc_total.unicast_xmit_pkts,
654                         node->ports[i].dc_total.unicast_rcv_pkts,
655                         node->ports[i].dc_total.multicast_xmit_pkts,
656                         node->ports[i].dc_total.multicast_rcv_pkts);
657         }
658 }
659
660 /* Define a context for the __db_dump callback */
661 typedef struct {
662         FILE *fp;
663         perfmgr_db_dump_t dump_type;
664 } dump_context_t;
665
666 /**********************************************************************
667  **********************************************************************/
668 static void __db_dump(cl_map_item_t * const p_map_item, void *context)
669 {
670         _db_node_t *node = (_db_node_t *) p_map_item;
671         dump_context_t *c = (dump_context_t *) context;
672         FILE *fp = c->fp;
673
674         switch (c->dump_type) {
675         case PERFMGR_EVENT_DB_DUMP_MR:
676                 __dump_node_mr(node, fp);
677                 break;
678         case PERFMGR_EVENT_DB_DUMP_HR:
679         default:
680                 __dump_node_hr(node, fp);
681                 break;
682         }
683 }
684
685 /**********************************************************************
686  * print node data to fp
687  **********************************************************************/
688 void
689 perfmgr_db_print_by_name(perfmgr_db_t * db, char *nodename, FILE *fp)
690 {
691         cl_map_item_t *item = NULL;
692         _db_node_t *node = NULL;
693
694         cl_plock_acquire(&(db->lock));
695
696         /* find the node */
697         item = cl_qmap_head(&(db->pc_data));
698         while (item != cl_qmap_end(&(db->pc_data))) {
699                 node = (_db_node_t *)item;
700                 if (strcmp(node->node_name, nodename) == 0) {
701                         __dump_node_hr(node, fp);
702                         goto done;
703                 }
704                 item = cl_qmap_next(item);
705         }
706
707         fprintf(fp, "Node %s not found...\n", nodename);
708 done:
709         cl_plock_release(&(db->lock));
710 }
711
712 /**********************************************************************
713  * print node data to fp
714  **********************************************************************/
715 void
716 perfmgr_db_print_by_guid(perfmgr_db_t * db, uint64_t nodeguid, FILE *fp)
717 {
718         cl_map_item_t *node = NULL;
719
720         cl_plock_acquire(&(db->lock));
721
722         node = cl_qmap_get(&(db->pc_data), nodeguid);
723         if (node != cl_qmap_end(&(db->pc_data)))
724                 __dump_node_hr((_db_node_t *)node, fp);
725         else
726                 fprintf(fp, "Node %"PRIx64" not found...\n", nodeguid);
727
728         cl_plock_release(&(db->lock));
729 }
730
731 /**********************************************************************
732  * dump the data to the file "file"
733  **********************************************************************/
734 perfmgr_db_err_t
735 perfmgr_db_dump(perfmgr_db_t * db, char *file, perfmgr_db_dump_t dump_type)
736 {
737         dump_context_t context;
738
739         context.fp = fopen(file, "w+");
740         if (!context.fp)
741                 return (PERFMGR_EVENT_DB_FAIL);
742         context.dump_type = dump_type;
743
744         cl_plock_acquire(&(db->lock));
745         cl_qmap_apply_func(&(db->pc_data), __db_dump, (void *)&context);
746         cl_plock_release(&(db->lock));
747         fclose(context.fp);
748         return (PERFMGR_EVENT_DB_SUCCESS);
749 }
750
751 /**********************************************************************
752  * Fill in the various DB objects from their wire counter parts
753  **********************************************************************/
754 void
755 perfmgr_db_fill_err_read(ib_port_counters_t * wire_read,
756                          perfmgr_db_err_reading_t * reading)
757 {
758         reading->symbol_err_cnt = cl_ntoh16(wire_read->symbol_err_cnt);
759         reading->link_err_recover = cl_ntoh16(wire_read->link_err_recover);
760         reading->link_downed = wire_read->link_downed;
761         reading->rcv_err = wire_read->rcv_err;
762         reading->rcv_rem_phys_err = cl_ntoh16(wire_read->rcv_rem_phys_err);
763         reading->rcv_switch_relay_err =
764             cl_ntoh16(wire_read->rcv_switch_relay_err);
765         reading->xmit_discards = cl_ntoh16(wire_read->xmit_discards);
766         reading->xmit_constraint_err =
767             cl_ntoh16(wire_read->xmit_constraint_err);
768         reading->rcv_constraint_err = wire_read->rcv_constraint_err;
769         reading->link_integrity =
770             PC_LINK_INT(wire_read->link_int_buffer_overrun);
771         reading->buffer_overrun =
772             PC_BUF_OVERRUN(wire_read->link_int_buffer_overrun);
773         reading->vl15_dropped = cl_ntoh16(wire_read->vl15_dropped);
774         reading->time = time(NULL);
775 }
776
777 void
778 perfmgr_db_fill_data_cnt_read_pc(ib_port_counters_t * wire_read,
779                                  perfmgr_db_data_cnt_reading_t * reading)
780 {
781         reading->xmit_data = cl_ntoh32(wire_read->xmit_data);
782         reading->rcv_data = cl_ntoh32(wire_read->rcv_data);
783         reading->xmit_pkts = cl_ntoh32(wire_read->xmit_pkts);
784         reading->rcv_pkts = cl_ntoh32(wire_read->rcv_pkts);
785         reading->unicast_xmit_pkts = 0;
786         reading->unicast_rcv_pkts = 0;
787         reading->multicast_xmit_pkts = 0;
788         reading->multicast_rcv_pkts = 0;
789         reading->time = time(NULL);
790 }
791
792 void
793 perfmgr_db_fill_data_cnt_read_epc(ib_port_counters_ext_t * wire_read,
794                                   perfmgr_db_data_cnt_reading_t * reading)
795 {
796         reading->xmit_data = cl_ntoh64(wire_read->xmit_data);
797         reading->rcv_data = cl_ntoh64(wire_read->rcv_data);
798         reading->xmit_pkts = cl_ntoh64(wire_read->xmit_pkts);
799         reading->rcv_pkts = cl_ntoh64(wire_read->rcv_pkts);
800         reading->unicast_xmit_pkts = cl_ntoh64(wire_read->unicast_xmit_pkts);
801         reading->unicast_rcv_pkts = cl_ntoh64(wire_read->unicast_rcv_pkts);
802         reading->multicast_xmit_pkts =
803             cl_ntoh64(wire_read->multicast_xmit_pkts);
804         reading->multicast_rcv_pkts = cl_ntoh64(wire_read->multicast_rcv_pkts);
805         reading->time = time(NULL);
806 }
807 #endif                          /* ENABLE_OSM_PERF_MGR */