On Sun, 5 Feb 2017 10:05:07 -0600 Keith Wiles <keith.wi...@intel.com> wrote:
> At the same time remove the code which created the first device queue > at probe time. Now all queues are created during queue setup calls. > > Signed-off-by: Keith Wiles <keith.wi...@intel.com> > --- > drivers/net/tap/rte_eth_tap.c | 104 > ++++++++++++++---------------------------- 1 file changed, 34 insertions(+), > 70 deletions(-) > > diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c > index 61659bc..7c923a2 100644 > --- a/drivers/net/tap/rte_eth_tap.c > +++ b/drivers/net/tap/rte_eth_tap.c > @@ -57,7 +57,11 @@ > #define ETH_TAP_IFACE_ARG "iface" > #define ETH_TAP_SPEED_ARG "speed" > > +#ifdef IFF_MULTI_QUEUE > #define RTE_PMD_TAP_MAX_QUEUES 16 > +#else > +#define RTE_PMD_TAP_MAX_QUEUES 1 > +#endif > > static struct rte_vdev_driver pmd_tap_drv; > > @@ -114,17 +118,20 @@ struct pmd_internals { > * supplied name. > */ > static int > -tun_alloc(char *name) > +tun_alloc(struct pmd_internals *pmd, uint16_t qid) > { > struct ifreq ifr; > +#ifdef IFF_MULTI_QUEUE > unsigned int features; > +#endif > int fd; > > memset(&ifr, 0, sizeof(struct ifreq)); > > ifr.ifr_flags = IFF_TAP | IFF_NO_PI; > - if (name && name[0]) > - strncpy(ifr.ifr_name, name, IFNAMSIZ); > + strncpy(ifr.ifr_name, pmd->name, IFNAMSIZ); > + > + RTE_LOG(DEBUG, PMD, "ifr_name '%s'\n", ifr.ifr_name); > > fd = open(TUN_TAP_DEV_PATH, O_RDWR); > if (fd < 0) { > @@ -132,37 +139,26 @@ tun_alloc(char *name) > goto error; > } > > - /* Grab the TUN features to verify we can work */ > +#ifdef IFF_MULTI_QUEUE > + /* Grab the TUN features to verify we can work multi-queue */ > if (ioctl(fd, TUNGETFEATURES, &features) < 0) { > - RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n"); > + RTE_LOG(ERR, PMD, "TAP unable to get TUN/TAP features\n"); > goto error; > } > - RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features); > + RTE_LOG(DEBUG, PMD, " TAP Features %08x\n", features); > > -#ifdef IFF_MULTI_QUEUE > - if (!(features & IFF_MULTI_QUEUE) && (RTE_PMD_TAP_MAX_QUEUES > 1)) { > - RTE_LOG(DEBUG, PMD, "TUN/TAP device only one queue\n"); > - goto error; > - } else if ((features & IFF_ONE_QUEUE) && > - (RTE_PMD_TAP_MAX_QUEUES == 1)) { > - ifr.ifr_flags |= IFF_ONE_QUEUE; > - RTE_LOG(DEBUG, PMD, "Single queue only support\n"); > - } else { > - ifr.ifr_flags |= IFF_MULTI_QUEUE; > - RTE_LOG(DEBUG, PMD, "Multi-queue support for %d queues\n", > + if (features & IFF_MULTI_QUEUE) { > + RTE_LOG(DEBUG, PMD, " Multi-queue support for %d queues\n", > RTE_PMD_TAP_MAX_QUEUES); > - } > -#else > - if (RTE_PMD_TAP_MAX_QUEUES > 1) { > - RTE_LOG(DEBUG, PMD, "TUN/TAP device only one queue\n"); > - goto error; > - } else { > + ifr.ifr_flags |= IFF_MULTI_QUEUE; > + } else > +#endif > + { > ifr.ifr_flags |= IFF_ONE_QUEUE; > RTE_LOG(DEBUG, PMD, "Single queue only support\n"); > } > -#endif > > - /* Set the TUN/TAP configuration and get the name if needed */ > + /* Set the TUN/TAP configuration and set the name if needed */ > if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { > RTE_LOG(ERR, PMD, "Unable to set TUNSETIFF for %s\n", > ifr.ifr_name); > @@ -177,9 +173,15 @@ tun_alloc(char *name) > goto error; > } > > - /* If the name is different that new name as default */ > - if (name && strcmp(name, ifr.ifr_name)) > - snprintf(name, RTE_ETH_NAME_MAX_LEN - 1, "%s", ifr.ifr_name); > + if (qid == 0) { > + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { > + RTE_LOG(ERR, PMD, "ioctl failed (SIOCGIFHWADDR) > (%s)\n", > + ifr.ifr_name); > + goto error; > + } > + > + rte_memcpy(&pmd->eth_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); > + } > > return fd; > > @@ -507,7 +509,7 @@ tap_setup_queue(struct rte_eth_dev *dev, > if (fd < 0) { > RTE_LOG(INFO, PMD, "Add queue to TAP %s for qid > %d\n", pmd->name, qid); > - fd = tun_alloc(pmd->name); > + fd = tun_alloc(pmd, qid); > if (fd < 0) { > RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n", > pmd->name); > @@ -629,34 +631,13 @@ static const struct eth_dev_ops ops = { > }; > > static int > -pmd_mac_address(int fd, struct ether_addr *addr) > -{ > - struct ifreq ifr; > - > - if ((fd <= 0) || !addr) > - return -1; > - > - memset(&ifr, 0, sizeof(ifr)); > - > - if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { > - RTE_LOG(ERR, PMD, "ioctl failed (SIOCGIFHWADDR) (%s)\n", > - ifr.ifr_name); > - return -1; > - } > - > - rte_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); > - > - return 0; > -} > - > -static int > eth_dev_tap_create(const char *name, char *tap_name) > { > int numa_node = rte_socket_id(); > struct rte_eth_dev *dev = NULL; > struct pmd_internals *pmd = NULL; > struct rte_eth_dev_data *data = NULL; > - int i, fd = -1; > + int i; > > RTE_LOG(INFO, PMD, > "%s: Create TAP Ethernet device with %d queues on numa %u\n", > @@ -674,7 +655,6 @@ eth_dev_tap_create(const char *name, char *tap_name) > goto error_exit; > } > > - /* Use the name and not the tap_name */ > dev = rte_eth_dev_allocate(tap_name); > if (!dev) { > RTE_LOG(ERR, PMD, "Unable to allocate device struct\n"); > @@ -705,28 +685,12 @@ eth_dev_tap_create(const char *name, char *tap_name) > dev->tx_pkt_burst = pmd_tx_burst; > snprintf(dev->data->name, sizeof(dev->data->name), "%s", name); > > - /* Create the first Tap device */ > - fd = tun_alloc(tap_name); > - if (fd < 0) { > - RTE_LOG(ERR, PMD, "tun_alloc() failed\n"); > - goto error_exit; > - } > - > - /* Presetup the fds to -1 as being not working */ > - for (i = 1; i < RTE_PMD_TAP_MAX_QUEUES; i++) { > + /* Presetup the fds to -1 as being not valid */ > + for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { > pmd->rxq[i].fd = -1; > pmd->txq[i].fd = -1; > } > > - /* Take the TUN/TAP fd and place in the first location */ > - pmd->rxq[0].fd = fd; > - pmd->txq[0].fd = fd; > - > - if (pmd_mac_address(fd, &pmd->eth_addr) < 0) { > - RTE_LOG(ERR, PMD, "Unable to get MAC address\n"); > - goto error_exit; > - } > - > return 0; > > error_exit: I like that you use #ifdef IFF_MULTI_QUEUE, it's a good thing. Something bothers me, though. I don't think you should close all fds in the dev_stop() function, but rather in the dev_close() function. After a dev_close(), we don't expect the user to re-use the device, so we can safely remove the queues. However, after a dev_stop(), the user can definitely do a dev_start(), which in your case would fail because it will try to set the link up on an inexisting device. dev_stop() should act as dev_start(), in symmetry, and dev_close() should close the fd/queues. The rest of the code looks OK to me. Best regards, Pascal