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 */ 53perfmgr_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 */ 68void 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 **********************************************************************/ 79static 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 89static 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 */ 100static _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 124free_rc: 125 free(rc); 126 return (NULL); 127} 128 129/** ========================================================================= 130 */ 131static 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 */ 141static 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 **********************************************************************/ 153perfmgr_db_err_t 154perfmgr_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 } 172Exit: 173 cl_plock_release(&(db->lock)); 174 return (rc); 175} 176 177/********************************************************************** 178 * Dump a reading vs the previous reading to stdout 179 **********************************************************************/ 180static inline void 181debug_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 **********************************************************************/ 245perfmgr_db_err_t 246perfmgr_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 313Exit: 314 cl_plock_release(&(db->lock)); 315 return (rc); 316} 317 318perfmgr_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 333Exit: 334 cl_plock_release(&(db->lock)); 335 return (rc); 336} 337 338perfmgr_db_err_t 339perfmgr_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 355Exit: 356 cl_plock_release(&(db->lock)); 357 return (rc); 358} 359 360static inline void 361debug_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 **********************************************************************/ 387perfmgr_db_err_t 388perfmgr_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 438Exit: 439 cl_plock_release(&(db->lock)); 440 return (rc); 441} 442 443perfmgr_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 458Exit: 459 cl_plock_release(&(db->lock)); 460 return (rc); 461} 462 463perfmgr_db_err_t 464perfmgr_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 480Exit: 481 cl_plock_release(&(db->lock)); 482 return (rc); 483} 484 485static 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 **********************************************************************/ 523void 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 **********************************************************************/ 537static 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 **********************************************************************/ 603static 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 */ 661typedef struct { 662 FILE *fp; 663 perfmgr_db_dump_t dump_type; 664} dump_context_t; 665 666/********************************************************************** 667 **********************************************************************/ 668static 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 **********************************************************************/ 688void 689perfmgr_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); 708done: 709 cl_plock_release(&(db->lock)); 710} 711 712/********************************************************************** 713 * print node data to fp 714 **********************************************************************/ 715void 716perfmgr_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 **********************************************************************/ 734perfmgr_db_err_t 735perfmgr_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 **********************************************************************/ 754void 755perfmgr_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 777void 778perfmgr_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 792void 793perfmgr_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 */ 808