From patchwork Wed Aug 22 19:02:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Perry" X-Patchwork-Id: 1362971 X-Patchwork-Delegate: hal@mellanox.com Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id EF10DDF280 for ; Wed, 22 Aug 2012 19:02:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758623Ab2HVTCH (ORCPT ); Wed, 22 Aug 2012 15:02:07 -0400 Received: from prdiron-3.llnl.gov ([128.15.143.173]:54459 "EHLO prdiron-3.llnl.gov" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758514Ab2HVTCF convert rfc822-to-8bit (ORCPT ); Wed, 22 Aug 2012 15:02:05 -0400 X-Attachments: Received: from nspexhub-2.llnl.gov (HELO nspexhub-2.the-lab.llnl.gov) ([128.115.54.114]) by prdiron-3.llnl.gov with ESMTP; 22 Aug 2012 12:02:03 -0700 Received: from NSPEXMBX-D.the-lab.llnl.gov ([128.115.54.108]) by nspexhub-2.the-lab.llnl.gov ([172.16.54.114]) with mapi; Wed, 22 Aug 2012 12:02:03 -0700 From: "Huang, Perry" To: "linux-rdma@vger.kernel.org" CC: "Chu, Al" , "alexne@mellanox.com" , "Weiny, Ira K." , "Foraker, Jim" Date: Wed, 22 Aug 2012 12:02:00 -0700 Subject: [PATCH] ibsim/sim_cmd: Add command to set perf. counters. Thread-Topic: [PATCH] ibsim/sim_cmd: Add command to set perf. counters. Thread-Index: Ac2AmJ3Xwxk2FL9qQoOSG90IC3hpXA== Message-ID: <5844B6EB-4D27-4D4A-9277-284220531169@llnl.gov> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org This patch requires: [PATCH 1/2] ibsim/sim.h: Add support for optional performance attributes. [PATCH 2/2] ibsim/sim_mad.c: Add read/reset functions for optional performance attributes. Use: PerformanceSet "nodeid"[port] [attribute].[field]=[value] eg. sim> PerformanceSet "S-0002c9020040fec8"[4] PortCounters.PortXmitPkts=125512 PortCounters.PortXmitPkts has been set to 125512 Add PerformanceSet command to enable setting performance counters (both required and optional fields). Signed-off-by: Perry Huang --- ibsim/sim_cmd.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) diff --git a/ibsim/sim_cmd.c b/ibsim/sim_cmd.c index 2da8c28..beab266 100644 --- a/ibsim/sim_cmd.c +++ b/ibsim/sim_cmd.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include "sim.h" @@ -820,6 +822,7 @@ static int dump_help(FILE * f) "\t\t\t\tSwitchInfo : 18\n" "\t\t\t\tPortInfo : 19\n" ); + fprintf(f, "\tPerformanceSet \"nodeid\"[port] [attribute].[field]=[value] : set perf. counters values\n"); fprintf(f, "\tBaselid \"nodeid\"[port] [lmc] : change port's lid (lmc)\n"); fprintf(f, "\tVerbose [newlevel] - show/set simulator verbosity\n"); @@ -843,6 +846,275 @@ static int do_disconnect_client(FILE * out, int id) return 0; } +static uint64_t check_limit(uint64_t *value, uint64_t limit) +{ + *value = (limit > *value? *value : limit); + return *value; +} + +static int parse_vl_num(char *attr, char *field, int *vl) +{ + char *vl_ptr, *end_ptr; + errno = 0; + if(strlen(field) < strlen(attr) + 1) + return -1; + vl_ptr = field + strlen(attr); + *vl = (int) strtol(vl_ptr, &end_ptr, 10); + if(*vl == 0 && (errno != 0 || vl_ptr == end_ptr)) + return -1; + else if(*vl > 15 || *vl < 0) + return -1; + return 0; +} + +static int do_perf_counter_set(FILE *f, char *line) +{ + char *s = line, *orig, *sp, *nodeid, *attr, *field, *field_trim, *val_error; + Node *node; + int portnum, vl; + uint64_t value; + char name[NAMELEN]; + Port *p; + Portcounters *pc; + + if (strsep(&s, "\"")) + orig = strsep(&s, "\""); + + if (!s) + goto format_error; + + nodeid = expand_name(orig, name, &sp); + + if (!sp && *s == '[') + sp = s + 1; + + if( !(node = find_node(nodeid))) { + fprintf(f, "# nodeid \"%s\" (%s) not found\n", orig, nodeid); + return -1; + } + + if (sp) { + portnum = strtoul(sp, 0, 0); + if (portnum < 1 || portnum > node->numports) { + fprintf(f, "# bad port number %d at nodeid \"%s\"\n", + portnum, nodeid); + return -1; + } + } + + if (!(p = node_get_port(node, portnum))) { + fprintf(f, "# port %d not found from node %s\n", portnum, nodeid); + return -1; + } + + strsep(&s, " "); + attr = strsep(&s, "."); + if(s == NULL) + goto format_error; + if(attr == NULL) { + fprintf(f, "# attribute not found in command\n"); + return -1; + } + + field = strsep(&s, "="); + if(s == NULL) + goto format_error; + if(field == NULL) { + fprintf(f, "# field not found in command\n"); + return -1; + } + field_trim = field + strlen(field) - 1; + while(field_trim > field && isspace(*field_trim)) + field_trim--; + *(field_trim + 1) = 0; + + errno = 0; + value = strtoull(s, &val_error, 0); + if((value == 0 || value == ULLONG_MAX) && errno != 0) { + fprintf(f, "# value is not valid integer\n"); + return -1; + } + if(*val_error) + { + fprintf(f, "# value %s is not valid integer\n", s); + return -1; + } + + pc = &(p->portcounters); + + if(!strcasecmp(attr, "PortCounters")) + { + if(!strcasecmp(field, "SymbolErrorCounter")) + pc->errs_sym = check_limit(&value, GS_PERF_ERR_SYM_LIMIT); + else if(!strcasecmp(field, "LinkErrorRecoveryCounter")) + pc->linkrecovers = check_limit(&value, GS_PERF_LINK_RECOVERS_LIMIT); + else if(!strcasecmp(field, "LinkDownedCounter")) + pc->linkdowned = check_limit(&value, GS_PERF_LINK_DOWNED_LIMIT); + else if(!strcasecmp(field, "PortRcvErrors")) + pc->errs_rcv = check_limit(&value, GS_PERF_ERR_RCV_LIMIT); + else if(!strcasecmp(field, "PortRcvRemotePhysicalErrors")) + pc->errs_remphysrcv = check_limit(&value, GS_PERF_ERR_PHYSRCV_LIMIT); + else if(!strcasecmp(field, "PortRcvSwitchRelayErrors")) + pc->errs_rcvswitchrelay = check_limit(&value, GS_PERF_ERR_SWITCH_REL_LIMIT); + else if(!strcasecmp(field, "PortXmitDiscards")) + pc->xmitdiscards = check_limit(&value, GS_PERF_XMT_DISCARDS_LIMIT); + else if(!strcasecmp(field, "PortXmitConstraintErrors")) + pc->errs_xmtconstraint = check_limit(&value, GS_PERF_ERR_XMTCONSTR_LIMIT); + else if(!strcasecmp(field, "PortRcvConstraintErrors")) + pc->errs_rcvconstraint = check_limit(&value, GS_PERF_ERR_RCVCONSTR_LIMIT); + else if(!strcasecmp(field, "LocalLinkIntegrityErrors")) + pc->errs_localinteg = check_limit(&value, GS_PERF_ERR_LOCALINTEG_LIMIT); + else if(!strcasecmp(field, "ExcessiveBufferOverrunErrors")) + pc->errs_excessbufovrrun = check_limit(&value, GS_PERF_ERR_EXCESS_OVR_LIMIT); + else if(!strcasecmp(field, "VL15Dropped")) + pc->vl15dropped = check_limit(&value, GS_PERF_VL15_DROPPED_LIMIT); + else if(!strcasecmp(field, "PortXmitData")) + pc->flow_xmt_bytes = check_limit(&value, GS_PERF_XMT_BYTES_LIMIT); + else if(!strcasecmp(field, "PortRcvData")) + pc->flow_rcv_bytes = check_limit(&value, GS_PERF_RCV_BYTES_LIMIT); + else if(!strcasecmp(field, "PortXmitPkts")) + pc->flow_xmt_pkts = check_limit(&value, GS_PERF_XMT_PKTS_LIMIT); + else if(!strcasecmp(field, "PortRcvPkts")) + pc->flow_rcv_pkts = check_limit(&value, GS_PERF_RCV_PKTS_LIMIT); + else if(!strcasecmp(field, "PortXmitWait")) + pc->xmt_wait = check_limit(&value, GS_PERF_XMT_WAIT_LIMIT); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortCountersExtended")) + { + if(!strcasecmp(field, "PortXmitData")) + pc->ext_xmit_data = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortRcvData")) + pc->ext_recv_data = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortXmitPkts")) + pc->ext_xmit_pkts = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortRcvPkts")) + pc->ext_recv_pkts = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortUnicastXmitPkts")) + pc->ext_ucast_xmit = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortUnicastRcvPkts")) + pc->ext_ucast_recv = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortMultiCastXmitPkts")) + pc->ext_mcast_xmit = check_limit(&value, UINT64_MAX); + else if(!strcasecmp(field, "PortMultiCastRcvPkts")) + pc->ext_mcast_recv = check_limit(&value, UINT64_MAX); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortRcvErrorDetails")) + { + if(!strcasecmp(field, "PortLocalPhysicalErrors")) + pc->rcv_error_details.PortLocalPhysicalErrors = + check_limit(&value, GS_PERF_LOCAL_PHYSICAL_ERRORS_LIMIT); + else if(!strcasecmp(field, "PortMalformedPacketErrors")) + pc->rcv_error_details.PortMalformedPacketErrors = + check_limit(&value, GS_PERF_MALFORMED_PACKET_ERRORS_LIMIT); + else if(!strcasecmp(field, "PortBufferOverrunErrors")) + pc->rcv_error_details.PortBufferOverrunErrors = + check_limit(&value, GS_PERF_BUFFER_OVERRUN_ERRORS_LIMIT); + else if(!strcasecmp(field, "PortDLIDMappingErrors")) + pc->rcv_error_details.PortDLIDMappingErrors = + check_limit(&value, GS_PERF_DLID_MAPPING_ERRORS_LIMIT); + else if(!strcasecmp(field, "PortVLMappingErrors")) + pc->rcv_error_details.PortVLMappingErrors = + check_limit(&value, GS_PERF_VL_MAPPING_ERRORS_LIMIT); + else if(!strcasecmp(field, "PortLoopingErrors")) + pc->rcv_error_details.PortLoopingErrors = + check_limit(&value, GS_PERF_LOOPING_ERRORS_LIMIT); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortXmitDiscardDetails")) + { + if(!strcasecmp(field, "PortInactiveDiscards")) + pc->xmit_discard_details.PortInactiveDiscards = + check_limit(&value, GS_PERF_INACTIVE_DISCARDS_LIMIT); + else if(!strcasecmp(field, "PortNeighborMTUDiscards")) + pc->xmit_discard_details.PortNeighborMTUDiscards = + check_limit(&value, GS_PERF_NEIGHBOR_MTU_DISCARDS_LIMIT); + else if(!strcasecmp(field, "PortSwLifetimeLimitDiscards")) + pc->xmit_discard_details.PortSwLifetimeLimitDiscards = + check_limit(&value, GS_PERF_SW_LIFETIME_LIMIT_DISCARDS_LIMIT); + else if(!strcasecmp(field, "PortSwHOQLifetimeLimitDiscards")) + pc->xmit_discard_details.PortSwHOQLifetimeLimitDiscards = + check_limit(&value, GS_PERF_SW_HOQ_LIFETIME_LIMIT_DISCARDS_LIMIT); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortOpRcvCounters")) + { + if(!strcasecmp(field, "PortOpRcvPkts")) + pc->op_rcv_counters.PortOpRcvPkts = check_limit(&value, + GS_PERF_OP_RCV_PKTS_LIMIT); + else if(!strcasecmp(field, "PortOpRcvData")) + pc->op_rcv_counters.PortOpRcvData = check_limit(&value, + GS_PERF_OP_RCV_DATA_LIMIT); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortFlowCtlCounters")) + { + if(!strcasecmp(field, "PortXmitFlowPkts")) + pc->flow_ctl_counters.PortXmitFlowPkts = + check_limit(&value, GS_PERF_XMIT_FLOW_PKTS_LIMIT); + else if(!strcasecmp(field, "PortRcvFlowPkts")) + pc->flow_ctl_counters.PortRcvFlowPkts = + check_limit(&value, GS_PERF_RCV_FLOW_PKTS_LIMIT); + else + goto field_not_found; + } + else if(!strcasecmp(attr, "PortVLOpPackets")) + { + if(strstr(field, "PortVLOpPackets") != field) + goto field_not_found; + if(parse_vl_num(attr, field, &vl) < 0) + goto field_not_found; + pc->vl_op_packets.PortVLOpPackets[vl] = + check_limit(&value, GS_PERF_VL_OP_PACKETS_LIMIT); + } + else if(!strcasecmp(attr, "PortVLOpData")) + { + if(strstr(field, "PortVLOpData") != field) + goto field_not_found; + if(parse_vl_num(attr, field, &vl) < 0) + goto field_not_found; + pc->vl_op_data.PortVLOpData[vl] = + check_limit(&value, GS_PERF_VL_OP_DATA_LIMIT); + } + else if(!strcasecmp(attr, "PortVLXmitFlowCtlUpdateErrors")) + { + if(strstr(field, "PortVLXmitFlowCtlUpdateErrors") != field) + goto field_not_found; + if(parse_vl_num(attr, field, &vl) < 0) + goto field_not_found; + pc->vl_xmit_flow_ctl_update_errors.PortVLXmitFlowCtlUpdateErrors[vl] = + check_limit(&value, GS_PERF_VL_XMIT_FLOW_CTL_UPDATE_ERRORS); + } + else if(!strcasecmp(attr, "PortVLXmitWaitCounters")) + { + if(strstr(field, "PortVLXmitWaitCounters") != field) + goto field_not_found; + if(parse_vl_num(attr, field, &vl) < 0) + goto field_not_found; + pc->vl_xmit_wait_counters.PortVLXmitWait[vl] = + check_limit(&value, GS_PERF_VL_XMIT_WAIT_COUNTERS_LIMIT); + } + else + { + fprintf(f, "# attribute %s cannot be found\n", attr); + return -1; + } + fprintf(f, "%s.%s has been set to %"PRIu64"\n", attr, field, value); + return 0; +field_not_found: + fprintf(f, "# field %s cannot be found in attribute %s\n", field, attr); + return -1; +format_error: + fprintf(f, "# command does not match: PerformanceSet \"nodeid\"[port] [attribute].[field]=[value]\n"); + return -1; +} + int netstarted; int do_cmd(char *buf, FILE *f) @@ -907,6 +1179,8 @@ int do_cmd(char *buf, FILE *f) */ else if (!strncasecmp(line, "ReLink", cmd_len)) r = do_relink(f, line); + else if (!strncasecmp(line, "PerformanceSet", cmd_len)) + r = do_perf_counter_set(f, line); else if (*line != '\n' && *line != '\0') fprintf(f, "command \'%s\' unknown - skipped\n", line);