]> git.openfabrics.org - ~shefty/ibacm.git/commitdiff
ib_acme: Add support for endpoint specific performance query.
authorKaike Wan <kaike.wan@intel.com>
Fri, 13 Jun 2014 19:35:02 +0000 (12:35 -0700)
committerSean Hefty <sean.hefty@intel.com>
Fri, 13 Jun 2014 19:35:02 +0000 (12:35 -0700)
Adds the following queries to ib_acme tool:

  ib_acme -P N
    to query the performance for a specific endpoint N (N = 1, 2, ...);
  ib_acme -P all
    to query the performance for all endpoints;
  ib_acme -f [n | i] -s [src name | ip addr] -P s
    to query the performance for a specific endpoint with the given address.

in addition to the normal query for overal (combined) performance:

  ib_acme -P
  ib_acme -P col

Signed-off-by: Kaike Wan <kaike.wan@intel.com>
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
src/acme.c
src/libacm.c
src/libacm.h

index d281319c035cc0a60a916f574ed1605b43224d19..8279b65159f7ccc9a4b8341f58659f1301820fb5 100644 (file)
@@ -64,7 +64,10 @@ static int enum_ep;
 enum perf_query_output {
        PERF_QUERY_NONE,
        PERF_QUERY_ROW,
-       PERF_QUERY_COL
+       PERF_QUERY_COL,
+       PERF_QUERY_EP_INDEX,
+       PERF_QUERY_EP_ALL,
+       PERF_QUERY_EP_ADDR
 };
 static enum perf_query_output perf_query;
 int verbose;
@@ -90,7 +93,13 @@ static void show_usage(char *program)
        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\n");
+       printf("   [-P [opt]]       - query performance data from destination service:\n");
+       printf("                        No option: output combined data in row format.\n");
+       printf("                        col: output combined data in colum format.\n");
+       printf("                        N: output data for endpoint N (N = 1, 2,...)\n");
+       printf("                        all: output data for all endpoints\n");
+       printf("                        s: output data for the endpoint with the\n");
+       printf("                           address specified in -s option\n");
        printf("   [-S svc_addr]    - address of ACM service, default: local service\n");
        printf("   [-C repetitions] - repeat count for resolution\n");
        printf("usage 2: %s\n", program);
@@ -748,24 +757,107 @@ static void resolve(char *svc)
        free(dest_list);
 }
 
-static void query_perf(char *svc)
+static int query_perf_ip(uint64_t **counters, int *cnt)
+{
+       union _sockaddr {
+               struct sockaddr_storage src;
+               struct sockaddr saddr;
+       } addr;
+       uint8_t type;
+       struct sockaddr_in *sin;
+       struct sockaddr_in6 *sin6;
+       int ret;
+
+       VPRINT("%s: src_addr %s\n", __FUNCTION__, src_addr);
+       addr.saddr.sa_family = AF_INET;
+       sin = (struct sockaddr_in *) &addr.saddr;
+       ret = inet_pton(AF_INET, src_addr, &sin->sin_addr);
+       if (ret <= 0) {
+               addr.saddr.sa_family = AF_INET6;
+               sin6 = (struct sockaddr_in6 *)&addr.saddr;
+               ret = inet_pton(AF_INET6, src_addr, &sin6->sin6_addr);
+               if (ret <= 0) {
+                       printf("inet_pton error on src address (%s): 0x%x\n",
+                              src_addr, ret);
+                       return -1;
+               }
+               type = ACM_EP_INFO_ADDRESS_IP6;
+       } else {
+               type = ACM_EP_INFO_ADDRESS_IP;
+       }
+
+       ret = ib_acm_query_perf_ep_addr((uint8_t *)&addr.src, type, counters,
+                                        cnt);
+       if (ret) {
+               printf("ib_acm_query_perf failed: %s\n", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int query_perf_name(uint64_t **counters, int *cnt)
+{
+       int ret;
+
+       VPRINT("%s: src_addr %s\n", __FUNCTION__, src_addr);
+       ret = ib_acm_query_perf_ep_addr((uint8_t *)src_addr, ACM_EP_INFO_NAME,
+                                        counters, cnt);
+       if (ret) {
+               printf("ib_acm_query_perf failed: %s\n", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int query_perf_ep_addr(uint64_t **counters, int *cnt)
+{
+       int ret;
+       char src_type;
+
+       src_addr = get_dest(src_arg, &src_type);
+       switch (src_type) {
+       case 'i':
+               ret = query_perf_ip(counters, cnt);
+               break;
+       case 'n':
+               ret = query_perf_name(counters, cnt);
+               break;
+       default:
+               printf("Unsupported src_type %d\n", src_type);
+               return -1;
+       }
+
+       return ret;
+}
+
+static int query_perf_one(char *svc, int index)
 {
-       static int lables;
+       static int labels;
        int ret, cnt, i;
        uint64_t *counters;
 
-       ret = ib_acm_query_perf(&counters, &cnt);
+       if (perf_query == PERF_QUERY_EP_ADDR)
+               ret = query_perf_ep_addr(&counters, &cnt);
+       else
+               ret = ib_acm_query_perf(index, &counters, &cnt);
+
        if (ret) {
-               printf("%s: Failed to query perf data %s\n", svc, strerror(errno));
-               return;
+               if (perf_query != PERF_QUERY_EP_ALL) {
+                       printf("%s: Failed to query perf data: %s\n", svc,
+                              strerror(errno));
+               }
+               return ret;
        }
 
-       if (perf_query == PERF_QUERY_ROW) {
-               if (!lables) {
+       if (perf_query != PERF_QUERY_COL) {
+               if (!labels) {
+                       printf("svc,");
                        for (i = 0; i < cnt - 1; i++)
                                printf("%s,", ib_acm_cntr_name(i));
                        printf("%s\n", ib_acm_cntr_name(i));
-                       lables = 1;
+                       labels = 1;
                }
                printf("%s,", svc);
                for (i = 0; i < cnt - 1; i++)
@@ -779,6 +871,20 @@ static void query_perf(char *svc)
                }
        }
        ib_acm_free_perf(counters);
+
+       return 0;
+}
+
+static void query_perf(char *svc)
+{
+       int index = 1;
+
+       if (perf_query != PERF_QUERY_EP_ALL) {
+               query_perf_one(svc, ep_index);
+       }
+       else {
+               while (!query_perf_one(svc, index++));
+       }
 }
 
 static int enumerate_ep(char *svc, int index)
@@ -864,6 +970,23 @@ char *opt_arg(int argc, char **argv)
        return NULL;
 }
 
+void parse_perf_arg(char *arg)
+{
+       if (!strnicmp("col", arg, 3)) {
+               perf_query = PERF_QUERY_COL;
+       } else if (!strnicmp("all", arg, 3)) {
+               perf_query = PERF_QUERY_EP_ALL;
+       } else if (!strcmp("s", arg)) {
+               perf_query = PERF_QUERY_EP_ADDR;
+       } else {
+               ep_index = atoi(arg);
+               if (ep_index > 0) 
+                       perf_query = PERF_QUERY_EP_INDEX;
+               else
+                       perf_query = PERF_QUERY_ROW;
+       }
+}
+
 int CDECL_FUNC main(int argc, char **argv)
 {
        int op, ret;
@@ -913,8 +1036,8 @@ int CDECL_FUNC main(int argc, char **argv)
                        dest_dir = optarg;
                        break;
                case 'P':
-                       if (opt_arg(argc, argv) && !strnicmp("col", opt_arg(argc, argv), 3))
-                               perf_query = PERF_QUERY_COL;
+                       if (opt_arg(argc, argv))
+                               parse_perf_arg(opt_arg(argc, argv));
                        else
                                perf_query = PERF_QUERY_ROW;
                        break;
@@ -934,7 +1057,8 @@ int CDECL_FUNC main(int argc, char **argv)
                }
        }
 
-       if ((src_arg && !dest_arg) ||
+       if ((src_arg && (!dest_arg && perf_query != PERF_QUERY_EP_ADDR)) ||
+           (perf_query == PERF_QUERY_EP_ADDR && !src_arg) || 
            (!src_arg && !dest_arg && !perf_query && !make_addr && !make_opts &&
             !enum_ep))
                goto show_use;
index 16cdead2de09101a4c412ac5d3018a652fbc20a5..95e562deb0311eb167e10a3cf54ebfa272bc1a16 100644 (file)
@@ -305,7 +305,7 @@ out:
        return ret;
 }
 
-int ib_acm_query_perf(uint64_t **counters, int *count)
+int ib_acm_query_perf(int index, uint64_t **counters, int *count)
 {
        struct acm_msg msg;
        int ret, i;
@@ -314,6 +314,7 @@ int ib_acm_query_perf(uint64_t **counters, int *count)
        memset(&msg, 0, sizeof msg);
        msg.hdr.version = ACM_VERSION;
        msg.hdr.opcode = ACM_OP_PERF_QUERY;
+       msg.hdr.data[1] = index;
        msg.hdr.length = htons(ACM_MSG_HDR_LENGTH);
 
        ret = send(sock, (char *) &msg, ACM_MSG_HDR_LENGTH, 0);
@@ -396,6 +397,60 @@ out:
        return ret;
 }
 
+int ib_acm_query_perf_ep_addr(uint8_t *src, uint8_t type, 
+                            uint64_t **counters, int *count)
+{
+       struct acm_msg msg;
+       int ret, i, len;
+
+       if (!src) 
+               return -1;
+
+       lock_acquire(&lock);
+       memset(&msg, 0, sizeof msg);
+       msg.hdr.version = ACM_VERSION;
+       msg.hdr.opcode = ACM_OP_PERF_QUERY;
+
+       ret = acm_format_ep_addr(&msg.resolve_data[0], src, type,
+               ACM_EP_FLAG_SOURCE);
+       if (ret)
+               goto out;
+
+       len = ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH;
+       msg.hdr.length = htons(len);
+
+       ret = send(sock, (char *) &msg, len, 0);
+       if (ret != len)
+               goto out;
+
+       ret = recv(sock, (char *) &msg, sizeof msg, 0);
+       if (ret < ACM_MSG_HDR_LENGTH || ret != ntohs(msg.hdr.length)) {
+               ret = ACM_STATUS_EINVAL;
+               goto out;
+       }
+
+       if (msg.hdr.status) {
+               ret = acm_error(msg.hdr.status);
+               goto out;
+       }
+
+       *counters = malloc(sizeof(uint64_t) * msg.hdr.data[0]);
+       if (!*counters) {
+               ret = ACM_STATUS_ENOMEM;
+               goto out;
+       }
+
+       *count = msg.hdr.data[0];
+       for (i = 0; i < *count; i++)
+               (*counters)[i] = ntohll(msg.perf_data[i]);
+
+       ret = 0;
+out:
+       lock_release(&lock);
+       return ret;
+}
+
+
 const char *ib_acm_cntr_name(int index)
 {
        static const char *const cntr_name[] = {
index e94291f2ca1519934e50ebc28c39e203f1e77f4e..359a6af3bb2966c3872c2b6462dba1dec9099a6b 100644 (file)
@@ -45,7 +45,9 @@ int ib_acm_resolve_ip(struct sockaddr *src, struct sockaddr *dest,
 int ib_acm_resolve_path(struct ibv_path_record *path, uint32_t flags);
 #define ib_acm_free_paths(paths) free(paths)
 
-int ib_acm_query_perf(uint64_t **counters, int *count);
+int ib_acm_query_perf(int index, uint64_t **counters, int *count);
+int ib_acm_query_perf_ep_addr(uint8_t *src, uint8_t type,
+                             uint64_t **counters, int *count);
 #define ib_acm_free_perf(counters) free(counters)
 
 const char *ib_acm_cntr_name(int index);