[dpdk-dev,2/5] net/tap: fix multi-queue support
Checks
Commit Message
Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
drivers/net/tap/rte_eth_tap.c | 93 ++++++++++++++++++++++---------------------
1 file changed, 48 insertions(+), 45 deletions(-)
Comments
On Thu, 2 Feb 2017 16:33:27 -0600
Keith Wiles <keith.wiles@intel.com> wrote:
> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
> ---
> drivers/net/tap/rte_eth_tap.c | 93
> ++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+),
> 45 deletions(-)
>
> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
> index 3f179c3..9ed7a87 100644
> --- a/drivers/net/tap/rte_eth_tap.c
> +++ b/drivers/net/tap/rte_eth_tap.c
> @@ -115,10 +115,9 @@ struct pmd_internals {
> * supplied name.
> */
> static int
> -tun_alloc(char *name)
> +tun_alloc(char *name, uint16_t qid)
> {
> struct ifreq ifr;
> - unsigned int features;
> int fd;
>
> memset(&ifr, 0, sizeof(struct ifreq));
> @@ -133,55 +132,57 @@ tun_alloc(char *name)
> goto error;
> }
>
> - /* Grab the TUN features to verify we can work */
> - if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
> - RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
> - goto error;
> - }
> - RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features);
> + /* This can only be done once per interface */
> + if (qid == 0) {
> + unsigned int features;
> +
> + /* Grab the TUN features to verify we can work */
> + if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
> + RTE_LOG(ERR, PMD, "Unable to get TUN/TAP
> features\n");
> + goto error;
> + }
> + RTE_LOG(DEBUG, PMD, "TUN/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",
> - RTE_PMD_TAP_MAX_QUEUES);
> - }
> + 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",
> + 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_ONE_QUEUE;
> - RTE_LOG(DEBUG, PMD, "Single queue only support\n");
> - }
> + 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_ONE_QUEUE;
> + RTE_LOG(DEBUG, PMD, "Single queue only support\n");
> + }
> #endif
>
> - /* Set the TUN/TAP configuration and get 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);
> - perror("TUNSETIFF");
> - goto error;
> - }
> + /* Set the TUN/TAP configuration and get 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);
> + perror("TUNSETIFF");
> + goto error;
> + }
>
> - /* Always set the file descriptor to non-blocking */
> - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> - RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
> - perror("F_SETFL, NONBLOCK");
> - goto error;
> + /* Always set the file descriptor to non-blocking */
> + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
> + RTE_LOG(WARNING, PMD, "Unable to set %s to
> nonblocking\n",
> + ifr.ifr_name);
> + perror("F_SETFL, NONBLOCK");
> + 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);
> -
> return fd;
>
> error:
> @@ -512,7 +513,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->name, qid);
> if (fd < 0) {
> RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n",
> pmd->name); return -1;
> @@ -711,7 +712,7 @@ eth_dev_tap_create(const char *name, char *tap_name)
> snprintf(dev->data->name, sizeof(dev->data->name), "%s", name);
>
> /* Create the first Tap device */
> - fd = tun_alloc(tap_name);
> + fd = tun_alloc(tap_name, 0);
> if (fd < 0) {
> RTE_LOG(ERR, PMD, "tun_alloc() failed\n");
> goto error_exit;
> @@ -739,6 +740,8 @@ eth_dev_tap_create(const char *name, char *tap_name)
> error_exit:
> RTE_PMD_DEBUG_TRACE("Unable to initialize %s\n", name);
>
> + if (fd > 0)
> + close(fd);
> rte_free(data);
> rte_free(pmd);
>
The patch looks good to me.
Can you maybe detail in the commit log that now queue 0 is created while
probing, while other queues are handled through tap_setup_queue() only?
Pascal
> On Feb 3, 2017, at 3:37 AM, Pascal Mazon <pascal.mazon@6wind.com> wrote:
>
> On Thu, 2 Feb 2017 16:33:27 -0600
> Keith Wiles <keith.wiles@intel.com> wrote:
>
>> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>> ---
>> drivers/net/tap/rte_eth_tap.c | 93
>> ++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+),
>> 45 deletions(-)
>>
>> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
>> index 3f179c3..9ed7a87 100644
>> --- a/drivers/net/tap/rte_eth_tap.c
>> +++ b/drivers/net/tap/rte_eth_tap.c
>> @@ -115,10 +115,9 @@ struct pmd_internals {
>> * supplied name.
>> */
>> static int
>> -tun_alloc(char *name)
>> +tun_alloc(char *name, uint16_t qid)
>> {
>> struct ifreq ifr;
>> - unsigned int features;
>> int fd;
>>
>> memset(&ifr, 0, sizeof(struct ifreq));
>> @@ -133,55 +132,57 @@ tun_alloc(char *name)
>> goto error;
>> }
>>
>> - /* Grab the TUN features to verify we can work */
>> - if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
>> - RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
>> - goto error;
>> - }
>> - RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features);
>> + /* This can only be done once per interface */
>> + if (qid == 0) {
>> + unsigned int features;
>> +
>> + /* Grab the TUN features to verify we can work */
>> + if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
>> + RTE_LOG(ERR, PMD, "Unable to get TUN/TAP
>> features\n");
>> + goto error;
>> + }
>> + RTE_LOG(DEBUG, PMD, "TUN/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",
>> - RTE_PMD_TAP_MAX_QUEUES);
>> - }
>> + 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",
>> + 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_ONE_QUEUE;
>> - RTE_LOG(DEBUG, PMD, "Single queue only support\n");
>> - }
>> + 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_ONE_QUEUE;
>> + RTE_LOG(DEBUG, PMD, "Single queue only support\n");
>> + }
>> #endif
>>
>> - /* Set the TUN/TAP configuration and get 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);
>> - perror("TUNSETIFF");
>> - goto error;
>> - }
>> + /* Set the TUN/TAP configuration and get 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);
>> + perror("TUNSETIFF");
>> + goto error;
>> + }
>>
>> - /* Always set the file descriptor to non-blocking */
>> - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
>> - RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
>> - perror("F_SETFL, NONBLOCK");
>> - goto error;
>> + /* Always set the file descriptor to non-blocking */
>> + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
>> + RTE_LOG(WARNING, PMD, "Unable to set %s to
>> nonblocking\n",
>> + ifr.ifr_name);
>> + perror("F_SETFL, NONBLOCK");
>> + 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);
>> -
>> return fd;
>>
>> error:
>> @@ -512,7 +513,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->name, qid);
>> if (fd < 0) {
>> RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n",
>> pmd->name); return -1;
>> @@ -711,7 +712,7 @@ eth_dev_tap_create(const char *name, char *tap_name)
>> snprintf(dev->data->name, sizeof(dev->data->name), "%s", name);
>>
>> /* Create the first Tap device */
>> - fd = tun_alloc(tap_name);
>> + fd = tun_alloc(tap_name, 0);
>> if (fd < 0) {
>> RTE_LOG(ERR, PMD, "tun_alloc() failed\n");
>> goto error_exit;
>> @@ -739,6 +740,8 @@ eth_dev_tap_create(const char *name, char *tap_name)
>> error_exit:
>> RTE_PMD_DEBUG_TRACE("Unable to initialize %s\n", name);
>>
>> + if (fd > 0)
>> + close(fd);
>> rte_free(data);
>> rte_free(pmd);
>>
>
> The patch looks good to me.
>
> Can you maybe detail in the commit log that now queue 0 is created while
> probing, while other queues are handled through tap_setup_queue() only?
In my changes before your patch set I had removed creating queue 0 at probe and only created the interface/queue at queue setup time. It would have required a more changes compared to your patches and the original code. :-(
>
> Pascal
Regards,
Keith
@@ -115,10 +115,9 @@ struct pmd_internals {
* supplied name.
*/
static int
-tun_alloc(char *name)
+tun_alloc(char *name, uint16_t qid)
{
struct ifreq ifr;
- unsigned int features;
int fd;
memset(&ifr, 0, sizeof(struct ifreq));
@@ -133,55 +132,57 @@ tun_alloc(char *name)
goto error;
}
- /* Grab the TUN features to verify we can work */
- if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
- RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
- goto error;
- }
- RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features);
+ /* This can only be done once per interface */
+ if (qid == 0) {
+ unsigned int features;
+
+ /* Grab the TUN features to verify we can work */
+ if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
+ goto error;
+ }
+ RTE_LOG(DEBUG, PMD, "TUN/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",
- RTE_PMD_TAP_MAX_QUEUES);
- }
+ 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",
+ 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_ONE_QUEUE;
- RTE_LOG(DEBUG, PMD, "Single queue only support\n");
- }
+ 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_ONE_QUEUE;
+ RTE_LOG(DEBUG, PMD, "Single queue only support\n");
+ }
#endif
- /* Set the TUN/TAP configuration and get 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);
- perror("TUNSETIFF");
- goto error;
- }
+ /* Set the TUN/TAP configuration and get 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);
+ perror("TUNSETIFF");
+ goto error;
+ }
- /* Always set the file descriptor to non-blocking */
- if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
- RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
- perror("F_SETFL, NONBLOCK");
- goto error;
+ /* Always set the file descriptor to non-blocking */
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ RTE_LOG(WARNING, PMD, "Unable to set %s to nonblocking\n",
+ ifr.ifr_name);
+ perror("F_SETFL, NONBLOCK");
+ 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);
-
return fd;
error:
@@ -512,7 +513,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->name, qid);
if (fd < 0) {
RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n", pmd->name);
return -1;
@@ -711,7 +712,7 @@ eth_dev_tap_create(const char *name, char *tap_name)
snprintf(dev->data->name, sizeof(dev->data->name), "%s", name);
/* Create the first Tap device */
- fd = tun_alloc(tap_name);
+ fd = tun_alloc(tap_name, 0);
if (fd < 0) {
RTE_LOG(ERR, PMD, "tun_alloc() failed\n");
goto error_exit;
@@ -739,6 +740,8 @@ eth_dev_tap_create(const char *name, char *tap_name)
error_exit:
RTE_PMD_DEBUG_TRACE("Unable to initialize %s\n", name);
+ if (fd > 0)
+ close(fd);
rte_free(data);
rte_free(pmd);