--- /dev/null
+Bottom: 2dabfe33c4a42a8c11d65c804d0641d900fe1b2e
+Top: 70fb93d64e9ecf38abaca2ab5496df0a03517a96
+Author: Sean Hefty <sean.hefty@intel.com>
+Date: 2011-06-30 16:34:43 -0700
+
+Refresh of counters
+
+---
+
+diff --git a/include/infiniband/acm.h b/include/infiniband/acm.h
+index c2d4088..bc85137 100644
+--- a/include/infiniband/acm.h
++++ b/include/infiniband/acm.h
+@@ -96,8 +96,8 @@ struct acm_ep_addr_data {
+ /*
+ * Resolve messages with the opcode set to ACM_OP_RESOLVE are only
+ * used to communicate with the local ib_acm service. Message fields
+- * in this case are not byte swapped, but note that the address
+- * data is in big-endian format.
++ * in this case are not byte swapped, but note that the acm_ep_info
++ * data is in network order.
+ */
+ struct acm_resolve_msg {
+ struct acm_hdr hdr;
+diff --git a/src/acme.c b/src/acme.c
+index 3787998..3030991 100644
+--- a/src/acme.c
++++ b/src/acme.c
+@@ -49,9 +49,13 @@ static char *opts_file = ACM_OPTS_FILE;
+
+ static char *dest_addr;
+ static char *src_addr;
++static char *svc_arg = "localhost";
++static char *dest_arg;
++static char *src_arg;
+ static char addr_type = 'u';
+ static int verify;
+ static int nodelay;
++static int perf_query;
+ int verbose;
+
+ struct ibv_context **verbs;
+@@ -65,15 +69,17 @@ extern char **parse(char *args, int *count);
+ static void show_usage(char *program)
+ {
+ printf("usage 1: %s\n", program);
++ printf("Query specified ib_acm service for data\n")
+ printf(" [-f addr_format] - i(p), n(ame), l(id), g(gid), or u(nspecified)\n");
+- printf(" default: 'u'\n");
+- printf(" [-s src_addr] - format defined by -f option\n");
+- printf(" [-d] dest_addr - format defined by -f option\n");
++ printf(" address format for -s and -d options, default: 'u'\n");
++ printf(" [-s src_addr] - source address for path queries\n");
++ printf(" [-d dest_addr] - destination addresses for path queries\n");
+ printf(" [-v] - verify ACM response against SA query response\n");
+ printf(" [-c] - read ACM cached data only\n");
++ printf(" [-P] - query performance data from destination service");
++ printf(" [-S svc_addr] - address of ACM service, default: local service")
+ printf("usage 2: %s\n", program);
+- printf(" -P dest_addr - query performance data from destination service");
+- printf("usage 3: %s\n", program);
++ printf("Generate default ib_acm service configuration and option files\n")
+ printf(" -A [addr_file] - generate local address configuration file\n");
+ printf(" (default is %s)\n", ACM_ADDR_FILE);
+ printf(" -O [opt_file] - generate local acm_opts.cfg options file\n");
+@@ -580,25 +586,24 @@ static char *get_dest(char *arg, char *format)
+ }
+ }
+
+-static int resolve(char *program, char *dest_arg)
++static int resolve(char *svc)
+ {
+- char **dest_list;
++ char **dest_list, **src_list;
+ struct ibv_path_record path;
+ int ret, i = 0;
+ char dest_type;
+
+- ret = ib_acm_connect("127.0.0.1");
+- if (ret) {
+- printf("Unable to contact ib_acm service\n");
+- return ret;
+- }
+-
+ dest_list = parse(dest_arg, NULL);
+ if (!dest_list) {
+ printf("Unable to parse destination argument\n");
+- return -1;
++ return;
++ }
++
++ if (src_arg) {
++ src_list = parse(src_arg, NULL);
+ }
+
++ printf("Service: %s\n", svc);
+ for (dest_addr = get_dest(dest_list[i], &dest_type); dest_addr;
+ dest_addr = get_dest(dest_list[++i], &dest_type)) {
+ printf("Destination: %s\n", dest_addr);
+@@ -618,8 +623,7 @@ static int resolve(char *program, char *dest_arg)
+ ret = resolve_gid(&path);
+ break;
+ default:
+- show_usage(program);
+- exit(1);
++ break;
+ }
+
+ if (!ret)
+@@ -631,47 +635,62 @@ static int resolve(char *program, char *dest_arg)
+ }
+
+ free(dest_list);
+- ib_acm_disconnect();
+ return ret;
+ }
+
+-static int query_perf(char *program, char *dest_arg)
++static void query_perf(static char *svc)
+ {
+- char **dest_list;
+- int ret, cnt, i, d;
++ int ret, cnt, i;
+ uint64_t *counters;
+
+- dest_list = parse(dest_arg, NULL);
+- if (!dest_list) {
+- printf("Unable to parse destination argument\n");
++ ret = ib_acm_query_perf(&counters, &cnt);
++ if (ret) {
++ printf("%s: Failed to query perf data %s\n", svc, strerror(errno));
++ return;
++ }
++
++ for (i = 0; i < cnt; i++)
++ printf("%llu,", (unsigned long long) counters[i]);
++ printf("\n");
++ ib_acm_free_perf(counters);
++}
++
++static int query_svcs(void)
++{
++ char **svc_list;
++ int ret, i;
++
++ svc_list = parse(svc_arg, NULL);
++ if (!svc_list) {
++ printf("Unable to parse service list argument\n");
+ return -1;
+ }
+
+- printf("Destination,Error Count,Resolve Count,No Data,Addr Query Count,"
+- "Addr Cache Count,Route Query Count,Route Cache Count\n");
+- for (d = 0; dest_list[d]; d++) {
++ if (perf_query) {
++ printf("Destination,Error Count,Resolve Count,No Data,Addr Query Count,"
++ "Addr Cache Count,Route Query Count,Route Cache Count\n");
++ }
+
+- printf("%s,", dest_list[d]);
+- ret = ib_acm_connect(dest_list[d]);
++ for (i = 0; svc_list[i]; i++) {
++ ret = ib_acm_connect(svc_list[i]);
+ if (ret) {
+- printf("Unable to contact ib_acm service\n");
++ printf("%s: Unable to contact ib_acm service\n", svc_list[i]);
+ continue;
+ }
+
+- ret = ib_acm_query_perf(&counters, &cnt);
+- if (ret) {
+- printf("Failed to query perf data %s\n", strerror(errno));
+- } else {
+- for (i = 0; i < cnt; i++)
+- printf("%llu,", (unsigned long long) counters[i]);
+- printf("\n");
+- ib_acm_free_perf(counters);
++ if (dest_arg) {
++ ret = resolve(svc_list[i]);
++ if (ret)
++ break;
+ }
+
++ if (perf_query)
++ query_perf(svc_list[i]);
++
+ ib_acm_disconnect();
+ }
+
+- free(dest_list);
++ free(svc_list);
+ return ret;
+ }
+
+@@ -688,23 +707,24 @@ char *opt_arg(int argc, char **argv)
+
+ int CDECL_FUNC main(int argc, char **argv)
+ {
+- char *dest_arg = NULL;
+ int op, ret;
+ int make_addr = 0;
+ int make_opts = 0;
+- int perf_query = 0;
+
+ ret = osd_init();
+ if (ret)
+ goto out;
+
+- while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:P:V")) != -1) {
++ while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:PV")) != -1) {
+ switch (op) {
+ case 'f':
+ addr_type = optarg[0];
++ if (addr_type != 'i' && addr_type != 'n' &&
++ addr_type != 'l' && addr_type != 'g')
++ goto show_use;
+ break;
+ case 's':
+- src_addr = optarg;
++ src_arg = optarg;
+ break;
+ case 'd':
+ dest_arg = optarg;
+@@ -730,29 +750,24 @@ int CDECL_FUNC main(int argc, char **argv)
+ break;
+ case 'P':
+ perf_query = 1;
+- dest_arg = optarg;
++ break;
++ case 'S':
++ svc_arg = optarg;
+ break;
+ case 'V':
+ verbose = 1;
+ break;
+ default:
+- show_usage(argv[0]);
+- exit(1);
++ goto show_use;
+ }
+ }
+
+- if ((src_addr && !dest_arg) ||
+- (!src_addr && !dest_arg && !make_addr && !make_opts)) {
+- show_usage(argv[0]);
+- exit(1);
+- }
++ if ((src_arg && !dest_arg) ||
++ (!src_arg && !dest_arg && !perf_query && !make_addr && !make_opts))
++ goto show_use;
+
+- if (dest_arg) {
+- if (perf_query)
+- ret = query_perf(argv[0], dest_arg);
+- else
+- ret = resolve(argv[0], dest_arg);
+- }
++ if (dest_arg || perf_query)
++ ret = query_svcs();
+
+ if (!ret && make_addr)
+ ret = gen_addr();
+@@ -765,4 +780,8 @@ out:
+ if (verbose || !(make_addr || make_opts) || ret)
+ printf("return status 0x%x\n", ret);
+ return ret;
++
++show_use:
++ show_usage(argv[0]);
++ exit(1);
+ }