/* 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
}
}
-/* Accumaulate L4 raw checksums */
+/* Accumulate L4 raw checksums */
static void
tap_tx_l4_add_rcksum(char *l4_data, unsigned int l4_len, uint16_t *l4_cksum,
uint32_t *l4_raw_cksum)
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;
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
RTE_PMD_TAP_MAX_QUEUES);
return -1;
}
+ if (dev->data->nb_rx_queues != dev->data->nb_tx_queues) {
+ TAP_LOG(ERR,
+ "%s: number of rx queues %d must be equal to number of tx queues %d",
+ dev->device->name,
+ dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues);
+ return -1;
+ }
TAP_LOG(INFO, "%s: %s: TX configured queues number: %u",
dev->device->name, pmd->name, dev->data->nb_tx_queues);
* functions together and not in partial combinations
*/
dev_info->flow_type_rss_offloads = ~TAP_RSS_HF_MASK;
+ dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
return 0;
}
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;
}
struct rte_eth_dev *dev = cb_arg;
struct pmd_internals *pmd = dev->data->dev_private;
- tap_nl_recv(pmd->intr_handle.fd, tap_nl_msg_handler, dev);
+ if (rte_intr_fd_get(pmd->intr_handle) >= 0)
+ tap_nl_recv(rte_intr_fd_get(pmd->intr_handle),
+ tap_nl_msg_handler, dev);
}
static int
/* In any case, disable interrupt if the conf is no longer there. */
if (!dev->data->dev_conf.intr_conf.lsc) {
- if (pmd->intr_handle.fd != -1) {
+ if (rte_intr_fd_get(pmd->intr_handle) != -1)
goto clean;
- }
+
return 0;
}
if (set) {
- pmd->intr_handle.fd = tap_nl_init(RTMGRP_LINK);
- if (unlikely(pmd->intr_handle.fd == -1))
+ rte_intr_fd_set(pmd->intr_handle, tap_nl_init(RTMGRP_LINK));
+ if (unlikely(rte_intr_fd_get(pmd->intr_handle) == -1))
return -EBADF;
return rte_intr_callback_register(
- &pmd->intr_handle, tap_dev_intr_handler, dev);
+ pmd->intr_handle, tap_dev_intr_handler, dev);
}
clean:
do {
- ret = rte_intr_callback_unregister(&pmd->intr_handle,
+ ret = rte_intr_callback_unregister(pmd->intr_handle,
tap_dev_intr_handler, dev);
if (ret >= 0) {
break;
}
} while (true);
- tap_nl_final(pmd->intr_handle.fd);
- pmd->intr_handle.fd = -1;
+ if (rte_intr_fd_get(pmd->intr_handle) >= 0) {
+ tap_nl_final(rte_intr_fd_get(pmd->intr_handle));
+ rte_intr_fd_set(pmd->intr_handle, -1);
+ }
return 0;
}
goto error_exit;
}
+ /* Allocate interrupt instance */
+ pmd->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
+ if (pmd->intr_handle == NULL) {
+ TAP_LOG(ERR, "Failed to allocate intr handle");
+ goto error_exit;
+ }
+
/* Setup some default values */
data = dev->data;
data->dev_private = pmd;
dev->rx_pkt_burst = pmd_rx_burst;
dev->tx_pkt_burst = pmd_tx_burst;
- pmd->intr_handle.type = RTE_INTR_HANDLE_EXT;
- pmd->intr_handle.fd = -1;
- dev->intr_handle = &pmd->intr_handle;
+ rte_intr_type_set(pmd->intr_handle, RTE_INTR_HANDLE_EXT);
+ rte_intr_fd_set(pmd->intr_handle, -1);
+ dev->intr_handle = pmd->intr_handle;
/* Presetup the fds to -1 as being not valid */
for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
/* mac_addrs must not be freed alone because part of dev_private */
dev->data->mac_addrs = NULL;
rte_eth_dev_release_port(dev);
+ rte_intr_instance_free(pmd->intr_handle);
error_exit_nodev:
TAP_LOG(ERR, "%s Unable to initialize %s",
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;
}