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