X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Ftestpmd.c;h=035836adfbdedca5d8025f8b1f57a914829bf8a9;hb=241a65006138f659f299290a5d1237827321db27;hp=38dbb12a8f64a4fec3e9f15673ef7ff8cb959d66;hpb=b57b66a97ebfbeb6cd98077db499ecc20ee6fb9d;p=dpdk.git diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 38dbb12a8f..035836adfb 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -78,6 +78,7 @@ #endif #define EXTMEM_HEAP_NAME "extmem" +#define EXTBUF_ZONE_SIZE RTE_PGSIZE_2M uint16_t verbose_level = 0; /**< Silent by default. */ int testpmd_logtype; /**< Log type for testpmd logs */ @@ -868,6 +869,66 @@ dma_map_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused, } } +static unsigned int +setup_extbuf(uint32_t nb_mbufs, uint16_t mbuf_sz, unsigned int socket_id, + char *pool_name, struct rte_pktmbuf_extmem **ext_mem) +{ + struct rte_pktmbuf_extmem *xmem; + unsigned int ext_num, zone_num, elt_num; + uint16_t elt_size; + + elt_size = RTE_ALIGN_CEIL(mbuf_sz, RTE_CACHE_LINE_SIZE); + elt_num = EXTBUF_ZONE_SIZE / elt_size; + zone_num = (nb_mbufs + elt_num - 1) / elt_num; + + xmem = malloc(sizeof(struct rte_pktmbuf_extmem) * zone_num); + if (xmem == NULL) { + TESTPMD_LOG(ERR, "Cannot allocate memory for " + "external buffer descriptors\n"); + *ext_mem = NULL; + return 0; + } + for (ext_num = 0; ext_num < zone_num; ext_num++) { + struct rte_pktmbuf_extmem *xseg = xmem + ext_num; + const struct rte_memzone *mz; + char mz_name[RTE_MEMZONE_NAMESIZE]; + int ret; + + ret = snprintf(mz_name, sizeof(mz_name), + RTE_MEMPOOL_MZ_FORMAT "_xb_%u", pool_name, ext_num); + if (ret < 0 || ret >= (int)sizeof(mz_name)) { + errno = ENAMETOOLONG; + ext_num = 0; + break; + } + mz = rte_memzone_reserve_aligned(mz_name, EXTBUF_ZONE_SIZE, + socket_id, + RTE_MEMZONE_IOVA_CONTIG | + RTE_MEMZONE_1GB | + RTE_MEMZONE_SIZE_HINT_ONLY, + EXTBUF_ZONE_SIZE); + if (mz == NULL) { + /* + * The caller exits on external buffer creation + * error, so there is no need to free memzones. + */ + errno = ENOMEM; + ext_num = 0; + break; + } + xseg->buf_ptr = mz->addr; + xseg->buf_iova = mz->iova; + xseg->buf_len = EXTBUF_ZONE_SIZE; + xseg->elt_size = elt_size; + } + if (ext_num == 0 && xmem != NULL) { + free(xmem); + xmem = NULL; + } + *ext_mem = xmem; + return ext_num; +} + /* * Configuration initialisation done once at init time. */ @@ -936,6 +997,26 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, heap_socket); break; } + case MP_ALLOC_XBUF: + { + struct rte_pktmbuf_extmem *ext_mem; + unsigned int ext_num; + + ext_num = setup_extbuf(nb_mbuf, mbuf_seg_size, + socket_id, pool_name, &ext_mem); + if (ext_num == 0) + rte_exit(EXIT_FAILURE, + "Can't create pinned data buffers\n"); + + TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n", + rte_mbuf_best_mempool_ops()); + rte_mp = rte_pktmbuf_pool_create_extbuf + (pool_name, nb_mbuf, mb_mempool_cache, + 0, mbuf_seg_size, socket_id, + ext_mem, ext_num); + free(ext_mem); + break; + } default: { rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n"); @@ -2552,32 +2633,17 @@ setup_attached_port(portid_t pi) printf("Done\n"); } -void -detach_port_device(portid_t port_id) +static void +detach_device(struct rte_device *dev) { - struct rte_device *dev; portid_t sibling; - printf("Removing a device...\n"); - - if (port_id_is_invalid(port_id, ENABLED_WARN)) - return; - - dev = rte_eth_devices[port_id].device; if (dev == NULL) { printf("Device already removed\n"); return; } - if (ports[port_id].port_status != RTE_PORT_CLOSED) { - if (ports[port_id].port_status != RTE_PORT_STOPPED) { - printf("Port not stopped\n"); - return; - } - printf("Port was not closed\n"); - if (ports[port_id].flow_list) - port_flow_flush(port_id); - } + printf("Removing a device...\n"); if (rte_dev_remove(dev) < 0) { TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name); @@ -2595,14 +2661,33 @@ detach_port_device(portid_t port_id) remove_invalid_ports(); - printf("Device of port %u is detached\n", port_id); + printf("Device is detached\n"); printf("Now total ports is %d\n", nb_ports); printf("Done\n"); return; } void -detach_device(char *identifier) +detach_port_device(portid_t port_id) +{ + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + if (ports[port_id].port_status != RTE_PORT_CLOSED) { + if (ports[port_id].port_status != RTE_PORT_STOPPED) { + printf("Port not stopped\n"); + return; + } + printf("Port was not closed\n"); + if (ports[port_id].flow_list) + port_flow_flush(port_id); + } + + detach_device(rte_eth_devices[port_id].device); +} + +void +detach_devargs(char *identifier) { struct rte_dev_iterator iterator; struct rte_devargs da; @@ -2715,8 +2800,6 @@ struct pmd_test_command { cmd_func_t cmd_func; }; -#define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) - /* Check the link status of all ports in up to 9s, and print them finally */ static void check_all_ports_link_status(uint32_t port_mask) @@ -2793,6 +2876,7 @@ rmv_port_callback(void *arg) int need_to_start = 0; int org_no_link_check = no_link_check; portid_t port_id = (intptr_t)arg; + struct rte_device *dev; RTE_ETH_VALID_PORTID_OR_RET(port_id); @@ -2803,8 +2887,12 @@ rmv_port_callback(void *arg) no_link_check = 1; stop_port(port_id); no_link_check = org_no_link_check; + + /* Save rte_device pointer before closing ethdev port */ + dev = rte_eth_devices[port_id].device; close_port(port_id); - detach_port_device(port_id); + detach_device(dev); /* might be already removed or have more ports */ + if (need_to_start) start_packet_forwarding(0); }