net/tap: fix to populate FDs in secondary process
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: 4852aa8f6e
("drivers/net: enable hotplug on secondary process")
Cc: stable@dpdk.org
Signed-off-by: Kumara Parameshwaran <kparameshwar@vmware.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
parent
961fb4029b
commit
c36ce7099c
@ -67,6 +67,7 @@
|
||||
|
||||
/* 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 +881,49 @@ 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 +940,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_eth_dev_get_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
|
||||
@ -1092,6 +1159,9 @@ tap_dev_close(struct rte_eth_dev *dev)
|
||||
|
||||
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
||||
rte_free(dev->process_private);
|
||||
if (tap_devices_count == 1)
|
||||
rte_mp_action_unregister(TAP_MP_REQ_START_RXTX);
|
||||
tap_devices_count--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2453,6 +2523,16 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
|
||||
ret = tap_mp_attach_queues(name, eth_dev);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
if (!tap_devices_count) {
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
tap_devices_count++;
|
||||
rte_eth_dev_probing_finish(eth_dev);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user