diff --git a/0481-net-af_xdp-add-interrupt-support.patch b/0481-net-af_xdp-add-interrupt-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..43813f8bcef220b6afc4487d1a5a3ba54a41da93 --- /dev/null +++ b/0481-net-af_xdp-add-interrupt-support.patch @@ -0,0 +1,224 @@ +From 0829966e018a4db6655618bd0b4cd24479dca5d0 Mon Sep 17 00:00:00 2001 +From: jiangheng +Date: Fri, 27 Sep 2024 15:56:35 +0800 +Subject: [PATCH] net/af_xdp: add interrupt support + +--- + drivers/net/af_xdp/rte_eth_af_xdp.c | 138 +++++++++++++++++++++++++++- + 1 file changed, 133 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c +index e79a308..9ae3ee9 100644 +--- a/drivers/net/af_xdp/rte_eth_af_xdp.c ++++ b/drivers/net/af_xdp/rte_eth_af_xdp.c +@@ -334,7 +334,9 @@ af_xdp_rx_zc(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + (void)recvfrom(xsk_socket__fd(rxq->xsk), NULL, 0, + MSG_DONTWAIT, NULL, NULL); + } else if (xsk_ring_prod__needs_wakeup(fq)) { +- (void)poll(&rxq->fds[0], 1, 1000); ++ if (rxq->fds[0].fd != 0) { ++ (void)poll(&rxq->fds[0], 1, 1000); ++ } + } + + return 0; +@@ -409,8 +411,11 @@ af_xdp_rx_cp(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + nb_pkts = xsk_ring_cons__peek(rx, nb_pkts, &idx_rx); + if (nb_pkts == 0) { + #if defined(XDP_USE_NEED_WAKEUP) +- if (xsk_ring_prod__needs_wakeup(fq)) +- (void)poll(rxq->fds, 1, 1000); ++ if (xsk_ring_prod__needs_wakeup(fq)) { ++ if (rxq->fds[0].fd != 0) { ++ (void)poll(rxq->fds, 1, 1000); ++ } ++ } + #endif + return 0; + } +@@ -765,6 +770,51 @@ find_internal_resource(struct pmd_internals *port_int) + return list; + } + ++static int xdp_queues_bind_intr(struct rte_eth_dev *dev) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < dev->data->nb_rx_queues; ++i) { ++ if (rte_intr_vec_list_index_set(dev->intr_handle, i, i + 1)) { ++ return -rte_errno; ++ } ++ } ++ ++ return 0; ++} ++ ++static int xdp_configure_intr(struct rte_eth_dev *dev) ++{ ++ struct pmd_internals *internals = dev->data->dev_private; ++ int ret; ++ ++ ret = rte_intr_efd_enable(dev->intr_handle, dev->data->nb_rx_queues); ++ if (ret < 0) { ++ AF_XDP_LOG(ERR, "Failed to enable intr efd\n"); ++ return ret; ++ } ++ ++ ret = rte_intr_vec_list_alloc(dev->intr_handle, "intr_vec", internals->max_queue_cnt); ++ if (ret < 0) { ++ AF_XDP_LOG(ERR, "Failed to allocate %u rxq vectors\n", internals->max_queue_cnt); ++ return ret; ++ } ++ ++ ret = rte_intr_enable(dev->intr_handle); ++ if (ret < 0) { ++ AF_XDP_LOG(ERR, "Failed to enable interrupt\n"); ++ return ret; ++ } ++ ++ ret = xdp_queues_bind_intr(dev); ++ if (ret < 0) { ++ AF_XDP_LOG(ERR, "Failed to bind queue/interrupt\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int + eth_dev_configure(struct rte_eth_dev *dev) + { +@@ -774,6 +824,13 @@ eth_dev_configure(struct rte_eth_dev *dev) + if (dev->data->nb_rx_queues != dev->data->nb_tx_queues) + return -EINVAL; + ++ if (dev->data->dev_conf.intr_conf.rxq) { ++ if (xdp_configure_intr(dev) < 0) { ++ AF_XDP_LOG(ERR, "Failed to configure interrupt\n"); ++ return -1; ++ } ++ } ++ + if (internal->shared_umem) { + struct internal_list *list = NULL; + const char *name = dev->device->name; +@@ -1823,8 +1880,17 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, + if (!rxq->busy_budget) + AF_XDP_LOG(DEBUG, "Preferred busy polling not enabled\n"); + +- rxq->fds[0].fd = xsk_socket__fd(rxq->xsk); +- rxq->fds[0].events = POLLIN; ++ if (dev->data->dev_conf.intr_conf.rxq) { ++ if (rte_intr_efds_index_set(dev->intr_handle, rx_queue_id, xsk_socket__fd(rxq->xsk))) { ++ AF_XDP_LOG(ERR, "Failed to set intr efds, queue id: %d\n", rx_queue_id); ++ ret = -rte_errno; ++ goto err; ++ } ++ rxq->fds[0].fd = 0; ++ } else { ++ rxq->fds[0].fd = xsk_socket__fd(rxq->xsk); ++ rxq->fds[0].events = POLLIN; ++ } + + process_private->rxq_xsk_fds[rx_queue_id] = rxq->fds[0].fd; + +@@ -1915,6 +1981,18 @@ eth_dev_promiscuous_disable(struct rte_eth_dev *dev) + return eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC); + } + ++static int ++eth_dev_rx_queue_intr_enable(__rte_unused struct rte_eth_dev *dev, __rte_unused uint16_t queue_id) ++{ ++ return 0; ++} ++ ++static int ++eth_dev_rx_queue_intr_disable(__rte_unused struct rte_eth_dev *dev, __rte_unused uint16_t queue_id) ++{ ++ return 0; ++} ++ + static const struct eth_dev_ops ops = { + .dev_start = eth_dev_start, + .dev_stop = eth_dev_stop, +@@ -1930,6 +2008,8 @@ static const struct eth_dev_ops ops = { + .stats_get = eth_stats_get, + .stats_reset = eth_stats_reset, + .get_monitor_addr = eth_get_monitor_addr, ++ .rx_queue_intr_enable = eth_dev_rx_queue_intr_enable, ++ .rx_queue_intr_disable = eth_dev_rx_queue_intr_disable, + }; + + /* AF_XDP Device Plugin option works in unprivileged +@@ -1951,6 +2031,8 @@ static const struct eth_dev_ops ops_afxdp_dp = { + .stats_get = eth_stats_get, + .stats_reset = eth_stats_reset, + .get_monitor_addr = eth_get_monitor_addr, ++ .rx_queue_intr_enable = eth_dev_rx_queue_intr_enable, ++ .rx_queue_intr_disable = eth_dev_rx_queue_intr_disable, + }; + + /** parse busy_budget argument */ +@@ -2166,6 +2248,47 @@ get_iface_info(const char *if_name, + return -1; + } + ++static int xdp_fill_intr_handle(struct rte_eth_dev *eth_dev) ++{ ++ struct pmd_internals *internals = eth_dev->data->dev_private; ++ if (eth_dev->intr_handle == NULL) { ++ eth_dev->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); ++ if (eth_dev->intr_handle == NULL) { ++ AF_XDP_LOG(ERR, "Failed to allocate intr_handle\n"); ++ return -1; ++ } ++ } ++ ++ for (int i = 0; i < internals->queue_cnt; ++i) { ++ if (rte_intr_efds_index_set(eth_dev->intr_handle, i, -1)) { ++ return -rte_errno; ++ } ++ } ++ ++ if (rte_intr_nb_efd_set(eth_dev->intr_handle, internals->queue_cnt)) { ++ return -rte_errno; ++ } ++ ++ if (rte_intr_max_intr_set(eth_dev->intr_handle, internals->queue_cnt + 1)) { ++ return -rte_errno; ++ } ++ ++ if (rte_intr_type_set(eth_dev->intr_handle, RTE_INTR_HANDLE_VDEV)) { ++ return -rte_errno; ++ } ++ ++ /* For xdp vdev, no need to read counter for clean */ ++ if (rte_intr_efd_counter_size_set(eth_dev->intr_handle, 0)) { ++ return -rte_errno; ++ } ++ ++ if (rte_intr_fd_set(eth_dev->intr_handle, -1)) { ++ return -rte_errno; ++ } ++ ++ return 0; ++} ++ + static struct rte_eth_dev * + init_internals(struct rte_vdev_device *dev, const char *if_name, + int start_queue_idx, int queue_cnt, int shared_umem, +@@ -2522,6 +2645,11 @@ rte_pmd_af_xdp_probe(struct rte_vdev_device *dev) + } + afxdp_dev_count++; + ++ if (xdp_fill_intr_handle(eth_dev) < 0) { ++ AF_XDP_LOG(ERR, "Failed to init interrupt handler\n"); ++ return -1; ++ } ++ + rte_eth_dev_probing_finish(eth_dev); + + return 0; +-- +2.33.0 + diff --git a/dpdk.spec b/dpdk.spec index 905607a91506f1977442af84e2ff8d7d66e5d5e9..17e2616be7f67ac01252f3c068bf784717235f7c 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 21.11 -Release: 72 +Release: 73 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 21.11 @@ -514,6 +514,7 @@ patch6478: 0478-adapt-libbpf-0.8.0.patch patch9479: 0479-config-arm-adapt-RTE_MAX_LCORE-to-640.patch patch9480: 0480-af_xdp-support-recv-multi-buffer.patch +Patch9481: 0481-net-af_xdp-add-interrupt-support.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -672,6 +673,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/%{kern_devel_ver}/extra/dpdk/igb_uio.ko /usr/sbin/depmod %changelog +* Fri Sep 27 2024 jiangheng - 21.11-73 + net/af_xdp: add interrupt support + * Fri Sep 27 2024 yangchen - 21.11-72 af_xdp: support recv multi-buffer