From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 69EEBA04A8 for ; Mon, 24 Jan 2022 13:55:10 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 56B1C427CB; Mon, 24 Jan 2022 13:55:10 +0100 (CET) Received: from mail-il1-f171.google.com (mail-il1-f171.google.com [209.85.166.171]) by mails.dpdk.org (Postfix) with ESMTP id 05E4840E0F; Mon, 24 Jan 2022 13:55:08 +0100 (CET) Received: by mail-il1-f171.google.com with SMTP id r16so13747126ile.8; Mon, 24 Jan 2022 04:55:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=zqQ7P9nTcbnICPEUWdVQlY26SNhuV3IQf2kViqFhmmY=; b=FP7kWbIFvaCxEIuydIo/i83mTztqnBGFvSdE6CaLYVAhA8b9GqszOdVZA4y+579m7c unXyH5VazulyjXd7h9nNh2Vt1q7ruxQCmN8dR/7LCOez4THvtjLhB+fstuihTMzKAioT zKHrJ1M9t8KTXKujriN/nQjX6763QNpeZMfQCxSbtBXw/sC1SNsPAXl4Vcol7ZQDoBuF 3xUD+LEKpPK7Hb687YbWRq7LU+hVG9ZsLKTGHhLLlS80IEknGLZjCWYsExn+e0QRw6G+ ILpmMd9rdNGxWXyY1L72ow+TtOjvHBeqXz6EU5neONUHFfiYsC1AGDsQLUVcvJeaxmta 4EnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=zqQ7P9nTcbnICPEUWdVQlY26SNhuV3IQf2kViqFhmmY=; b=tSN5JUMStzjJyCIg0D1tPoSSQ+kjUsyy1yNU06uS0qNSg5Il7jL6qaJCfP5Nf6z2xM M+L1tqP9Ib8rgFQdfB7V1WKpfYxYh6Lsvh1dNg6Rp2q9IRQ0J+k/syXDgHLRUOEwcXPj lJR+yapHGlaYrjVZe3reYXVdVuBRbjqfBlzxpy6rGYkQuCrZsYN+VsFRsEPGmqcU2nTu IVWT8J61dNjgM0KmF7xoZhoJTr4zkpfsE/vsIXaw3x5nbNjuJItu/QSFo2H4bHkq+kUz yOp+7xO/69VIDZ2q+k4d3f4QjjeEuP+7PqFMibSyBUgZhLONHw6FIjMScsC5Kj4O8J2Z HYJg== X-Gm-Message-State: AOAM532ua2+btMyvRu8mgUcMGDdlk+gW4zmtsZpV/6DZ4Ai8npJV6obt ve8Fa4fYHoxG/Yi2uBqXFlEzNOZJIYq+tBiNJmA= X-Google-Smtp-Source: ABdhPJypakq1/cATux6VdpP6+4VXsvQHF6rtyflXqV+Y5j6flvhho6s4E7JqSX7RQ1ume4u419ujmSi5/dicOHLknKs= X-Received: by 2002:a05:6e02:1ba9:: with SMTP id n9mr7074451ili.278.1643028907139; Mon, 24 Jan 2022 04:55:07 -0800 (PST) MIME-Version: 1.0 References: <20220121042944.23929-1-kumaraparamesh92@gmail.com> <20220124121251.64762-1-kumaraparamesh92@gmail.com> In-Reply-To: From: kumaraparameshwaran rathinavel Date: Mon, 24 Jan 2022 18:24:55 +0530 Message-ID: Subject: Re: [PATCH v2] net/tap: fix to populate fds in secondary process To: Ferruh Yigit Cc: dev@dpdk.org, Kumara Parameshwaran , stable@dpdk.org Content-Type: multipart/alternative; boundary="0000000000005da55705d6537a17" X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org --0000000000005da55705d6537a17 Content-Type: text/plain; charset="UTF-8" On Mon, Jan 24, 2022 at 6:05 PM Ferruh Yigit wrote: > On 1/24/2022 12:12 PM, Kumara Parameshwaran wrote: > > From: Kumara Parameshwaran > > > > 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 > > --- > > > > v2: > > * Addressed review comments to move the function declaration and version > > map > > > > Thanks for adding patch version. > > > drivers/net/tap/rte_eth_tap.c | 196 +++++++++++++--------------------- > > lib/ethdev/ethdev_driver.h | 17 +++ > > lib/ethdev/rte_ethdev.c | 11 ++ > > lib/ethdev/version.map | 2 + > > 4 files changed, 102 insertions(+), 124 deletions(-) > > > > Can you please separate etdev (API) changes to another patch, so this will > be a patchset > with two patches, > first patch adds ethdev API > second patch is tap patch, that uses the API in the first patch Sure, I will do it. > > > 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" > > > > We said we can drop "tap_mp_sync_queues", but thinking twice, > will current implementation cover following usecase: > > - Primary applicaiton started with tap interface, all config, setup, > start done > - Secondary app started without any parameter > > Since primary already started, I think secondary fds will be wrong, > what do you think? > That is true, the fds would be unitialised, we should retain for the > secondary attach case. > > #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) > > Can you please follow the coding convention: > sure, will do it. > 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) > > +{ > > I asked last time but I don't remember the response, > what should be in the 'peer' variable? > > > + 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..a08991bcdf 100644 > > --- a/lib/ethdev/ethdev_driver.h > > +++ b/lib/ethdev/ethdev_driver.h > > @@ -1629,6 +1629,23 @@ rte_eth_hairpin_queue_peer_bind(uint16_t > cur_port, uint16_t cur_queue, > > struct rte_hairpin_peer_info *peer_info, > > uint32_t direction); > > > > +/** > > Please add '@internal' tag into doxygen comment. > > > +* 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); > > As the API name, better to start with 'rte_eth_' prefix to be consistent > with > rest of the APIs. > I suggest 'rte_eth_dev_get_by_name' but feel free to chose better one. > > > + > > /** > > * @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..7e3797189b 100644 > > --- a/lib/ethdev/version.map > > +++ b/lib/ethdev/version.map > > @@ -256,6 +256,7 @@ EXPERIMENTAL { > > rte_flow_flex_item_create; > > rte_flow_flex_item_release; > > rte_flow_pick_transfer_proxy; > > + > > This is unintendent change. > > > }; > > > > INTERNAL { > > @@ -282,4 +283,5 @@ INTERNAL { > > rte_eth_representor_id_get; > > rte_eth_switch_domain_alloc; > > rte_eth_switch_domain_free; > > + rte_get_eth_dev_by_name; > > Please add in a sorted way. > > > }; > > --0000000000005da55705d6537a17 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Mon, Jan 24, 2022 at 6:05 PM Ferru= h Yigit <ferruh.yigit@intel.co= m> wrote:
On 1/24/2022 12:12 PM, Kumara Parameshwaran wrote:
> 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 pr= ocess")
> Cc: stable@dpdk.o= rg
>
> Signed-off-by: Kumara Parameshwaran <kparameshwar@vmware.com>
> ---
>
> v2:
> * Addressed review comments to move the function declaration and versi= on
>=C2=A0 =C2=A0 map
>

Thanks for adding patch version.

>=C2=A0 =C2=A0drivers/net/tap/rte_eth_tap.c | 196 +++++++++++++---------= ------------
>=C2=A0 =C2=A0lib/ethdev/ethdev_driver.h=C2=A0 =C2=A0 |=C2=A0 17 +++
>=C2=A0 =C2=A0lib/ethdev/rte_ethdev.c=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 = 11 ++
>=C2=A0 =C2=A0lib/ethdev/version.map=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 = =C2=A02 +
>=C2=A0 =C2=A04 files changed, 102 insertions(+), 124 deletions(-)
>

Can you please separate etdev (API) changes to another patch, so this will = be a patchset
with two patches,
first patch adds ethdev API
second patch is tap patch, that uses the API in the first patch=C2=A0
=C2=A0 =C2=A0 Sure, I will do it.=C2=A0

> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_t= ap.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 @@
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(TAP_GSO_MBUFS_PER_CORE * TAP_GSO_MBUF_CACHE= _SIZE)
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0/* 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"
>

We said we can drop "tap_mp_sync_queues", but thinking twice,
will current implementation cover following usecase:

- Primary applicaiton started with tap interface, all config, setup,
=C2=A0 =C2=A0start done
- Secondary app started without any parameter

Since primary already started, I think secondary fds will be wrong,
what do you think?
That is true, the fds would be unitialised, we should retain for the second= ary attach case.
>=C2=A0 =C2=A0#define TAP_IOV_DEFAULT_MAX 1024
>=C2=A0 =C2=A0
> @@ -880,11 +880,48 @@ tap_link_set_up(struct rte_eth_dev *dev)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr= , 1, LOCAL_AND_REMOTE);
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> +static int tap_mp_req_on_rxtx(struct rte_eth_dev *dev)

Can you please follow the coding convention:
sure, will do it.
static int
tap_mp_req_on_rxtx(struct rte_eth_dev *dev)
{

> +{
> +=C2=A0 =C2=A0 =C2=A0struct rte_mp_msg msg;
> +=C2=A0 =C2=A0 =C2=A0struct ipc_queues *request_param =3D (struct ipc_= queues *)msg.param;
> +=C2=A0 =C2=A0 =C2=A0int err;
> +=C2=A0 =C2=A0 =C2=A0int fd_iterator =3D 0;
> +=C2=A0 =C2=A0 =C2=A0struct pmd_process_private *process_private =3D d= ev->process_private;
> +=C2=A0 =C2=A0 =C2=A0int i;
> +
> +=C2=A0 =C2=A0 =C2=A0memset(&msg, 0, sizeof(msg));
> +=C2=A0 =C2=A0 =C2=A0strlcpy(msg.name, TAP_MP_REQ_START_RXTX, sizeof(msg.name)); > +=C2=A0 =C2=A0 =C2=A0strlcpy(request_param->port_name, dev->data= ->name, sizeof(request_param->port_name));
> +=C2=A0 =C2=A0 =C2=A0msg.len_param =3D sizeof(*request_param);
> +=C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < dev->data->nb_tx_queue= s; i++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0msg.fds[fd_iterator++= ] =3D process_private->txq_fds[i];
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0msg.num_fds++;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request_param->txq= _count++;
> +=C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < dev->data->nb_rx_queue= s; i++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0msg.fds[fd_iterator++= ] =3D process_private->rxq_fds[i];
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0msg.num_fds++;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request_param->rxq= _count++;
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0err =3D rte_mp_sendmsg(&msg);
> +=C2=A0 =C2=A0 =C2=A0if (err < 0) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Fa= iled to send start req to secondary %d",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0rte_errno);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0return 0;
> +}
> +
>=C2=A0 =C2=A0static int
>=C2=A0 =C2=A0tap_dev_start(struct rte_eth_dev *dev)
>=C2=A0 =C2=A0{
>=C2=A0 =C2=A0 =C2=A0 =C2=A0int err, i;
>=C2=A0 =C2=A0
> +=C2=A0 =C2=A0 =C2=A0if (rte_eal_process_type() =3D=3D RTE_PROC_PRIMAR= Y)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tap_mp_req_on_rxtx(de= v);
> +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0err =3D tap_intr_handle_set(dev, 1);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0if (err)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return err;
> @@ -901,6 +938,34 @@ tap_dev_start(struct rte_eth_dev *dev)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return err;
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> +static int
> +tap_mp_req_start_rxtx(const struct rte_mp_msg *request, __rte_unused = const void *peer)
> +{

I asked last time but I don't remember the response,
what should be in the 'peer' variable?

> +=C2=A0 =C2=A0 =C2=A0struct rte_eth_dev *dev;
> +=C2=A0 =C2=A0 =C2=A0const struct ipc_queues *request_param =3D
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(const struct ipc_que= ues *)request->param;
> +=C2=A0 =C2=A0 =C2=A0int fd_iterator;
> +=C2=A0 =C2=A0 =C2=A0int queue;
> +=C2=A0 =C2=A0 =C2=A0struct pmd_process_private *process_private;
> +
> +=C2=A0 =C2=A0 =C2=A0dev =3D rte_get_eth_dev_by_name(request_param->= ;port_name);
> +=C2=A0 =C2=A0 =C2=A0if (!dev) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Fa= iled to get dev for %s",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0request_param->port_name);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> +=C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0process_private =3D dev->process_private;
> +=C2=A0 =C2=A0 =C2=A0fd_iterator =3D 0;
> +=C2=A0 =C2=A0 =C2=A0TAP_LOG(DEBUG, "tap_attach rx_q:%d tx_q:%d\n= ", request_param->rxq_count,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request_param->txq= _count);
> +=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < request_param->tx= q_count; queue++)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0process_private->t= xq_fds[queue] =3D request->fds[fd_iterator++];
> +=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < request_param->rx= q_count; queue++)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0process_private->r= xq_fds[queue] =3D request->fds[fd_iterator++];
> +
> +=C2=A0 =C2=A0 =C2=A0return 0;
> +}
> +
>=C2=A0 =C2=A0/* This function gets called when the current port gets st= opped.
>=C2=A0 =C2=A0 */
>=C2=A0 =C2=A0static int
> @@ -1084,6 +1149,7 @@ tap_dev_close(struct rte_eth_dev *dev)
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0if (rte_eal_process_type() !=3D RTE_PROC_PRI= MARY) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_free(dev->= ;process_private);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_mp_action_unregis= ter(TAP_MP_REQ_START_RXTX);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> @@ -1140,8 +1206,6 @@ tap_dev_close(struct rte_eth_dev *dev)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0internals->io= ctl_sock =3D -1;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_free(dev->process_private);
> -=C2=A0 =C2=A0 =C2=A0if (tap_devices_count =3D=3D 1)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_mp_action_unregis= ter(TAP_MP_KEY);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0tap_devices_count--;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0/*
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 * Since TUN device has no more opened file = descriptors
> @@ -2292,113 +2356,6 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev)=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return ret;
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> -/* Request queue file descriptors from secondary to primary. */
> -static int
> -tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev)<= br> > -{
> -=C2=A0 =C2=A0 =C2=A0int ret;
> -=C2=A0 =C2=A0 =C2=A0struct timespec timeout =3D {.tv_sec =3D 1, .tv_n= sec =3D 0};
> -=C2=A0 =C2=A0 =C2=A0struct rte_mp_msg request, *reply;
> -=C2=A0 =C2=A0 =C2=A0struct rte_mp_reply replies;
> -=C2=A0 =C2=A0 =C2=A0struct ipc_queues *request_param =3D (struct ipc_= queues *)request.param;
> -=C2=A0 =C2=A0 =C2=A0struct ipc_queues *reply_param;
> -=C2=A0 =C2=A0 =C2=A0struct pmd_process_private *process_private =3D d= ev->process_private;
> -=C2=A0 =C2=A0 =C2=A0int queue, fd_iterator;
> -
> -=C2=A0 =C2=A0 =C2=A0/* Prepare the request */
> -=C2=A0 =C2=A0 =C2=A0memset(&request, 0, sizeof(request));
> -=C2=A0 =C2=A0 =C2=A0strlcpy(request.name, TAP_MP_KEY, sizeof(request.name= ));
> -=C2=A0 =C2=A0 =C2=A0strlcpy(request_param->port_name, port_name, > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(request_param-= >port_name));
> -=C2=A0 =C2=A0 =C2=A0request.len_param =3D sizeof(*request_param);
> -=C2=A0 =C2=A0 =C2=A0/* Send request and receive reply */
> -=C2=A0 =C2=A0 =C2=A0ret =3D rte_mp_request_sync(&request, &re= plies, &timeout);
> -=C2=A0 =C2=A0 =C2=A0if (ret < 0 || replies.nb_received !=3D 1) { > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Fa= iled to request queues from primary: %d",
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0rte_errno);
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> -=C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0reply =3D &replies.msgs[0];
> -=C2=A0 =C2=A0 =C2=A0reply_param =3D (struct ipc_queues *)reply->pa= ram;
> -=C2=A0 =C2=A0 =C2=A0TAP_LOG(DEBUG, "Received IPC reply for %s&qu= ot;, reply_param->port_name);
> -
> -=C2=A0 =C2=A0 =C2=A0/* Attach the queues from received file descripto= rs */
> -=C2=A0 =C2=A0 =C2=A0if (reply_param->rxq_count + reply_param->t= xq_count !=3D reply->num_fds) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Un= expected number of fds received");
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> -=C2=A0 =C2=A0 =C2=A0}
> -
> -=C2=A0 =C2=A0 =C2=A0dev->data->nb_rx_queues =3D reply_param->= ;rxq_count;
> -=C2=A0 =C2=A0 =C2=A0dev->data->nb_tx_queues =3D reply_param->= ;txq_count;
> -=C2=A0 =C2=A0 =C2=A0fd_iterator =3D 0;
> -=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < reply_param->rxq_= count; queue++)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0process_private->r= xq_fds[queue] =3D reply->fds[fd_iterator++];
> -=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < reply_param->txq_= count; queue++)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0process_private->t= xq_fds[queue] =3D reply->fds[fd_iterator++];
> -=C2=A0 =C2=A0 =C2=A0free(reply);
> -=C2=A0 =C2=A0 =C2=A0return 0;
> -}
> -
> -/* Send the queue file descriptors from the primary process to second= ary. */
> -static int
> -tap_mp_sync_queues(const struct rte_mp_msg *request, const void *peer= )
> -{
> -=C2=A0 =C2=A0 =C2=A0struct rte_eth_dev *dev;
> -=C2=A0 =C2=A0 =C2=A0struct pmd_process_private *process_private;
> -=C2=A0 =C2=A0 =C2=A0struct rte_mp_msg reply;
> -=C2=A0 =C2=A0 =C2=A0const struct ipc_queues *request_param =3D
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(const struct ipc_que= ues *)request->param;
> -=C2=A0 =C2=A0 =C2=A0struct ipc_queues *reply_param =3D
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(struct ipc_queues *)= reply.param;
> -=C2=A0 =C2=A0 =C2=A0uint16_t port_id;
> -=C2=A0 =C2=A0 =C2=A0int queue;
> -=C2=A0 =C2=A0 =C2=A0int ret;
> -
> -=C2=A0 =C2=A0 =C2=A0/* Get requested port */
> -=C2=A0 =C2=A0 =C2=A0TAP_LOG(DEBUG, "Received IPC request for %s&= quot;, request_param->port_name);
> -=C2=A0 =C2=A0 =C2=A0ret =3D rte_eth_dev_get_port_by_name(request_para= m->port_name, &port_id);
> -=C2=A0 =C2=A0 =C2=A0if (ret) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Fa= iled to get port id for %s",
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0request_param->port_name);
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> -=C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0dev =3D &rte_eth_devices[port_id];
> -=C2=A0 =C2=A0 =C2=A0process_private =3D dev->process_private;
> -
> -=C2=A0 =C2=A0 =C2=A0/* Fill file descriptors for all queues */
> -=C2=A0 =C2=A0 =C2=A0reply.num_fds =3D 0;
> -=C2=A0 =C2=A0 =C2=A0reply_param->rxq_count =3D 0;
> -=C2=A0 =C2=A0 =C2=A0if (dev->data->nb_rx_queues + dev->data-= >nb_tx_queues >
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0RTE_MP_MAX_FD_NUM){
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Nu= mber of rx/tx queues exceeds max number of fds");
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> -=C2=A0 =C2=A0 =C2=A0}
> -
> -=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < dev->data->nb_= rx_queues; queue++) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reply.fds[reply.num_f= ds++] =3D process_private->rxq_fds[queue];
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reply_param->rxq_c= ount++;
> -=C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0RTE_ASSERT(reply_param->rxq_count =3D=3D dev-&= gt;data->nb_rx_queues);
> -
> -=C2=A0 =C2=A0 =C2=A0reply_param->txq_count =3D 0;
> -=C2=A0 =C2=A0 =C2=A0for (queue =3D 0; queue < dev->data->nb_= tx_queues; queue++) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reply.fds[reply.num_f= ds++] =3D process_private->txq_fds[queue];
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reply_param->txq_c= ount++;
> -=C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0RTE_ASSERT(reply_param->txq_count =3D=3D dev-&= gt;data->nb_tx_queues);
> -
> -=C2=A0 =C2=A0 =C2=A0/* Send reply */
> -=C2=A0 =C2=A0 =C2=A0strlcpy(reply.name, request->name, sizeof(reply.name)= );
> -=C2=A0 =C2=A0 =C2=A0strlcpy(reply_param->port_name, request_param-= >port_name,
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(reply_param-&g= t;port_name));
> -=C2=A0 =C2=A0 =C2=A0reply.len_param =3D sizeof(*reply_param);
> -=C2=A0 =C2=A0 =C2=A0if (rte_mp_reply(&reply, peer) < 0) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, "Fa= iled to reply an IPC request to sync queues");
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> -=C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0return 0;
> -}
> -
>=C2=A0 =C2=A0/* Open a TAP interface device.
>=C2=A0 =C2=A0 */
>=C2=A0 =C2=A0static int
> @@ -2442,9 +2399,11 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)<= br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0return -1;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D tap_mp_attach= _queues(name, eth_dev);
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret !=3D 0)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0return -1;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D rte_mp_action= _register(TAP_MP_REQ_START_RXTX, tap_mp_req_start_rxtx);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0 &&= amp; rte_errno !=3D ENOTSUP)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0TAP_LOG(ERR, "tap: Failed to register IPC callback: %s", > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0strerror(rte_errno));
> +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_eth_dev_prob= ing_finish(eth_dev);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> @@ -2492,15 +2451,6 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)<= br> >=C2=A0 =C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(DEBUG, "Initializing pmd_tap fo= r %s", name);
>=C2=A0 =C2=A0
> -=C2=A0 =C2=A0 =C2=A0/* Register IPC feed callback */
> -=C2=A0 =C2=A0 =C2=A0if (!tap_devices_count) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D rte_mp_action= _register(TAP_MP_KEY, tap_mp_sync_queues);
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0 &&= amp; rte_errno !=3D ENOTSUP) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0TAP_LOG(ERR, "tap: Failed to register IPC callback: %s", > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0strerror(rte_errno));
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0goto leave;
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> -=C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0tap_devices_count++;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0tap_devices_count_increased =3D 1;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D eth_dev_tap_create(dev, tap_name, re= mote_iface, &user_mac,
> @@ -2511,8 +2461,6 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0TAP_LOG(ERR, &qu= ot;Failed to create pmd for %s as %s",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0name, tap_name);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (tap_devices_= count_increased =3D=3D 1) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (tap_devices_count =3D=3D 1)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_mp_action_unregister(TAP_MP_KEY); >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0tap_devices_count--;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h > index d95605a355..a08991bcdf 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -1629,6 +1629,23 @@ rte_eth_hairpin_queue_peer_bind(uint16_t cur_po= rt, uint16_t cur_queue,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_hairpin_peer_info *peer= _info,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0uint32_t direction);
>=C2=A0 =C2=A0
> +/**

Please add '@internal' tag into doxygen comment.

> +* Get rte_eth_dev from device name. The device name should be specifi= ed
> +* 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
> +*=C2=A0 pci address or name of the device
> +* @return
> +*=C2=A0 =C2=A0- rte_eth_dev if successful
> +*=C2=A0 =C2=A0- NULL on failure
> +*/
> +__rte_internal
> +struct rte_eth_dev*
> +rte_get_eth_dev_by_name(const char *name);

As the API name, better to start with 'rte_eth_' prefix to be consi= stent with
rest of the APIs.
I suggest 'rte_eth_dev_get_by_name' but feel free to chose better o= ne.

> +
>=C2=A0 =C2=A0/**
>=C2=A0 =C2=A0 * @internal
>=C2=A0 =C2=A0 * Reset the current queue state and configuration to disc= onnect (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, ui= nt16_t *port_id)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENODEV;
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> +struct rte_eth_dev *
> +rte_get_eth_dev_by_name(const char *name)
> +{
> +=C2=A0 =C2=A0 =C2=A0uint16_t pid;
> +
> +=C2=A0 =C2=A0 =C2=A0if (rte_eth_dev_get_port_by_name(name, &pid))=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL;
> +
> +=C2=A0 =C2=A0 =C2=A0return &rte_eth_devices[pid];
> +}
> +
>=C2=A0 =C2=A0static int
>=C2=A0 =C2=A0eth_err(uint16_t port_id, int ret)
>=C2=A0 =C2=A0{
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index c2fb0669a4..7e3797189b 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -256,6 +256,7 @@ EXPERIMENTAL {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_flow_flex_item_create;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_flow_flex_item_release;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_flow_pick_transfer_proxy;
> +

This is unintendent change.

>=C2=A0 =C2=A0};
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0INTERNAL {
> @@ -282,4 +283,5 @@ INTERNAL {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_eth_representor_id_get;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_eth_switch_domain_alloc;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_eth_switch_domain_free;
> +=C2=A0 =C2=A0 =C2=A0rte_get_eth_dev_by_name;

Please add in a sorted way.

>=C2=A0 =C2=A0};

--0000000000005da55705d6537a17--