net/af_xdp: add interrupt support

(cherry picked from commit 0a212e28f8403f10cf3010848d81e3b259f389d7)
This commit is contained in:
jiangheng 2024-09-27 16:00:15 +08:00 committed by openeuler-sync-bot
parent 585149920c
commit e1bca2e2d9
2 changed files with 229 additions and 1 deletions

View File

@ -0,0 +1,224 @@
From 0829966e018a4db6655618bd0b4cd24479dca5d0 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
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

View File

@ -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 <jiangheng14@huawei.com> - 21.11-73
net/af_xdp: add interrupt support
* Fri Sep 27 2024 yangchen <yangchen145@huawei.com> - 21.11-72
af_xdp: support recv multi-buffer