From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Anatoly Burakov <anatoly.burakov@intel.com>
Subject: [PATCH v5 08/10] net/rtap: add multi-process support
Date: Mon, 9 Feb 2026 10:39:07 -0800 [thread overview]
Message-ID: <20260209184045.132774-9-stephen@networkplumber.org> (raw)
In-Reply-To: <20260209184045.132774-1-stephen@networkplumber.org>
Add support for DPDK multi-process operation. Secondary processes
need access to the per-queue TAP file descriptors owned by the
primary process.
Implement fd sharing using the DPDK multi-process IPC mechanism:
- Primary registers an MP action handler that responds to fd
requests by sending queue fds via rte_mp_reply()
- Secondary process attaches to the existing device and requests
fds from primary via rte_mp_request_sync()
The MP action is registered on the first device probe and
unregistered when the last device is closed.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/guides/nics/features/rtap.ini | 1 +
drivers/net/rtap/rtap_ethdev.c | 130 ++++++++++++++++++++++++++++++
2 files changed, 131 insertions(+)
diff --git a/doc/guides/nics/features/rtap.ini b/doc/guides/nics/features/rtap.ini
index 36a14e9696..fe0c88a8fc 100644
--- a/doc/guides/nics/features/rtap.ini
+++ b/doc/guides/nics/features/rtap.ini
@@ -14,6 +14,7 @@ Basic stats = Y
Stats per queue = Y
TSO = Y
L4 checksum offload = Y
+Multiprocess aware = Y
Linux = Y
ARMv7 = Y
ARMv8 = Y
diff --git a/drivers/net/rtap/rtap_ethdev.c b/drivers/net/rtap/rtap_ethdev.c
index 8c22021655..9b8ad1f452 100644
--- a/drivers/net/rtap/rtap_ethdev.c
+++ b/drivers/net/rtap/rtap_ethdev.c
@@ -42,6 +42,8 @@
RTE_ETH_RX_OFFLOAD_TCP_LRO | \
RTE_ETH_RX_OFFLOAD_SCATTER)
+#define RTAP_MP_KEY "rtap_mp_send_fds"
+
#define RTAP_DEFAULT_BURST 64
#define RTAP_NUM_BUFFERS 1024
#define RTAP_MAX_QUEUES 128
@@ -53,6 +55,8 @@ static_assert(RTAP_MAX_QUEUES <= RTE_MP_MAX_FD_NUM, "Max queues exceeds MP fd li
#define RTAP_IFACE_ARG "iface"
#define RTAP_PERSIST_ARG "persist"
+static RTE_ATOMIC(unsigned int) rtap_dev_count;
+
static const char * const valid_arguments[] = {
RTAP_IFACE_ARG,
RTAP_PERSIST_ARG,
@@ -530,6 +534,8 @@ rtap_dev_close(struct rte_eth_dev *dev)
free(dev->process_private);
dev->process_private = NULL;
+ if (rte_atomic_fetch_sub_explicit(&rtap_dev_count, 1, rte_memory_order_release) == 1)
+ rte_mp_action_unregister(RTAP_MP_KEY);
return 0;
}
@@ -669,6 +675,89 @@ rtap_parse_iface(const char *key __rte_unused, const char *value, void *extra_ar
return 0;
}
+/* Secondary process requests rxq fds from primary. */
+static int
+rtap_request_fds(const char *name, struct rte_eth_dev *dev)
+{
+ struct rte_mp_msg request = { };
+
+ strlcpy(request.name, RTAP_MP_KEY, sizeof(request.name));
+ strlcpy((char *)request.param, name, RTE_MP_MAX_PARAM_LEN);
+ request.len_param = strlen(name);
+
+ /* Send the request and receive the reply */
+ PMD_LOG(DEBUG, "Sending multi-process IPC request for %s", name);
+
+ struct timespec timeout = {.tv_sec = 1, .tv_nsec = 0};
+ struct rte_mp_reply replies;
+ int ret = rte_mp_request_sync(&request, &replies, &timeout);
+ if (ret < 0 || replies.nb_received != 1) {
+ PMD_LOG(ERR, "Failed to request fds from primary: %s",
+ rte_strerror(rte_errno));
+ return -1;
+ }
+
+ struct rte_mp_msg *reply = replies.msgs;
+ PMD_LOG(DEBUG, "Received multi-process IPC reply for %s", name);
+ if (dev->data->nb_rx_queues != reply->num_fds) {
+ PMD_LOG(ERR, "Incorrect number of fds received: %d != %d",
+ reply->num_fds, dev->data->nb_rx_queues);
+ free(reply);
+ return -EINVAL;
+ }
+
+ int *fds = dev->process_private;
+ for (int i = 0; i < reply->num_fds; i++) {
+ fds[i] = reply->fds[i];
+ PMD_LOG(DEBUG, "Received queue %u fd %d from primary", i, fds[i]);
+ }
+
+ free(reply);
+ return 0;
+}
+
+/* Primary process sends rxq fds to secondary. */
+static int
+rtap_mp_send_fds(const struct rte_mp_msg *request, const void *peer)
+{
+ const char *request_name = (const char *)request->param;
+
+ PMD_LOG(DEBUG, "Received multi-process IPC request for %s", request_name);
+
+ /* Find the requested port */
+ struct rte_eth_dev *dev = rte_eth_dev_get_by_name(request_name);
+ if (!dev) {
+ PMD_LOG(ERR, "Failed to get port id for %s", request_name);
+ return -1;
+ }
+
+ /* Populate the reply with the fds for each queue */
+ struct rte_mp_msg reply = { };
+ if (dev->data->nb_rx_queues > RTE_MP_MAX_FD_NUM) {
+ PMD_LOG(ERR, "Number of rx queues (%d) exceeds max number of fds (%d)",
+ dev->data->nb_rx_queues, RTE_MP_MAX_FD_NUM);
+ return -EINVAL;
+ }
+
+ int *fds = dev->process_private;
+ for (uint16_t i = 0; i < dev->data->nb_rx_queues; i++) {
+ PMD_LOG(DEBUG, "Send queue %u fd %d to secondary", i, fds[i]);
+ reply.fds[reply.num_fds++] = fds[i];
+ }
+
+ /* Send the reply */
+ strlcpy(reply.name, request->name, sizeof(reply.name));
+ strlcpy((char *)reply.param, request_name, RTE_MP_MAX_PARAM_LEN);
+ reply.len_param = strlen(request_name);
+
+ PMD_LOG(DEBUG, "Sending multi-process IPC reply for %s", request_name);
+ if (rte_mp_reply(&reply, peer) < 0) {
+ PMD_LOG(ERR, "Failed to reply to multi-process IPC request");
+ return -1;
+ }
+ return 0;
+}
+
static int
rtap_probe(struct rte_vdev_device *vdev)
{
@@ -683,6 +772,38 @@ rtap_probe(struct rte_vdev_device *vdev)
PMD_LOG(INFO, "Initializing %s", name);
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ eth_dev = rte_eth_dev_attach_secondary(name);
+ if (!eth_dev) {
+ PMD_LOG(ERR, "Failed to probe %s", name);
+ return -1;
+ }
+ eth_dev->dev_ops = &rtap_ops;
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+ eth_dev->device = &vdev->device;
+
+ if (!rte_eal_primary_proc_alive(NULL)) {
+ PMD_LOG(ERR, "Primary process is missing");
+ goto error;
+ }
+
+ fds = calloc(RTE_MAX_QUEUES_PER_PORT, sizeof(int));
+ if (fds == NULL) {
+ PMD_LOG(ERR, "Failed to alloc memory for process private");
+ goto error;
+ }
+ for (uint16_t i = 0; i < RTE_MAX_QUEUES_PER_PORT; i++)
+ fds[i] = -1;
+
+ eth_dev->process_private = fds;
+
+ if (rtap_request_fds(name, eth_dev))
+ goto error;
+
+ rte_eth_dev_probing_finish(eth_dev);
+ return 0;
+ }
+
if (params != NULL) {
kvlist = rte_kvargs_parse(params, valid_arguments);
if (kvlist == NULL)
@@ -721,6 +842,15 @@ rtap_probe(struct rte_vdev_device *vdev)
if (rtap_create(eth_dev, tap_name, persist) < 0)
goto error;
+ /* register the MP server on the first device */
+ if (rte_atomic_fetch_add_explicit(&rtap_dev_count, 1, rte_memory_order_acquire) == 0) {
+ if (rte_mp_action_register(RTAP_MP_KEY, rtap_mp_send_fds) < 0) {
+ PMD_LOG(ERR, "Failed to register multi-process callback: %s",
+ rte_strerror(rte_errno));
+ goto error;
+ }
+ }
+
rte_eth_dev_probing_finish(eth_dev);
rte_kvargs_free(kvlist);
return 0;
--
2.51.0
next prev parent reply other threads:[~2026-02-09 18:41 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-10 21:23 [RFC 0/8] ioring: network driver Stephen Hemminger
2024-12-10 21:23 ` [RFC 1/8] net/ioring: introduce new driver Stephen Hemminger
2024-12-10 21:23 ` [RFC 2/8] net/ioring: implement link state Stephen Hemminger
2024-12-10 21:23 ` [RFC 3/8] net/ioring: implement control functions Stephen Hemminger
2024-12-10 21:23 ` [RFC 4/8] net/ioring: implement management functions Stephen Hemminger
2024-12-10 21:23 ` [RFC 5/8] net/ioring: implement primary secondary fd passing Stephen Hemminger
2024-12-10 21:23 ` [RFC 6/8] net/ioring: implement receive and transmit Stephen Hemminger
2024-12-10 21:23 ` [RFC 7/8] net/ioring: add VLAN support Stephen Hemminger
2024-12-10 21:23 ` [RFC 8/8] net/ioring: implement statistics Stephen Hemminger
2024-12-11 11:34 ` [RFC 0/8] ioring: network driver Konstantin Ananyev
2024-12-11 15:03 ` Stephen Hemminger
2024-12-12 19:06 ` Konstantin Ananyev
2024-12-19 15:40 ` Morten Brørup
2024-12-20 14:34 ` Konstantin Ananyev
2024-12-20 16:19 ` Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 " Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 1/8] net/ioring: introduce new driver Stephen Hemminger
2024-12-28 16:39 ` Morten Brørup
2024-12-11 16:28 ` [PATCH v2 2/8] net/ioring: implement link state Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 3/8] net/ioring: implement control functions Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 4/8] net/ioring: implement management functions Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 5/8] net/ioring: implement primary secondary fd passing Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 6/8] net/ioring: implement receive and transmit Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 7/8] net/ioring: add VLAN support Stephen Hemminger
2024-12-11 16:28 ` [PATCH v2 8/8] net/ioring: implement statistics Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 0/9] ioring PMD device Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 1/9] net/ioring: introduce new driver Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 2/9] net/ioring: implement link state Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 3/9] net/ioring: implement control functions Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 4/9] net/ioring: implement management functions Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 5/9] net/ioring: implement secondary process support Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 6/9] net/ioring: implement receive and transmit Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 7/9] net/ioring: add VLAN support Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 8/9] net/ioring: implement statistics Stephen Hemminger
2025-03-11 23:51 ` [PATCH v3 9/9] net/ioring: support multi-segment Rx and Tx Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 00/10] new ioring PMD Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 01/10] net/ioring: introduce new driver Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 02/10] net/ioring: implement link state Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 03/10] net/ioring: implement control functions Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 04/10] net/ioring: implement management functions Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 05/10] net/ioring: implement secondary process support Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 06/10] net/ioring: implement receive and transmit Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 07/10] net/ioring: implement statistics Stephen Hemminger
2025-03-13 21:50 ` [PATCH v4 08/10] net/ioring: support multi-segment Rx and Tx Stephen Hemminger
2025-03-13 21:51 ` [PATCH v4 09/10] net/ioring: support Tx checksum and segment offload Stephen Hemminger
2025-03-13 21:51 ` [PATCH v4 10/10] net/ioring: add support for Rx offload Stephen Hemminger
2026-02-09 18:38 ` [PATCH v5 00/10] net/rtap: add io_uring based TAP driver Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 01/10] net/rtap: add driver skeleton and documentation Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 02/10] net/rtap: add TAP device creation and queue management Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 03/10] net/rtap: add Rx/Tx with scatter/gather support Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 04/10] net/rtap: add statistics and device info Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 05/10] net/rtap: add link and device management operations Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 06/10] net/rtap: add checksum and TSO offload support Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 07/10] net/rtap: add link state change interrupt Stephen Hemminger
2026-02-09 18:39 ` Stephen Hemminger [this message]
2026-02-09 18:39 ` [PATCH v5 09/10] net/rtap: add Rx interrupt support Stephen Hemminger
2026-02-09 18:39 ` [PATCH v5 10/10] test: add unit tests for rtap PMD Stephen Hemminger
2026-02-10 9:18 ` [PATCH v5 00/10] net/rtap: add io_uring based TAP driver Morten Brørup
2026-02-14 23:44 ` [PATCH v6 00/11] " Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 01/11] net/rtap: add driver skeleton and documentation Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 02/11] net/rtap: add TAP device creation and queue management Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 03/11] net/rtap: add Rx/Tx with scatter/gather support Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 04/11] net/rtap: add statistics and device info Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 05/11] net/rtap: add link and device management operations Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 06/11] net/rtap: add checksum and TSO offload support Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 07/11] net/rtap: add multi-process support Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 08/11] net/rtap: add link state change interrupt Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 09/11] net/rtap: add Rx interrupt support Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 10/11] net/rtap: add extended statistics support Stephen Hemminger
2026-02-14 23:44 ` [PATCH v6 11/11] test: add unit tests for rtap PMD Stephen Hemminger
2026-02-15 8:58 ` [PATCH v6 00/11] net/rtap: add io_uring based TAP driver Konstantin Ananyev
2026-02-15 17:08 ` Stephen Hemminger
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=20260209184045.132774-9-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=anatoly.burakov@intel.com \
--cc=dev@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.