From: Kumara Parameshwaran <kumaraparamesh92@gmail.com>
To: dev@dpdk.org
Cc: ferruh.yigit@intel.com,
Kumara Parameshwaran <kparameshwar@vmware.com>,
stable@dpdk.org
Subject: [PATCH v2] net/tap: fix to populate fds in secondary process
Date: Mon, 24 Jan 2022 18:07:43 +0530 [thread overview]
Message-ID: <20220124123743.70471-1-kumaraparamesh92@gmail.com> (raw)
In-Reply-To: <20220121042944.23929-1-kumaraparamesh92@gmail.com>
From: Kumara Parameshwaran <kparameshwar@vmware.com>
When a tap device is hotplugged to primary process which in turn
adds the device to all secondary process, the secondary process
does a tap_mp_attach_queues, but the fds are not populated in
the primary during the probe they are populated during the queue_setup,
added a fix to sync the queues during rte_eth_dev_start
Fixes: 4852aa8f6e21 ("drivers/net: enable hotplug on secondary process")
Cc: stable@dpdk.org
Signed-off-by: Kumara Parameshwaran <kparameshwar@vmware.com>
---
drivers/net/tap/rte_eth_tap.c | 196 +++++++++++++---------------------
lib/ethdev/ethdev_driver.h | 18 ++++
lib/ethdev/rte_ethdev.c | 11 ++
lib/ethdev/version.map | 1 +
4 files changed, 102 insertions(+), 124 deletions(-)
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index f1b48cae82..f6c25d7e21 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -66,7 +66,7 @@
(TAP_GSO_MBUFS_PER_CORE * TAP_GSO_MBUF_CACHE_SIZE)
/* IPC key for queue fds sync */
-#define TAP_MP_KEY "tap_mp_sync_queues"
+#define TAP_MP_REQ_START_RXTX "tap_mp_req_start_rxtx"
#define TAP_IOV_DEFAULT_MAX 1024
@@ -880,11 +880,48 @@ tap_link_set_up(struct rte_eth_dev *dev)
return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
}
+static int tap_mp_req_on_rxtx(struct rte_eth_dev *dev)
+{
+ struct rte_mp_msg msg;
+ struct ipc_queues *request_param = (struct ipc_queues *)msg.param;
+ int err;
+ int fd_iterator = 0;
+ struct pmd_process_private *process_private = dev->process_private;
+ int i;
+
+ memset(&msg, 0, sizeof(msg));
+ strlcpy(msg.name, TAP_MP_REQ_START_RXTX, sizeof(msg.name));
+ strlcpy(request_param->port_name, dev->data->name, sizeof(request_param->port_name));
+ msg.len_param = sizeof(*request_param);
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ msg.fds[fd_iterator++] = process_private->txq_fds[i];
+ msg.num_fds++;
+ request_param->txq_count++;
+ }
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ msg.fds[fd_iterator++] = process_private->rxq_fds[i];
+ msg.num_fds++;
+ request_param->rxq_count++;
+ }
+
+ err = rte_mp_sendmsg(&msg);
+ if (err < 0) {
+ TAP_LOG(ERR, "Failed to send start req to secondary %d",
+ rte_errno);
+ return -1;
+ }
+
+ return 0;
+}
+
static int
tap_dev_start(struct rte_eth_dev *dev)
{
int err, i;
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ tap_mp_req_on_rxtx(dev);
+
err = tap_intr_handle_set(dev, 1);
if (err)
return err;
@@ -901,6 +938,34 @@ tap_dev_start(struct rte_eth_dev *dev)
return err;
}
+static int
+tap_mp_req_start_rxtx(const struct rte_mp_msg *request, __rte_unused const void *peer)
+{
+ struct rte_eth_dev *dev;
+ const struct ipc_queues *request_param =
+ (const struct ipc_queues *)request->param;
+ int fd_iterator;
+ int queue;
+ struct pmd_process_private *process_private;
+
+ dev = rte_get_eth_dev_by_name(request_param->port_name);
+ if (!dev) {
+ TAP_LOG(ERR, "Failed to get dev for %s",
+ request_param->port_name);
+ return -1;
+ }
+ process_private = dev->process_private;
+ fd_iterator = 0;
+ TAP_LOG(DEBUG, "tap_attach rx_q:%d tx_q:%d\n", request_param->rxq_count,
+ request_param->txq_count);
+ for (queue = 0; queue < request_param->txq_count; queue++)
+ process_private->txq_fds[queue] = request->fds[fd_iterator++];
+ for (queue = 0; queue < request_param->rxq_count; queue++)
+ process_private->rxq_fds[queue] = request->fds[fd_iterator++];
+
+ return 0;
+}
+
/* This function gets called when the current port gets stopped.
*/
static int
@@ -1084,6 +1149,7 @@ tap_dev_close(struct rte_eth_dev *dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
rte_free(dev->process_private);
+ rte_mp_action_unregister(TAP_MP_REQ_START_RXTX);
return 0;
}
@@ -1140,8 +1206,6 @@ tap_dev_close(struct rte_eth_dev *dev)
internals->ioctl_sock = -1;
}
rte_free(dev->process_private);
- if (tap_devices_count == 1)
- rte_mp_action_unregister(TAP_MP_KEY);
tap_devices_count--;
/*
* Since TUN device has no more opened file descriptors
@@ -2292,113 +2356,6 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev)
return ret;
}
-/* Request queue file descriptors from secondary to primary. */
-static int
-tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev)
-{
- int ret;
- struct timespec timeout = {.tv_sec = 1, .tv_nsec = 0};
- struct rte_mp_msg request, *reply;
- struct rte_mp_reply replies;
- struct ipc_queues *request_param = (struct ipc_queues *)request.param;
- struct ipc_queues *reply_param;
- struct pmd_process_private *process_private = dev->process_private;
- int queue, fd_iterator;
-
- /* Prepare the request */
- memset(&request, 0, sizeof(request));
- strlcpy(request.name, TAP_MP_KEY, sizeof(request.name));
- strlcpy(request_param->port_name, port_name,
- sizeof(request_param->port_name));
- request.len_param = sizeof(*request_param);
- /* Send request and receive reply */
- ret = rte_mp_request_sync(&request, &replies, &timeout);
- if (ret < 0 || replies.nb_received != 1) {
- TAP_LOG(ERR, "Failed to request queues from primary: %d",
- rte_errno);
- return -1;
- }
- reply = &replies.msgs[0];
- reply_param = (struct ipc_queues *)reply->param;
- TAP_LOG(DEBUG, "Received IPC reply for %s", reply_param->port_name);
-
- /* Attach the queues from received file descriptors */
- if (reply_param->rxq_count + reply_param->txq_count != reply->num_fds) {
- TAP_LOG(ERR, "Unexpected number of fds received");
- return -1;
- }
-
- dev->data->nb_rx_queues = reply_param->rxq_count;
- dev->data->nb_tx_queues = reply_param->txq_count;
- fd_iterator = 0;
- for (queue = 0; queue < reply_param->rxq_count; queue++)
- process_private->rxq_fds[queue] = reply->fds[fd_iterator++];
- for (queue = 0; queue < reply_param->txq_count; queue++)
- process_private->txq_fds[queue] = reply->fds[fd_iterator++];
- free(reply);
- return 0;
-}
-
-/* Send the queue file descriptors from the primary process to secondary. */
-static int
-tap_mp_sync_queues(const struct rte_mp_msg *request, const void *peer)
-{
- struct rte_eth_dev *dev;
- struct pmd_process_private *process_private;
- struct rte_mp_msg reply;
- const struct ipc_queues *request_param =
- (const struct ipc_queues *)request->param;
- struct ipc_queues *reply_param =
- (struct ipc_queues *)reply.param;
- uint16_t port_id;
- int queue;
- int ret;
-
- /* Get requested port */
- TAP_LOG(DEBUG, "Received IPC request for %s", request_param->port_name);
- ret = rte_eth_dev_get_port_by_name(request_param->port_name, &port_id);
- if (ret) {
- TAP_LOG(ERR, "Failed to get port id for %s",
- request_param->port_name);
- return -1;
- }
- dev = &rte_eth_devices[port_id];
- process_private = dev->process_private;
-
- /* Fill file descriptors for all queues */
- reply.num_fds = 0;
- reply_param->rxq_count = 0;
- if (dev->data->nb_rx_queues + dev->data->nb_tx_queues >
- RTE_MP_MAX_FD_NUM){
- TAP_LOG(ERR, "Number of rx/tx queues exceeds max number of fds");
- return -1;
- }
-
- for (queue = 0; queue < dev->data->nb_rx_queues; queue++) {
- reply.fds[reply.num_fds++] = process_private->rxq_fds[queue];
- reply_param->rxq_count++;
- }
- RTE_ASSERT(reply_param->rxq_count == dev->data->nb_rx_queues);
-
- reply_param->txq_count = 0;
- for (queue = 0; queue < dev->data->nb_tx_queues; queue++) {
- reply.fds[reply.num_fds++] = process_private->txq_fds[queue];
- reply_param->txq_count++;
- }
- RTE_ASSERT(reply_param->txq_count == dev->data->nb_tx_queues);
-
- /* Send reply */
- strlcpy(reply.name, request->name, sizeof(reply.name));
- strlcpy(reply_param->port_name, request_param->port_name,
- sizeof(reply_param->port_name));
- reply.len_param = sizeof(*reply_param);
- if (rte_mp_reply(&reply, peer) < 0) {
- TAP_LOG(ERR, "Failed to reply an IPC request to sync queues");
- return -1;
- }
- return 0;
-}
-
/* Open a TAP interface device.
*/
static int
@@ -2442,9 +2399,11 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
return -1;
}
- ret = tap_mp_attach_queues(name, eth_dev);
- if (ret != 0)
- return -1;
+ ret = rte_mp_action_register(TAP_MP_REQ_START_RXTX, tap_mp_req_start_rxtx);
+ if (ret < 0 && rte_errno != ENOTSUP)
+ TAP_LOG(ERR, "tap: Failed to register IPC callback: %s",
+ strerror(rte_errno));
+
rte_eth_dev_probing_finish(eth_dev);
return 0;
}
@@ -2492,15 +2451,6 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
TAP_LOG(DEBUG, "Initializing pmd_tap for %s", name);
- /* Register IPC feed callback */
- if (!tap_devices_count) {
- ret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues);
- if (ret < 0 && rte_errno != ENOTSUP) {
- TAP_LOG(ERR, "tap: Failed to register IPC callback: %s",
- strerror(rte_errno));
- goto leave;
- }
- }
tap_devices_count++;
tap_devices_count_increased = 1;
ret = eth_dev_tap_create(dev, tap_name, remote_iface, &user_mac,
@@ -2511,8 +2461,6 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
TAP_LOG(ERR, "Failed to create pmd for %s as %s",
name, tap_name);
if (tap_devices_count_increased == 1) {
- if (tap_devices_count == 1)
- rte_mp_action_unregister(TAP_MP_KEY);
tap_devices_count--;
}
}
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index d95605a355..04b3a9f933 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1629,6 +1629,24 @@ rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue,
struct rte_hairpin_peer_info *peer_info,
uint32_t direction);
+/**
+ * @internal
+ * Get rte_eth_dev from device name. The device name should be specified
+ * as below:
+ * - PCIe address (Domain:Bus:Device.Function), for example- 0000:2:00.0
+ * - SoC device name, for example- fsl-gmac0
+ * - vdev dpdk name, for example- net_[pcap0|null0|tap0]
+ *
+ * @param name
+ * pci address or name of the device
+ * @return
+ * - rte_eth_dev if successful
+ * - NULL on failure
+ */
+__rte_internal
+struct rte_eth_dev*
+rte_get_eth_dev_by_name(const char *name);
+
/**
* @internal
* Reset the current queue state and configuration to disconnect (unbind) it
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index a1d475a292..9192b0d664 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -894,6 +894,17 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
return -ENODEV;
}
+struct rte_eth_dev *
+rte_get_eth_dev_by_name(const char *name)
+{
+ uint16_t pid;
+
+ if (rte_eth_dev_get_port_by_name(name, &pid))
+ return NULL;
+
+ return &rte_eth_devices[pid];
+}
+
static int
eth_err(uint16_t port_id, int ret)
{
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index c2fb0669a4..23ca0e8865 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -282,4 +282,5 @@ INTERNAL {
rte_eth_representor_id_get;
rte_eth_switch_domain_alloc;
rte_eth_switch_domain_free;
+ rte_get_eth_dev_by_name;
};
--
2.17.1
next prev parent reply other threads:[~2022-01-24 12:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-21 4:29 [PATCH] net/tap: Bug fix to populate fds in secondary process Kumara Parameshwaran
2022-01-24 9:47 ` Ferruh Yigit
2022-01-24 12:12 ` [PATCH v2] net/tap: " Kumara Parameshwaran
2022-01-24 12:35 ` Ferruh Yigit
2022-01-24 12:48 ` Kumara Parameshwaran
2022-01-24 12:54 ` kumaraparameshwaran rathinavel
2022-01-24 13:05 ` Ferruh Yigit
2022-01-28 9:55 ` kumaraparameshwaran rathinavel
2022-01-28 12:55 ` Ferruh Yigit
2022-01-24 12:37 ` Kumara Parameshwaran [this message]
2022-01-24 13:06 ` Ferruh Yigit
2022-01-31 14:21 ` [PATCH v3 1/2] ethdev: define a function to get eth dev structure Kumara Parameshwaran
2022-01-31 14:21 ` [PATCH v3 2/2] net/tap: fix to populate fds in secondary process Kumara Parameshwaran
2022-01-31 14:32 ` [PATCH v3 1/2] ethdev: define a function to get eth dev structure Kumara Parameshwaran
2022-01-31 14:32 ` [PATCH v3 2/2] net/tap: fix to populate fds in secondary process Kumara Parameshwaran
2022-02-01 16:57 ` Ferruh Yigit
2022-02-01 16:56 ` [PATCH v3 1/2] ethdev: define a function to get eth dev structure Ferruh Yigit
2022-02-01 17:12 ` Ferruh Yigit
2022-02-01 17:15 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220124123743.70471-1-kumaraparamesh92@gmail.com \
--to=kumaraparamesh92@gmail.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=kparameshwar@vmware.com \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.