X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fvdpa%2Fmain.c;h=2345f98665e06e0c6b3f19d1ec4b33f22ce43969;hb=fbe6be6ea04cad614a4d2914be2f6da788bcf706;hp=d2e2cb7cd4823bf6eb8558f4e685724ee3ee12ef;hpb=21c3c433f37e02a69ea05932d9021c2478086622;p=dpdk.git diff --git a/examples/vdpa/main.c b/examples/vdpa/main.c index d2e2cb7cd4..2345f98665 100644 --- a/examples/vdpa/main.c +++ b/examples/vdpa/main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #define MAX_PATH_LEN 128 @@ -26,15 +27,17 @@ struct vdpa_port { char ifname[MAX_PATH_LEN]; - int did; + struct rte_vdpa_device *dev; int vid; uint64_t flags; + int stats_n; + struct rte_vdpa_stat_name *stats_names; + struct rte_vdpa_stat *stats; }; static struct vdpa_port vports[MAX_VDPA_SAMPLE_PORTS]; static char iface[MAX_PATH_LEN]; -static int dev_total; static int devcnt; static int interactive; static int client_mode; @@ -101,16 +104,23 @@ static int new_device(int vid) { char ifname[MAX_PATH_LEN]; + struct rte_device *dev; int i; rte_vhost_get_ifname(vid, ifname, sizeof(ifname)); for (i = 0; i < MAX_VDPA_SAMPLE_PORTS; i++) { - if (strncmp(ifname, vports[i].ifname, MAX_PATH_LEN) == 0) { - printf("\nnew port %s, did: %d\n", - ifname, vports[i].did); - vports[i].vid = vid; - break; + if (strncmp(ifname, vports[i].ifname, MAX_PATH_LEN)) + continue; + + dev = rte_vdpa_get_rte_device(vports[i].dev); + if (!dev) { + RTE_LOG(ERR, VDPA, + "Failed to get generic device for port %d\n", i); + continue; } + printf("\nnew port %s, device : %s\n", ifname, dev->name); + vports[i].vid = vid; + break; } if (i >= MAX_VDPA_SAMPLE_PORTS) @@ -122,16 +132,24 @@ new_device(int vid) static void destroy_device(int vid) { + struct rte_device *dev; char ifname[MAX_PATH_LEN]; int i; rte_vhost_get_ifname(vid, ifname, sizeof(ifname)); for (i = 0; i < MAX_VDPA_SAMPLE_PORTS; i++) { - if (strcmp(ifname, vports[i].ifname) == 0) { - printf("\ndestroy port %s, did: %d\n", - ifname, vports[i].did); - break; + if (strncmp(ifname, vports[i].ifname, MAX_PATH_LEN)) + continue; + + dev = rte_vdpa_get_rte_device(vports[i].dev); + if (!dev) { + RTE_LOG(ERR, VDPA, + "Failed to get generic device for port %d\n", i); + continue; } + + printf("\ndestroy port %s, device: %s\n", ifname, dev->name); + break; } } @@ -145,7 +163,6 @@ start_vdpa(struct vdpa_port *vport) { int ret; char *socket_path = vport->ifname; - int did = vport->did; if (client_mode) vport->flags |= RTE_VHOST_USER_CLIENT; @@ -169,7 +186,7 @@ start_vdpa(struct vdpa_port *vport) "register driver ops failed: %s\n", socket_path); - ret = rte_vhost_driver_attach_vdpa_device(socket_path, did); + ret = rte_vhost_driver_attach_vdpa_device(socket_path, vport->dev); if (ret != 0) rte_exit(EXIT_FAILURE, "attach vdpa device failed: %s\n", @@ -199,13 +216,17 @@ close_vdpa(struct vdpa_port *vport) RTE_LOG(ERR, VDPA, "Fail to unregister vhost driver for %s.\n", socket_path); + if (vport->stats_names) { + rte_free(vport->stats_names); + vport->stats_names = NULL; + } } static void vdpa_sample_quit(void) { int i; - for (i = 0; i < RTE_MIN(MAX_VDPA_SAMPLE_PORTS, dev_total); i++) { + for (i = 0; i < RTE_MIN(MAX_VDPA_SAMPLE_PORTS, devcnt); i++) { if (vports[i].ifname[0] != '\0') close_vdpa(&vports[i]); } @@ -228,9 +249,9 @@ struct cmd_help_result { cmdline_fixed_string_t help; }; -static void cmd_help_parsed(__attribute__((unused)) void *parsed_result, +static void cmd_help_parsed(__rte_unused void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) + __rte_unused void *data) { cmdline_printf( cl, @@ -240,6 +261,7 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result, " help : Show interactive instructions.\n" " list : list all available vdpa devices.\n" " create : create a new vdpa port.\n" + " stats : show statistics of virtio queue, 0xffff for all.\n" " quit : exit vdpa sample app.\n" ); } @@ -263,38 +285,35 @@ struct cmd_list_result { }; static void cmd_list_vdpa_devices_parsed( - __attribute__((unused)) void *parsed_result, + __rte_unused void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) + __rte_unused void *data) { - int did; uint32_t queue_num; uint64_t features; struct rte_vdpa_device *vdev; - struct rte_pci_addr addr; + struct rte_device *dev; + struct rte_dev_iterator dev_iter; - cmdline_printf(cl, "device id\tdevice address\tqueue num\tsupported features\n"); - for (did = 0; did < dev_total; did++) { - vdev = rte_vdpa_get_device(did); + cmdline_printf(cl, "device name\tqueue num\tsupported features\n"); + RTE_DEV_FOREACH(dev, "class=vdpa", &dev_iter) { + vdev = rte_vdpa_find_device_by_name(dev->name); if (!vdev) continue; - if (vdev->ops->get_queue_num(did, &queue_num) < 0) { + if (rte_vdpa_get_queue_num(vdev, &queue_num) < 0) { RTE_LOG(ERR, VDPA, "failed to get vdpa queue number " - "for device id %d.\n", did); + "for device %s.\n", dev->name); continue; } - if (vdev->ops->get_features(did, &features) < 0) { + if (rte_vdpa_get_features(vdev, &features) < 0) { RTE_LOG(ERR, VDPA, "failed to get vdpa features " - "for device id %d.\n", did); + "for device %s.\n", dev->name); continue; } - addr = vdev->addr.pci_addr; - cmdline_printf(cl, - "%d\t\t" PCI_PRI_FMT "\t%" PRIu32 "\t\t0x%" PRIx64 "\n", - did, addr.domain, addr.bus, addr.devid, - addr.function, queue_num, features); + cmdline_printf(cl, "%s\t\t%" PRIu32 "\t\t0x%" PRIx64 "\n", + dev->name, queue_num, features); } } @@ -320,25 +339,20 @@ struct cmd_create_result { static void cmd_create_vdpa_port_parsed(void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) + __rte_unused void *data) { - int did; + struct rte_vdpa_device *dev; struct cmd_create_result *res = parsed_result; - struct rte_vdpa_dev_addr addr; rte_strscpy(vports[devcnt].ifname, res->socket_path, MAX_PATH_LEN); - if (rte_pci_addr_parse(res->bdf, &addr.pci_addr) != 0) { - cmdline_printf(cl, "Unable to parse the given bdf.\n"); - return; - } - addr.type = PCI_ADDR; - did = rte_vdpa_find_device_id(&addr); - if (did < 0) { - cmdline_printf(cl, "Unable to find vdpa device id.\n"); + dev = rte_vdpa_find_device_by_name(res->bdf); + if (dev == NULL) { + cmdline_printf(cl, "Unable to find vdpa device id for %s.\n", + res->bdf); return; } - vports[devcnt].did = did; + vports[devcnt].dev = dev; if (start_vdpa(&vports[devcnt]) == 0) devcnt++; @@ -363,14 +377,122 @@ cmdline_parse_inst_t cmd_create_vdpa_port = { }, }; +/* *** STATS *** */ +struct cmd_stats_result { + cmdline_fixed_string_t stats; + cmdline_fixed_string_t bdf; + uint16_t qid; +}; + +static void cmd_device_stats_parsed(void *parsed_result, struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_stats_result *res = parsed_result; + struct rte_vdpa_device *vdev = rte_vdpa_find_device_by_name(res->bdf); + struct vdpa_port *vport = NULL; + uint32_t first, last; + int i; + + if (!vdev) { + RTE_LOG(ERR, VDPA, "Invalid device: %s.\n", + res->bdf); + return; + } + for (i = 0; i < RTE_MIN(MAX_VDPA_SAMPLE_PORTS, devcnt); i++) { + if (vports[i].dev == vdev) { + vport = &vports[i]; + break; + } + } + if (!vport) { + RTE_LOG(ERR, VDPA, "Device %s was not created.\n", res->bdf); + return; + } + if (res->qid == 0xFFFF) { + first = 0; + last = rte_vhost_get_vring_num(vport->vid); + if (last == 0) { + RTE_LOG(ERR, VDPA, "Failed to get num of actual virtqs" + " for device %s.\n", res->bdf); + return; + } + last--; + } else { + first = res->qid; + last = res->qid; + } + if (!vport->stats_names) { + vport->stats_n = rte_vdpa_get_stats_names(vport->dev, NULL, 0); + if (vport->stats_n <= 0) { + RTE_LOG(ERR, VDPA, "Failed to get names number of " + "device %s stats.\n", res->bdf); + return; + } + vport->stats_names = rte_zmalloc(NULL, + (sizeof(*vport->stats_names) + sizeof(*vport->stats)) * + vport->stats_n, 0); + if (!vport->stats_names) { + RTE_LOG(ERR, VDPA, "Failed to allocate memory for stat" + " names of device %s.\n", res->bdf); + return; + } + i = rte_vdpa_get_stats_names(vport->dev, vport->stats_names, + vport->stats_n); + if (vport->stats_n != i) { + RTE_LOG(ERR, VDPA, "Failed to get names of device %s " + "stats.\n", res->bdf); + return; + } + vport->stats = (struct rte_vdpa_stat *) + (vport->stats_names + vport->stats_n); + } + cmdline_printf(cl, "\nDevice %s:\n", res->bdf); + for (; first <= last; first++) { + memset(vport->stats, 0, sizeof(*vport->stats) * vport->stats_n); + if (rte_vdpa_get_stats(vport->dev, (int)first, vport->stats, + vport->stats_n) <= 0) { + RTE_LOG(ERR, VDPA, "Failed to get vdpa queue statistics" + " for device %s qid %d.\n", res->bdf, + (int)first); + return; + } + cmdline_printf(cl, "\tVirtq %" PRIu32 ":\n", first); + for (i = 0; i < vport->stats_n; ++i) { + cmdline_printf(cl, "\t\t%-*s %-16" PRIu64 "\n", + RTE_VDPA_STATS_NAME_SIZE, + vport->stats_names[vport->stats[i].id].name, + vport->stats[i].value); + } + } +} + +cmdline_parse_token_string_t cmd_device_stats_ = + TOKEN_STRING_INITIALIZER(struct cmd_stats_result, stats, "stats"); +cmdline_parse_token_string_t cmd_device_bdf = + TOKEN_STRING_INITIALIZER(struct cmd_stats_result, bdf, NULL); +cmdline_parse_token_num_t cmd_queue_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_result, qid, UINT32); + +cmdline_parse_inst_t cmd_device_stats = { + .f = cmd_device_stats_parsed, + .data = NULL, + .help_str = "stats: show device statistics", + .tokens = { + (void *)&cmd_device_stats_, + (void *)&cmd_device_bdf, + (void *)&cmd_queue_id, + NULL, + }, +}; + /* *** QUIT *** */ struct cmd_quit_result { cmdline_fixed_string_t quit; }; -static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, +static void cmd_quit_parsed(__rte_unused void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) + __rte_unused void *data) { vdpa_sample_quit(); cmdline_quit(cl); @@ -392,6 +514,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_help, (cmdline_parse_inst_t *)&cmd_list_vdpa_devices, (cmdline_parse_inst_t *)&cmd_create_vdpa_port, + (cmdline_parse_inst_t *)&cmd_device_stats, (cmdline_parse_inst_t *)&cmd_quit, NULL, }; @@ -400,9 +523,11 @@ int main(int argc, char *argv[]) { char ch; - int i; int ret; struct cmdline *cl; + struct rte_vdpa_device *vdev; + struct rte_device *dev; + struct rte_dev_iterator dev_iter; ret = rte_eal_init(argc, argv); if (ret < 0) @@ -410,10 +535,6 @@ main(int argc, char *argv[]) argc -= ret; argv += ret; - dev_total = rte_vdpa_get_device_num(); - if (dev_total <= 0) - rte_exit(EXIT_FAILURE, "No available vdpa device found\n"); - signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); @@ -428,13 +549,18 @@ main(int argc, char *argv[]) cmdline_interact(cl); cmdline_stdin_exit(cl); } else { - for (i = 0; i < RTE_MIN(MAX_VDPA_SAMPLE_PORTS, dev_total); - i++) { - vports[i].did = i; - snprintf(vports[i].ifname, MAX_PATH_LEN, "%s%d", - iface, i); + RTE_DEV_FOREACH(dev, "class=vdpa", &dev_iter) { + vdev = rte_vdpa_find_device_by_name(dev->name); + if (vdev == NULL) { + rte_panic("Failed to find vDPA dev for %s\n", + dev->name); + } + vports[devcnt].dev = vdev; + snprintf(vports[devcnt].ifname, MAX_PATH_LEN, "%s%d", + iface, devcnt); - start_vdpa(&vports[i]); + start_vdpa(&vports[devcnt]); + devcnt++; } printf("enter \'q\' to quit\n");