[dpdk-dev,2/5] net/tap: fix multi-queue support

Message ID 20170202223330.39240-2-keith.wiles@intel.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel compilation success Compilation OK

Commit Message

Wiles, Keith Feb. 2, 2017, 10:33 p.m. UTC
  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

Pascal Mazon Feb. 3, 2017, 9:37 a.m. UTC | #1
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
  
Wiles, Keith Feb. 3, 2017, 8:32 p.m. UTC | #2
> 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
  

Patch

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);