Oops, forgot to attach the patch.  Here it is.

Al

On Fri, 2008-10-10 at 16:02 -0700, Al Chu wrote:
> Hey Sasha,
> 
> And finally the big patch.  If -a is specified and AllPortSelect is not
> supported (and -l isn't specified) loop through all ports and aggregate
> them into one output.
> 
> So the patch is a tad lengthy given the manual packet parsing/counting
> that had to be done.  I'm not aware of any libs/helper funcs in OFED
> that could have made this code shorter.  Please let me know if there are
> some obvious funcs that could make this better. 
> 
> Also, my understanding is that in IB, counters don't wrap around.  When
> they get to the max they stay at the max.  So wrap-around checks for all
> of the counters is there as I added things up.  Couldn't find some
> wrapper funcs for this in OFED already.  So hopefully I'm not repeating
> code.
> 
> Al
> 
-- 
Albert Chu
[EMAIL PROTECTED]
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
>From 5864bf543181dda556e41bfb6b7c2780faeb3035 Mon Sep 17 00:00:00 2001
From: Albert Chu <[EMAIL PROTECTED]>
Date: Thu, 9 Oct 2008 16:39:19 -0700
Subject: [PATCH] aggregate port counters for single output under --all_ports


Signed-off-by: Albert Chu <[EMAIL PROTECTED]>
---
 infiniband-diags/src/perfquery.c |  238 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 229 insertions(+), 9 deletions(-)

diff --git a/infiniband-diags/src/perfquery.c b/infiniband-diags/src/perfquery.c
index 69a00d4..6e5359c 100644
--- a/infiniband-diags/src/perfquery.c
+++ b/infiniband-diags/src/perfquery.c
@@ -49,8 +49,45 @@
 
 #include "ibdiag_common.h"
 
+struct perf_count {
+	uint32_t portselect;
+	uint32_t counterselect;
+	uint32_t symbolerrors;
+	uint32_t linkrecovers;
+	uint32_t linkdowned;
+	uint32_t rcverrors;
+	uint32_t rcvremotephyerrors;
+	uint32_t rcvswrelayerrors;
+	uint32_t xmtdiscards;
+	uint32_t xmtconstrainterrors;
+	uint32_t rcvconstrainterrors;
+	uint32_t linkintegrityerrors;
+	uint32_t excbufoverrunerrors;
+	uint32_t vl15dropped;
+	uint32_t xmtdata;
+	uint32_t rcvdata;
+	uint32_t xmtpkts;
+	uint32_t rcvpkts;
+};
+
+struct perf_count_ext {
+	uint32_t portselect;
+	uint32_t counterselect;
+	uint64_t portxmitdata;
+	uint64_t portrcvdata;
+	uint64_t portxmitpkts;
+	uint64_t portrcvpkts;
+	uint64_t portunicastxmitpkts;
+	uint64_t portunicastrcvpkts;
+	uint64_t portmulticastxmitpkits;
+	uint64_t portmulticastrcvpkts;
+};
+
 static uint8_t pc[1024];
 
+struct perf_count perf_count = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+struct perf_count_ext perf_count_ext = {0,0,0,0,0,0,0,0,0,0};
+
 char *argv0 = "perfquery";
 
 #define ALL_PORTS 0xFF
@@ -83,27 +120,203 @@ usage(void)
 	exit(-1);
 }
 
-static void dump_perfcounters(int extended, int timeout,
-			      uint16_t cap_mask, ib_portid_t *portid, int port)
+/* Notes: IB semantics is to cap counters if count has exceeded limits.
+ * Therefore we must check for overflows and cap the counters if necessary.
+ * 
+ * mad_decode_field and mad_encode_field assume 32 bit integers passed in
+ * for fields < 32 bits in length.
+ */
+
+static void aggregate_4bit(uint32_t *dest, uint32_t val)
+{
+	if ((((*dest) + val) < (*dest))
+	    || ((*dest) + val) > 0xf)
+		(*dest) = 0xf;
+	else
+		(*dest) = (*dest) + val;
+}
+
+static void aggregate_8bit(uint32_t *dest, uint32_t val)
+{
+	if ((((*dest) + val) < (*dest))
+	    || ((*dest) + val) > 0xff)
+		(*dest) = 0xff;
+	else
+		(*dest) = (*dest) + val;
+}
+
+static void aggregate_16bit(uint32_t *dest, uint32_t val)
+{
+	if ((((*dest) + val) < (*dest))
+	    || ((*dest) + val) > 0xffff)
+		(*dest) = 0xffff;
+	else
+		(*dest) = (*dest) + val;
+}
+
+static void aggregate_32bit(uint32_t *dest, uint32_t val)
+{
+	if (((*dest) + val) < (*dest))
+		(*dest) = 0xffffffff;
+	else
+		(*dest) = (*dest) + val;
+}
+
+static void aggregate_64bit(uint64_t *dest, uint64_t val)
+{
+	if (((*dest) + val) < (*dest))
+		(*dest) = 0xffffffffffffffff;
+	else
+		(*dest) = (*dest) + val;
+}
+
+static void aggregate_perfcounters(void)
+{
+	uint32_t val;
+
+	mad_decode_field(pc, IB_PC_PORT_SELECT_F, &val);
+	perf_count.portselect = val;
+        mad_decode_field(pc, IB_PC_COUNTER_SELECT_F, &val);
+	perf_count.counterselect = val;
+        mad_decode_field(pc, IB_PC_ERR_SYM_F, &val);
+	aggregate_16bit(&perf_count.symbolerrors, val);
+        mad_decode_field(pc, IB_PC_LINK_RECOVERS_F, &val);
+	aggregate_8bit(&perf_count.linkrecovers, val);
+        mad_decode_field(pc, IB_PC_LINK_DOWNED_F, &val);
+	aggregate_8bit(&perf_count.linkdowned, val);
+        mad_decode_field(pc, IB_PC_ERR_RCV_F, &val);
+	aggregate_16bit(&perf_count.rcverrors, val);
+        mad_decode_field(pc, IB_PC_ERR_PHYSRCV_F, &val);
+	aggregate_16bit(&perf_count.rcvremotephyerrors, val);
+        mad_decode_field(pc, IB_PC_ERR_SWITCH_REL_F, &val);
+	aggregate_16bit(&perf_count.rcvswrelayerrors, val);
+        mad_decode_field(pc, IB_PC_XMT_DISCARDS_F, &val);
+	aggregate_16bit(&perf_count.xmtdiscards, val);
+        mad_decode_field(pc, IB_PC_ERR_XMTCONSTR_F, &val);
+	aggregate_8bit(&perf_count.xmtconstrainterrors, val);
+        mad_decode_field(pc, IB_PC_ERR_RCVCONSTR_F, &val);
+	aggregate_8bit(&perf_count.rcvconstrainterrors, val);
+        mad_decode_field(pc, IB_PC_ERR_LOCALINTEG_F, &val);
+	aggregate_4bit(&perf_count.linkintegrityerrors, val);
+        mad_decode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &val);
+	aggregate_4bit(&perf_count.excbufoverrunerrors, val);
+        mad_decode_field(pc, IB_PC_VL15_DROPPED_F, &val);
+	aggregate_16bit(&perf_count.vl15dropped, val);
+        mad_decode_field(pc, IB_PC_XMT_BYTES_F, &val);
+	aggregate_32bit(&perf_count.xmtdata, val);
+        mad_decode_field(pc, IB_PC_RCV_BYTES_F, &val);
+	aggregate_32bit(&perf_count.rcvdata, val);
+        mad_decode_field(pc, IB_PC_XMT_PKTS_F, &val);
+	aggregate_32bit(&perf_count.xmtpkts, val);
+        mad_decode_field(pc, IB_PC_RCV_PKTS_F, &val);
+	aggregate_32bit(&perf_count.rcvpkts, val);
+}
+
+static void output_aggregate_perfcounters(ib_portid_t *portid)
+{
+	char buf[1024];
+	uint32_t val = ALL_PORTS;
+
+	/* set port_select to 255 to emulate AllPortSelect */
+	mad_encode_field(pc, IB_PC_PORT_SELECT_F, &val); 
+	mad_encode_field(pc, IB_PC_COUNTER_SELECT_F, &perf_count.counterselect);
+	mad_encode_field(pc, IB_PC_ERR_SYM_F, &perf_count.symbolerrors);
+	mad_encode_field(pc, IB_PC_LINK_RECOVERS_F, &perf_count.linkrecovers);
+	mad_encode_field(pc, IB_PC_LINK_DOWNED_F, &perf_count.linkdowned);
+	mad_encode_field(pc, IB_PC_ERR_RCV_F, &perf_count.rcverrors);
+	mad_encode_field(pc, IB_PC_ERR_PHYSRCV_F, &perf_count.rcvremotephyerrors);
+	mad_encode_field(pc, IB_PC_ERR_SWITCH_REL_F, &perf_count.rcvswrelayerrors);
+	mad_encode_field(pc, IB_PC_XMT_DISCARDS_F, &perf_count.xmtdiscards);
+	mad_encode_field(pc, IB_PC_ERR_XMTCONSTR_F, &perf_count.xmtconstrainterrors);
+	mad_encode_field(pc, IB_PC_ERR_RCVCONSTR_F, &perf_count.rcvconstrainterrors);
+	mad_encode_field(pc, IB_PC_ERR_LOCALINTEG_F, &perf_count.linkintegrityerrors);
+	mad_encode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &perf_count.excbufoverrunerrors);
+	mad_encode_field(pc, IB_PC_VL15_DROPPED_F, &perf_count.vl15dropped);
+	mad_encode_field(pc, IB_PC_XMT_BYTES_F, &perf_count.xmtdata);
+	mad_encode_field(pc, IB_PC_RCV_BYTES_F, &perf_count.rcvdata);
+	mad_encode_field(pc, IB_PC_XMT_PKTS_F, &perf_count.xmtpkts);
+	mad_encode_field(pc, IB_PC_RCV_PKTS_F, &perf_count.rcvpkts);
+
+	mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
+	
+	printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf);	
+}
+
+static void aggregate_perfcounters_ext(void)
+{
+	uint32_t val;
+	uint64_t val64;
+
+	mad_decode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
+	perf_count_ext.portselect = val;
+	mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &val);
+	perf_count_ext.counterselect = val;
+	mad_decode_field(pc, IB_PC_EXT_XMT_BYTES_F, &val64);
+	aggregate_64bit(&perf_count_ext.portxmitdata, val64);
+	mad_decode_field(pc, IB_PC_EXT_RCV_BYTES_F, &val64);
+	aggregate_64bit(&perf_count_ext.portrcvdata, val64);
+	mad_decode_field(pc, IB_PC_EXT_XMT_PKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portxmitpkts, val64);
+	mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portrcvpkts, val64);
+	mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
+	mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
+	mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
+	mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
+	aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
+}
+
+static void output_aggregate_perfcounters_ext(ib_portid_t *portid)
+{
+	char buf[1024];
+	uint32_t val = ALL_PORTS;
+
+        /* set port_select to 255 to emulate AllPortSelect */
+        mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
+	mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &perf_count_ext.counterselect);
+	mad_encode_field(pc, IB_PC_EXT_XMT_BYTES_F, &perf_count_ext.portxmitdata);
+	mad_encode_field(pc, IB_PC_EXT_RCV_BYTES_F, &perf_count_ext.portrcvdata);
+	mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F, &perf_count_ext.portxmitpkts);
+	mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts);
+	mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &perf_count_ext.portunicastxmitpkts);
+	mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &perf_count_ext.portunicastrcvpkts);
+	mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &perf_count_ext.portmulticastxmitpkits);
+	mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &perf_count_ext.portmulticastrcvpkts);
+
+	mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
+
+	printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS, buf);
+}
+
+static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask, ib_portid_t *portid, 
+			      int port, int aggregate)
 {
 	char buf[1024];
 
 	if (extended != 1) {
 		if (!port_performance_query(pc, portid, port, timeout))
 			IBERROR("perfquery");
-
-		mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
+		if (aggregate)
+			aggregate_perfcounters();
+		else
+			mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
 	} else {
 		if (!(cap_mask & 0x200)) /* 1.2 errata: bit 9 is extended counter support */
 			IBWARN("PerfMgt ClassPortInfo 0x%x extended counters not indicated\n", cap_mask);
 
 		if (!port_performance_ext_query(pc, portid, port, timeout))
 			IBERROR("perfextquery");
-
-		mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
+		if (aggregate)
+			aggregate_perfcounters_ext();
+		else
+			mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
 	}
 
-	printf("# Port counters: %s port %d\n%s", portid2str(portid), port, buf);
+	if (!aggregate)
+		printf("# Port counters: %s port %d\n%s", portid2str(portid), port, buf);
 }
 
 static void reset_counters(int extended, int timeout, int mask, ib_portid_t *portid, int port)
@@ -271,10 +484,17 @@ main(int argc, char **argv)
 
 	if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
 		for (i = start_port; i <= num_ports; i++)
-			dump_perfcounters(extended, timeout, cap_mask, &portid, i);
+			dump_perfcounters(extended, timeout, cap_mask, &portid, i,
+					  (all_ports_loop && !loop_ports));
+		if (all_ports_loop && !loop_ports) {
+			if (extended != 1)
+				output_aggregate_perfcounters(&portid);
+			else
+				output_aggregate_perfcounters_ext(&portid);
+		}
 	}
 	else
-		dump_perfcounters(extended, timeout, cap_mask, &portid, port);
+		dump_perfcounters(extended, timeout, cap_mask, &portid, port, 0);
 
 	if (!reset)
 		exit(0);
-- 
1.5.4.5

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to