[dpdk-stable] patch 'net/tap: fix device removal when no queue exist' has been queued to stable release 18.02.2

luca.boccassi at gmail.com luca.boccassi at gmail.com
Wed May 23 14:09:59 CEST 2018


Hi,

FYI, your patch has been queued to stable release 18.02.2

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 05/25/18. So please
shout if anyone has objections.

Thanks.

Luca Boccassi

---
>From 94106a31e6645023b9a942dc4dd58fee334a6321 Mon Sep 17 00:00:00 2001
From: Ophir Munk <ophirmu at mellanox.com>
Date: Mon, 21 May 2018 07:54:33 +0000
Subject: [PATCH] net/tap: fix device removal when no queue exist

[ upstream commit 3101191c63ab25a9d743b96cc004eec2e9a8c1cc ]

TAP device is created following its first queue creation. Multiple
queues can be added or removed over time. In Linux terminology those
are file descriptors which are opened or closed over time. As long as
the number of opened file descriptors is positive - TAP device will
appear as a Linux device. In case all queues are released (the
equivalent of all file descriptors being closed) the TAP device will
be removed. This can lead to abnormalities in different scenarios
where the TAP device should exist even if all its queues are released.
In order to make TAP existence independent of its number of queues -
an extra file descriptor is opened on TAP creation and is closed on
TAP closure. Its only purpose is to serve as a keep-alive mechanism
for the TAP device.

Fixes: bf7b7f437b49 ("net/tap: create netdevice during probing")

Signed-off-by: Ophir Munk <ophirmu at mellanox.com>
Acked-by: Keith Wiles <keith.wiles at intel.com>
---
 drivers/net/tap/rte_eth_tap.c | 31 ++++++++++++++++++++++++-------
 drivers/net/tap/rte_eth_tap.h |  1 +
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 6ce02c9b6..b9b9397b9 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -824,6 +824,15 @@ tap_dev_close(struct rte_eth_dev *dev)
 		ioctl(internals->ioctl_sock, SIOCSIFFLAGS,
 				&internals->remote_initial_flags);
 	}
+
+	if (internals->ka_fd != -1) {
+		close(internals->ka_fd);
+		internals->ka_fd = -1;
+	}
+	/*
+	 * Since TUN device has no more opened file descriptors
+	 * it will be removed from kernel
+	 */
 }
 
 static void
@@ -1389,6 +1398,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
 	dev->intr_handle = &pmd->intr_handle;
 
 	/* Presetup the fds to -1 as being not valid */
+	pmd->ka_fd = -1;
 	for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
 		pmd->rxq[i].fd = -1;
 		pmd->txq[i].fd = -1;
@@ -1405,13 +1415,17 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
 		eth_random_addr((uint8_t *)&pmd->eth_addr);
 	}
 
-	/* Immediately create the netdevice (this will create the 1st queue). */
-	/* rx queue */
-	if (tap_setup_queue(dev, pmd, 0, 1) == -1)
-		goto error_exit;
-	/* tx queue */
-	if (tap_setup_queue(dev, pmd, 0, 0) == -1)
+	/*
+	 * Allocate a TUN device keep-alive file descriptor that will only be
+	 * closed when the TUN device itself is closed or removed.
+	 * This keep-alive file descriptor will guarantee that the TUN device
+	 * exists even when all of its queues are closed
+	 */
+	pmd->ka_fd = tun_alloc(pmd);
+	if (pmd->ka_fd == -1) {
+		RTE_LOG(ERR, PMD, "Unable to create %s interface", tap_name);
 		goto error_exit;
+	}
 
 	ifr.ifr_mtu = dev->data->mtu;
 	if (tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1, LOCAL_AND_REMOTE) < 0)
@@ -1685,9 +1699,12 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev)
 	close(internals->ioctl_sock);
 	rte_free(eth_dev->data->dev_private);
 	rte_free(eth_dev->data);
-
 	rte_eth_dev_release_port(eth_dev);
 
+	if (internals->ka_fd != -1) {
+		close(internals->ka_fd);
+		internals->ka_fd = -1;
+	}
 	return 0;
 }
 
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 53a506add..dcafd6df1 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -76,6 +76,7 @@ struct pmd_internals {
 	struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */
 	struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */
 	struct rte_intr_handle intr_handle;          /* LSC interrupt handle. */
+	int ka_fd;                        /* keep-alive file descriptor */
 };
 
 /* tap_intr.c */
-- 
2.14.2



More information about the stable mailing list