Hey Sasha,
We have a switch here that does not report the AllPortSelect flag as a
capability. It's pretty annoying typing each port on the switch or
always having to script around this one oddball switch we have. So I
added an option --loop_ports for perfquery. If you want to do something
to all the ports on the CA/Switch, but AllPortSelect isn't available, it
loops through all the available ports instead.
There was already a workaround in the tool for a CA that did not support
the AllPortSelect flag. I get the feeling the workaround may have been
for a specific hardware, so I kept the workaround in there.
Al
--
Albert Chu
[EMAIL PROTECTED]
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
>From 6de5b57f0905ea719b4dc32508140a00704ac466 Mon Sep 17 00:00:00 2001
From: Albert Chu <[EMAIL PROTECTED]>
Date: Tue, 7 Oct 2008 14:05:54 -0700
Subject: [PATCH] support --loop_ports in perfquery
Signed-off-by: Albert Chu <[EMAIL PROTECTED]>
---
infiniband-diags/man/perfquery.8 | 12 ++++-
infiniband-diags/src/perfquery.c | 110 +++++++++++++++++++++++++-------------
2 files changed, 84 insertions(+), 38 deletions(-)
diff --git a/infiniband-diags/man/perfquery.8 b/infiniband-diags/man/perfquery.8
index 5b23d57..2f10e33 100644
--- a/infiniband-diags/man/perfquery.8
+++ b/infiniband-diags/man/perfquery.8
@@ -5,7 +5,7 @@ perfquery \- query InfiniBand port counters
.SH SYNOPSIS
.B perfquery
-[\-d(ebug)] [\-G(uid)] [-e(xtended)] [-a(ll_ports)] [-r(eset_after_read)] [-R(eset_only)] [\-C ca_name] [\-P ca_port] [\-t(imeout) timeout_ms] [\-V(ersion)] [\-h(elp)] [<lid|guid> [[port] [reset_mask]]]
+[\-d(ebug)] [\-G(uid)] [-e(xtended)] [-a(ll_ports)] [-l(oop_ports)] [-r(eset_after_read)] [-R(eset_only)] [\-C ca_name] [\-P ca_port] [\-t(imeout) timeout_ms] [\-V(ersion)] [\-h(elp)] [<lid|guid> [[port] [reset_mask]]]
.SH DESCRIPTION
.PP
@@ -32,6 +32,16 @@ Note that extended port counters attribute is optional.
show aggregated counters for all ports of the destination lid.
Note all ports support is optional.
.TP
+\fB\-l\fR, \fB\-\-loop_ports\fR
+If all ports are selected by the user (the \fB\-a\fR option or port
+255) and the node/port does not support the AllPortSelect capability,
+this option will inform perfquery to iterate through all potential
+ports instead of outputting an error. This option is particularly
+useful in combination with the \fB\-R\fR option, so that counters can
+be reset without hitting an AllPortSelect error. When used with
+outputting port counters, multiple port counter outputs will be output
+rather than a single aggregate output.
+.TP
\fB\-r\fR, \fB\-\-reset_after_read\fR
reset counters after read
.TP
diff --git a/infiniband-diags/src/perfquery.c b/infiniband-diags/src/perfquery.c
index c07acb2..0d1249e 100644
--- a/infiniband-diags/src/perfquery.c
+++ b/infiniband-diags/src/perfquery.c
@@ -65,7 +65,7 @@ usage(void)
else
basename++;
- fprintf(stderr, "Usage: %s [-d(ebug) -G(uid) -a(ll_ports) -r(eset_after_read) -C ca_name -P ca_port "
+ fprintf(stderr, "Usage: %s [-d(ebug) -G(uid) -a(ll_ports) -l(oop_ports) -r(eset_after_read) -C ca_name -P ca_port "
"-R(eset_only) -t(imeout) timeout_ms -V(ersion) -h(elp)] [<lid|guid> [[port] [reset_mask]]]\n",
basename);
fprintf(stderr, "\tExamples:\n");
@@ -83,6 +83,46 @@ usage(void)
exit(-1);
}
+static void dump_perfcounters(int extended, int allports, int timeout,
+ uint16_t cap_mask, ib_portid_t *portid, int port)
+{
+ char buf[1024];
+
+ if (extended != 1) {
+ if (!port_performance_query(pc, portid, port, timeout))
+ IBERROR("perfquery");
+
+ if (allports == 1)
+ pc[1] = ALL_PORTS; /* fake PortSelect */
+
+ 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");
+
+ if (allports == 1)
+ pc[1] = ALL_PORTS; /* fake PortSelect */
+
+ mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
+ }
+
+ 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)
+{
+ if (extended != 1) {
+ if (!port_performance_reset(pc, portid, port, mask, timeout))
+ IBERROR("perf reset");
+ } else {
+ if (!port_performance_ext_reset(pc, portid, port, mask, timeout))
+ IBERROR("perf ext reset");
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -95,17 +135,18 @@ main(int argc, char **argv)
int mask = 0xffff, all = 0;
int reset = 0, reset_only = 0;
int port = 0;
- char buf[1024];
int udebug = 0;
char *ca = 0;
int ca_port = 0;
int extended = 0;
uint16_t cap_mask;
int allports = 0;
- int node_type, num_ports;
+ int loop_ports = 0;
+ int node_type, num_ports = 0;
uint8_t data[IB_SMP_DATA_SIZE];
+ int i;
- static char const str_opts[] = "C:P:s:t:dGearRVhu";
+ static char const str_opts[] = "C:P:s:t:dGealrRVhu";
static const struct option long_opts[] = {
{ "C", 1, 0, 'C'},
{ "P", 1, 0, 'P'},
@@ -113,6 +154,7 @@ main(int argc, char **argv)
{ "Guid", 0, 0, 'G'},
{ "extended", 0, 0, 'e'},
{ "all_ports", 0, 0, 'a'},
+ { "loop_ports", 0, 0, 'l'},
{ "reset_after_read", 0, 0, 'r'},
{ "Reset_only", 0, 0, 'R'},
{ "sm_portid", 1, 0, 's'},
@@ -143,6 +185,9 @@ main(int argc, char **argv)
all++;
port = ALL_PORTS;
break;
+ case 'l':
+ loop_ports++;
+ break;
case 'd':
ibdebug++;
madrpc_show_errors(1);
@@ -218,51 +263,42 @@ main(int argc, char **argv)
if (smp_query(data, &portid, IB_ATTR_NODE_INFO, 0, 0) < 0)
IBERROR("smp query nodeinfo failed");
node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
- if (node_type != IB_NODE_CA) /* NodeType other than CA ? */
- IBERROR("smp query nodeinfo: Node type not CA, cannot simulate AllPortSelect");
mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports);
- if (num_ports != 1)
- IBERROR("smp query nodeinfo: %d ports; only 1 supported for AllPortSelect simulation", num_ports);
- port = num_ports;
+ /* If loop_ports not set, can only do the limited simulation we currently allow */
+ if (!loop_ports) {
+ if (node_type != IB_NODE_CA) /* NodeType other than CA ? */
+ IBERROR("smp query nodeinfo: Node type not CA, cannot simulate AllPortSelect");
+ if (num_ports != 1)
+ IBERROR("smp query nodeinfo: %d ports; only 1 supported for AllPortSelect simulation", num_ports);
+ port = num_ports;
+ }
+ else if (!num_ports)
+ IBERROR("smp query nodeinfo: num ports invalid");
}
if (reset_only)
goto do_reset;
-
- if (extended != 1) {
- if (!port_performance_query(pc, &portid, port, timeout))
- IBERROR("perfquery");
-
- if (allports == 1)
- pc[1] = ALL_PORTS; /* fake PortSelect */
-
- 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");
-
- if (allports == 1)
- pc[1] = ALL_PORTS; /* fake PortSelect */
-
- mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
+
+ if (allports && loop_ports) {
+ IBWARN("Emulating AllPortSelect by iterating through all ports");
+ for (i = 1; i <= num_ports; i++)
+ dump_perfcounters(extended, 0, timeout, cap_mask, &portid, i);
}
-
- printf("# Port counters: %s port %d\n%s", portid2str(&portid), port, buf);
+ else
+ dump_perfcounters(extended, allports, timeout, cap_mask, &portid, port);
if (!reset)
exit(0);
do_reset:
- if (extended != 1) {
- if (!port_performance_reset(pc, &portid, port, mask, timeout))
- IBERROR("perf reset");
- } else {
- if (!port_performance_ext_reset(pc, &portid, port, mask, timeout))
- IBERROR("perf ext reset");
+
+ if (allports && loop_ports) {
+ IBWARN("Emulating AllPortSelect by iterating through all ports");
+ for (i = 1; i <= num_ports; i++)
+ reset_counters(extended, timeout, mask, &portid, i);
}
+ else
+ reset_counters(extended, timeout, mask, &portid, port);
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