[PATCH] net/tap: defer qdisc initialisation for rte_flow

David Marchand david.marchand at redhat.com
Tue Feb 24 16:27:44 CET 2026


qdisc setup is required when using a remote_iface or when creating
rte_flow rules.
Otherwise, many applications don't care about it.

Let's postpone the qdisc init to when it is really needed, that will
avoid spewing ERR logs for nothing.

Signed-off-by: David Marchand <david.marchand at redhat.com>
---
 drivers/net/tap/rte_eth_tap.c | 32 +++++---------------------------
 drivers/net/tap/rte_eth_tap.h |  1 +
 drivers/net/tap/tap_flow.c    | 26 ++++++++++++++++++++++++++
 drivers/net/tap/tap_flow.h    |  2 ++
 4 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 7a8a98cddb..71fb0a74fa 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -2122,26 +2122,14 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
 	pmd->persist = persist;
 
 #ifdef HAVE_TCA_FLOWER
-	/*
-	 * Set up everything related to rte_flow:
-	 * - mandatory QDISCs
-	 * - rte_flow actual/implicit lists
-	 * - implicit rules
-	 */
-	if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) {
-		TAP_LOG(ERR, "%s: failed to create multiq qdisc.",
-			pmd->name);
-		goto disable_rte_flow;
-	}
-	if (qdisc_create_ingress(pmd->nlsk_fd, pmd->if_index) < 0) {
-		TAP_LOG(ERR, "%s: failed to create ingress qdisc.",
-			pmd->name);
-		goto disable_rte_flow;
-	}
-
 	LIST_INIT(&pmd->flows);
 
 	if (strlen(remote_iface)) {
+		if (tap_flow_init(pmd) < 0) {
+			TAP_LOG(ERR, "Remote feature requires flow support.");
+			goto error_exit;
+		}
+
 		pmd->remote_if_index = if_nametoindex(remote_iface);
 		if (!pmd->remote_if_index) {
 			TAP_LOG(ERR, "%s: failed to get %s if_index.",
@@ -2196,16 +2184,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
 	rte_eth_dev_probing_finish(dev);
 	return 0;
 
-disable_rte_flow:
-	TAP_LOG(ERR, " Disabling rte flow support: %s(%d)",
-		strerror(errno), errno);
-	if (strlen(remote_iface)) {
-		TAP_LOG(ERR, "Remote feature requires flow support.");
-		goto error_exit;
-	}
-	rte_eth_dev_probing_finish(dev);
-	return 0;
-
 #ifdef HAVE_TCA_FLOWER
 error_remote:
 	TAP_LOG(ERR, " Can't set up remote feature: %s(%d)",
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 218ee1b811..59d61582cc 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -79,6 +79,7 @@ struct pmd_internals {
 	int nlsk_fd;                      /* Netlink socket fd */
 
 #ifdef HAVE_TCA_FLOWER
+	int flow_init;                    /* 1 if qdiscs were created */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 
 	struct tap_rss *rss;		  /* BPF program */
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 9d4ef27a8a..8877cef3ff 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1235,6 +1235,12 @@ tap_flow_create(struct rte_eth_dev *dev,
 	struct tap_nlmsg *msg = NULL;
 	int err;
 
+	if (pmd->flow_init == 0 && tap_flow_init(pmd) < 0) {
+		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				   NULL,
+				   "can't create rule, qdisc not initialized");
+		goto fail;
+	}
 	if (!pmd->if_index) {
 		rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
 				   NULL,
@@ -1875,6 +1881,26 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 }
 #endif
 
+int
+tap_flow_init(struct pmd_internals *pmd)
+{
+	if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) {
+		TAP_LOG(ERR, "%s: failed to create multiq qdisc.",
+			pmd->name);
+		return -1;
+	}
+
+	if (qdisc_create_ingress(pmd->nlsk_fd, pmd->if_index) < 0) {
+		TAP_LOG(ERR, "%s: failed to create ingress qdisc.",
+			pmd->name);
+		return -1;
+	}
+
+	pmd->flow_init = 1;
+
+	return 0;
+}
+
 /**
  * Get rte_flow operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 8b19347a93..49e7e04050 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -45,6 +45,8 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+int tap_flow_init(struct pmd_internals *pmd);
+
 int tap_dev_flow_ops_get(struct rte_eth_dev *dev,
 			 const struct rte_flow_ops **ops);
 int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error);
-- 
2.53.0



More information about the dev mailing list