* [PATCH v2 net-next 00/11] ENA driver XDP changes
@ 2024-01-01 19:08 darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 01/11] net: ena: Move XDP code to its new files darinzon
` (12 more replies)
0 siblings, 13 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
This patchset contains multiple XDP-related changes
in the ENA driver, including moving the XDP code to
dedicated files.
Changes in v2:
- Moved changes to right commits in order to avoid compilation errors
David Arinzon (11):
net: ena: Move XDP code to its new files
net: ena: Pass ena_adapter instead of net_device to ena_xmit_common()
net: ena: Put orthogonal fields in ena_tx_buffer in a union
net: ena: Introduce total_tx_size field in ena_tx_buffer struct
net: ena: Use tx_ring instead of xdp_ring for XDP channel TX
net: ena: Don't check if XDP program is loaded in ena_xdp_execute()
net: ena: Refactor napi functions
net: ena: Add more debug prints to XDP related function
net: ena: Always register RX queue info
net: ena: Make queue stats code cleaner by removing the if block
net: ena: Take xdp packets stats into account in ena_get_stats64()
.../device_drivers/ethernet/amazon/ena.rst | 1 +
drivers/net/ethernet/amazon/ena/Makefile | 2 +-
drivers/net/ethernet/amazon/ena/ena_ethtool.c | 18 +-
drivers/net/ethernet/amazon/ena/ena_netdev.c | 689 ++----------------
drivers/net/ethernet/amazon/ena/ena_netdev.h | 99 ++-
drivers/net/ethernet/amazon/ena/ena_xdp.c | 468 ++++++++++++
drivers/net/ethernet/amazon/ena/ena_xdp.h | 151 ++++
7 files changed, 736 insertions(+), 692 deletions(-)
create mode 100644 drivers/net/ethernet/amazon/ena/ena_xdp.c
create mode 100644 drivers/net/ethernet/amazon/ena/ena_xdp.h
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 01/11] net: ena: Move XDP code to its new files
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 02/11] net: ena: Pass ena_adapter instead of net_device to ena_xmit_common() darinzon
` (11 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
XDP system has a very large footprint in the driver's overall code.
makes the whole driver's code much harder to read.
Moving XDP code to dedicated files.
This patch doesn't make any changes to the code itself and only
cut-pastes the code into ena_xdp.c and ena_xdp.h files so the change
is purely cosmetic.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
.../device_drivers/ethernet/amazon/ena.rst | 1 +
drivers/net/ethernet/amazon/ena/Makefile | 2 +-
drivers/net/ethernet/amazon/ena/ena_ethtool.c | 1 +
drivers/net/ethernet/amazon/ena/ena_netdev.c | 634 +-----------------
drivers/net/ethernet/amazon/ena/ena_netdev.h | 82 +--
drivers/net/ethernet/amazon/ena/ena_xdp.c | 465 +++++++++++++
drivers/net/ethernet/amazon/ena/ena_xdp.h | 152 +++++
7 files changed, 680 insertions(+), 657 deletions(-)
create mode 100644 drivers/net/ethernet/amazon/ena/ena_xdp.c
create mode 100644 drivers/net/ethernet/amazon/ena/ena_xdp.h
diff --git a/Documentation/networking/device_drivers/ethernet/amazon/ena.rst b/Documentation/networking/device_drivers/ethernet/amazon/ena.rst
index 5eaa3ab..b842bcb 100644
--- a/Documentation/networking/device_drivers/ethernet/amazon/ena.rst
+++ b/Documentation/networking/device_drivers/ethernet/amazon/ena.rst
@@ -54,6 +54,7 @@ ena_common_defs.h Common definitions for ena_com layer.
ena_regs_defs.h Definition of ENA PCI memory-mapped (MMIO) registers.
ena_netdev.[ch] Main Linux kernel driver.
ena_ethtool.c ethtool callbacks.
+ena_xdp.[ch] XDP files
ena_pci_id_tbl.h Supported device IDs.
================= ======================================================
diff --git a/drivers/net/ethernet/amazon/ena/Makefile b/drivers/net/ethernet/amazon/ena/Makefile
index f1f752a..6ab6153 100644
--- a/drivers/net/ethernet/amazon/ena/Makefile
+++ b/drivers/net/ethernet/amazon/ena/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_ENA_ETHERNET) += ena.o
-ena-y := ena_netdev.o ena_com.o ena_eth_com.o ena_ethtool.o
+ena-y := ena_netdev.o ena_com.o ena_eth_com.o ena_ethtool.o ena_xdp.o
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 2d8c5a2..724af7d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include "ena_netdev.h"
+#include "ena_xdp.h"
struct ena_stats {
char name[ETH_GSTRING_LEN];
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index afd1b7c..0a0d97c 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -19,8 +19,8 @@
#include <net/ip.h>
#include "ena_netdev.h"
-#include <linux/bpf_trace.h>
#include "ena_pci_id_tbl.h"
+#include "ena_xdp.h"
MODULE_AUTHOR("Amazon.com, Inc. or its affiliates");
MODULE_DESCRIPTION(DEVICE_NAME);
@@ -45,53 +45,6 @@ static void check_for_admin_com_state(struct ena_adapter *adapter);
static void ena_destroy_device(struct ena_adapter *adapter, bool graceful);
static int ena_restore_device(struct ena_adapter *adapter);
-static void ena_init_io_rings(struct ena_adapter *adapter,
- int first_index, int count);
-static void ena_init_napi_in_range(struct ena_adapter *adapter, int first_index,
- int count);
-static void ena_del_napi_in_range(struct ena_adapter *adapter, int first_index,
- int count);
-static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid);
-static int ena_setup_tx_resources_in_range(struct ena_adapter *adapter,
- int first_index,
- int count);
-static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid);
-static void ena_free_tx_resources(struct ena_adapter *adapter, int qid);
-static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget);
-static void ena_destroy_all_tx_queues(struct ena_adapter *adapter);
-static void ena_free_all_io_tx_resources(struct ena_adapter *adapter);
-static void ena_napi_disable_in_range(struct ena_adapter *adapter,
- int first_index, int count);
-static void ena_napi_enable_in_range(struct ena_adapter *adapter,
- int first_index, int count);
-static int ena_up(struct ena_adapter *adapter);
-static void ena_down(struct ena_adapter *adapter);
-static void ena_unmask_interrupt(struct ena_ring *tx_ring,
- struct ena_ring *rx_ring);
-static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
- struct ena_ring *rx_ring);
-static void ena_unmap_tx_buff(struct ena_ring *tx_ring,
- struct ena_tx_buffer *tx_info);
-static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter,
- int first_index, int count);
-static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter,
- int first_index, int count);
-
-/* Increase a stat by cnt while holding syncp seqlock on 32bit machines */
-static void ena_increase_stat(u64 *statp, u64 cnt,
- struct u64_stats_sync *syncp)
-{
- u64_stats_update_begin(syncp);
- (*statp) += cnt;
- u64_stats_update_end(syncp);
-}
-
-static void ena_ring_tx_doorbell(struct ena_ring *tx_ring)
-{
- ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
- ena_increase_stat(&tx_ring->tx_stats.doorbells, 1, &tx_ring->syncp);
-}
-
static void ena_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
struct ena_adapter *adapter = netdev_priv(dev);
@@ -135,12 +88,12 @@ static int ena_change_mtu(struct net_device *dev, int new_mtu)
return ret;
}
-static int ena_xmit_common(struct net_device *dev,
- struct ena_ring *ring,
- struct ena_tx_buffer *tx_info,
- struct ena_com_tx_ctx *ena_tx_ctx,
- u16 next_to_use,
- u32 bytes)
+int ena_xmit_common(struct net_device *dev,
+ struct ena_ring *ring,
+ struct ena_tx_buffer *tx_info,
+ struct ena_com_tx_ctx *ena_tx_ctx,
+ u16 next_to_use,
+ u32 bytes)
{
struct ena_adapter *adapter = netdev_priv(dev);
int rc, nb_hw_desc;
@@ -186,467 +139,6 @@ static int ena_xmit_common(struct net_device *dev,
return 0;
}
-/* This is the XDP napi callback. XDP queues use a separate napi callback
- * than Rx/Tx queues.
- */
-static int ena_xdp_io_poll(struct napi_struct *napi, int budget)
-{
- struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
- u32 xdp_work_done, xdp_budget;
- struct ena_ring *xdp_ring;
- int napi_comp_call = 0;
- int ret;
-
- xdp_ring = ena_napi->xdp_ring;
-
- xdp_budget = budget;
-
- if (!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags) ||
- test_bit(ENA_FLAG_TRIGGER_RESET, &xdp_ring->adapter->flags)) {
- napi_complete_done(napi, 0);
- return 0;
- }
-
- xdp_work_done = ena_clean_xdp_irq(xdp_ring, xdp_budget);
-
- /* If the device is about to reset or down, avoid unmask
- * the interrupt and return 0 so NAPI won't reschedule
- */
- if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags))) {
- napi_complete_done(napi, 0);
- ret = 0;
- } else if (xdp_budget > xdp_work_done) {
- napi_comp_call = 1;
- if (napi_complete_done(napi, xdp_work_done))
- ena_unmask_interrupt(xdp_ring, NULL);
- ena_update_ring_numa_node(xdp_ring, NULL);
- ret = xdp_work_done;
- } else {
- ret = xdp_budget;
- }
-
- u64_stats_update_begin(&xdp_ring->syncp);
- xdp_ring->tx_stats.napi_comp += napi_comp_call;
- xdp_ring->tx_stats.tx_poll++;
- u64_stats_update_end(&xdp_ring->syncp);
- xdp_ring->tx_stats.last_napi_jiffies = jiffies;
-
- return ret;
-}
-
-static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
- struct ena_tx_buffer *tx_info,
- struct xdp_frame *xdpf,
- struct ena_com_tx_ctx *ena_tx_ctx)
-{
- struct ena_adapter *adapter = xdp_ring->adapter;
- struct ena_com_buf *ena_buf;
- int push_len = 0;
- dma_addr_t dma;
- void *data;
- u32 size;
-
- tx_info->xdpf = xdpf;
- data = tx_info->xdpf->data;
- size = tx_info->xdpf->len;
-
- if (xdp_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
- /* Designate part of the packet for LLQ */
- push_len = min_t(u32, size, xdp_ring->tx_max_header_size);
-
- ena_tx_ctx->push_header = data;
-
- size -= push_len;
- data += push_len;
- }
-
- ena_tx_ctx->header_len = push_len;
-
- if (size > 0) {
- dma = dma_map_single(xdp_ring->dev,
- data,
- size,
- DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(xdp_ring->dev, dma)))
- goto error_report_dma_error;
-
- tx_info->map_linear_data = 0;
-
- ena_buf = tx_info->bufs;
- ena_buf->paddr = dma;
- ena_buf->len = size;
-
- ena_tx_ctx->ena_bufs = ena_buf;
- ena_tx_ctx->num_bufs = tx_info->num_of_bufs = 1;
- }
-
- return 0;
-
-error_report_dma_error:
- ena_increase_stat(&xdp_ring->tx_stats.dma_mapping_err, 1,
- &xdp_ring->syncp);
- netif_warn(adapter, tx_queued, adapter->netdev, "Failed to map xdp buff\n");
-
- return -EINVAL;
-}
-
-static int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
- struct net_device *dev,
- struct xdp_frame *xdpf,
- int flags)
-{
- struct ena_com_tx_ctx ena_tx_ctx = {};
- struct ena_tx_buffer *tx_info;
- u16 next_to_use, req_id;
- int rc;
-
- next_to_use = xdp_ring->next_to_use;
- req_id = xdp_ring->free_ids[next_to_use];
- tx_info = &xdp_ring->tx_buffer_info[req_id];
- tx_info->num_of_bufs = 0;
-
- rc = ena_xdp_tx_map_frame(xdp_ring, tx_info, xdpf, &ena_tx_ctx);
- if (unlikely(rc))
- return rc;
-
- ena_tx_ctx.req_id = req_id;
-
- rc = ena_xmit_common(dev,
- xdp_ring,
- tx_info,
- &ena_tx_ctx,
- next_to_use,
- xdpf->len);
- if (rc)
- goto error_unmap_dma;
-
- /* trigger the dma engine. ena_ring_tx_doorbell()
- * calls a memory barrier inside it.
- */
- if (flags & XDP_XMIT_FLUSH)
- ena_ring_tx_doorbell(xdp_ring);
-
- return rc;
-
-error_unmap_dma:
- ena_unmap_tx_buff(xdp_ring, tx_info);
- tx_info->xdpf = NULL;
- return rc;
-}
-
-static int ena_xdp_xmit(struct net_device *dev, int n,
- struct xdp_frame **frames, u32 flags)
-{
- struct ena_adapter *adapter = netdev_priv(dev);
- struct ena_ring *xdp_ring;
- int qid, i, nxmit = 0;
-
- if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
- return -EINVAL;
-
- if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
- return -ENETDOWN;
-
- /* We assume that all rings have the same XDP program */
- if (!READ_ONCE(adapter->rx_ring->xdp_bpf_prog))
- return -ENXIO;
-
- qid = smp_processor_id() % adapter->xdp_num_queues;
- qid += adapter->xdp_first_ring;
- xdp_ring = &adapter->tx_ring[qid];
-
- /* Other CPU ids might try to send thorugh this queue */
- spin_lock(&xdp_ring->xdp_tx_lock);
-
- for (i = 0; i < n; i++) {
- if (ena_xdp_xmit_frame(xdp_ring, dev, frames[i], 0))
- break;
- nxmit++;
- }
-
- /* Ring doorbell to make device aware of the packets */
- if (flags & XDP_XMIT_FLUSH)
- ena_ring_tx_doorbell(xdp_ring);
-
- spin_unlock(&xdp_ring->xdp_tx_lock);
-
- /* Return number of packets sent */
- return nxmit;
-}
-
-static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
-{
- u32 verdict = ENA_XDP_PASS;
- struct bpf_prog *xdp_prog;
- struct ena_ring *xdp_ring;
- struct xdp_frame *xdpf;
- u64 *xdp_stat;
-
- xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog);
-
- if (!xdp_prog)
- goto out;
-
- verdict = bpf_prog_run_xdp(xdp_prog, xdp);
-
- switch (verdict) {
- case XDP_TX:
- xdpf = xdp_convert_buff_to_frame(xdp);
- if (unlikely(!xdpf)) {
- trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
- xdp_stat = &rx_ring->rx_stats.xdp_aborted;
- verdict = ENA_XDP_DROP;
- break;
- }
-
- /* Find xmit queue */
- xdp_ring = rx_ring->xdp_ring;
-
- /* The XDP queues are shared between XDP_TX and XDP_REDIRECT */
- spin_lock(&xdp_ring->xdp_tx_lock);
-
- if (ena_xdp_xmit_frame(xdp_ring, rx_ring->netdev, xdpf,
- XDP_XMIT_FLUSH))
- xdp_return_frame(xdpf);
-
- spin_unlock(&xdp_ring->xdp_tx_lock);
- xdp_stat = &rx_ring->rx_stats.xdp_tx;
- verdict = ENA_XDP_TX;
- break;
- case XDP_REDIRECT:
- if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
- xdp_stat = &rx_ring->rx_stats.xdp_redirect;
- verdict = ENA_XDP_REDIRECT;
- break;
- }
- trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
- xdp_stat = &rx_ring->rx_stats.xdp_aborted;
- verdict = ENA_XDP_DROP;
- break;
- case XDP_ABORTED:
- trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
- xdp_stat = &rx_ring->rx_stats.xdp_aborted;
- verdict = ENA_XDP_DROP;
- break;
- case XDP_DROP:
- xdp_stat = &rx_ring->rx_stats.xdp_drop;
- verdict = ENA_XDP_DROP;
- break;
- case XDP_PASS:
- xdp_stat = &rx_ring->rx_stats.xdp_pass;
- verdict = ENA_XDP_PASS;
- break;
- default:
- bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict);
- xdp_stat = &rx_ring->rx_stats.xdp_invalid;
- verdict = ENA_XDP_DROP;
- }
-
- ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
-out:
- return verdict;
-}
-
-static void ena_init_all_xdp_queues(struct ena_adapter *adapter)
-{
- adapter->xdp_first_ring = adapter->num_io_queues;
- adapter->xdp_num_queues = adapter->num_io_queues;
-
- ena_init_io_rings(adapter,
- adapter->xdp_first_ring,
- adapter->xdp_num_queues);
-}
-
-static int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter)
-{
- u32 xdp_first_ring = adapter->xdp_first_ring;
- u32 xdp_num_queues = adapter->xdp_num_queues;
- int rc = 0;
-
- rc = ena_setup_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues);
- if (rc)
- goto setup_err;
-
- rc = ena_create_io_tx_queues_in_range(adapter, xdp_first_ring, xdp_num_queues);
- if (rc)
- goto create_err;
-
- return 0;
-
-create_err:
- ena_free_all_io_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues);
-setup_err:
- return rc;
-}
-
-/* Provides a way for both kernel and bpf-prog to know
- * more about the RX-queue a given XDP frame arrived on.
- */
-static int ena_xdp_register_rxq_info(struct ena_ring *rx_ring)
-{
- int rc;
-
- rc = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, rx_ring->qid, 0);
-
- if (rc) {
- netif_err(rx_ring->adapter, ifup, rx_ring->netdev,
- "Failed to register xdp rx queue info. RX queue num %d rc: %d\n",
- rx_ring->qid, rc);
- goto err;
- }
-
- rc = xdp_rxq_info_reg_mem_model(&rx_ring->xdp_rxq, MEM_TYPE_PAGE_SHARED,
- NULL);
-
- if (rc) {
- netif_err(rx_ring->adapter, ifup, rx_ring->netdev,
- "Failed to register xdp rx queue info memory model. RX queue num %d rc: %d\n",
- rx_ring->qid, rc);
- xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
- }
-
-err:
- return rc;
-}
-
-static void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring)
-{
- xdp_rxq_info_unreg_mem_model(&rx_ring->xdp_rxq);
- xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
-}
-
-static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
- struct bpf_prog *prog,
- int first, int count)
-{
- struct bpf_prog *old_bpf_prog;
- struct ena_ring *rx_ring;
- int i = 0;
-
- for (i = first; i < count; i++) {
- rx_ring = &adapter->rx_ring[i];
- old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
-
- if (!old_bpf_prog && prog) {
- ena_xdp_register_rxq_info(rx_ring);
- rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
- } else if (old_bpf_prog && !prog) {
- ena_xdp_unregister_rxq_info(rx_ring);
- rx_ring->rx_headroom = NET_SKB_PAD;
- }
- }
-}
-
-static void ena_xdp_exchange_program(struct ena_adapter *adapter,
- struct bpf_prog *prog)
-{
- struct bpf_prog *old_bpf_prog = xchg(&adapter->xdp_bpf_prog, prog);
-
- ena_xdp_exchange_program_rx_in_range(adapter,
- prog,
- 0,
- adapter->num_io_queues);
-
- if (old_bpf_prog)
- bpf_prog_put(old_bpf_prog);
-}
-
-static int ena_destroy_and_free_all_xdp_queues(struct ena_adapter *adapter)
-{
- bool was_up;
- int rc;
-
- was_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
-
- if (was_up)
- ena_down(adapter);
-
- adapter->xdp_first_ring = 0;
- adapter->xdp_num_queues = 0;
- ena_xdp_exchange_program(adapter, NULL);
- if (was_up) {
- rc = ena_up(adapter);
- if (rc)
- return rc;
- }
- return 0;
-}
-
-static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
-{
- struct ena_adapter *adapter = netdev_priv(netdev);
- struct bpf_prog *prog = bpf->prog;
- struct bpf_prog *old_bpf_prog;
- int rc, prev_mtu;
- bool is_up;
-
- is_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
- rc = ena_xdp_allowed(adapter);
- if (rc == ENA_XDP_ALLOWED) {
- old_bpf_prog = adapter->xdp_bpf_prog;
- if (prog) {
- if (!is_up) {
- ena_init_all_xdp_queues(adapter);
- } else if (!old_bpf_prog) {
- ena_down(adapter);
- ena_init_all_xdp_queues(adapter);
- }
- ena_xdp_exchange_program(adapter, prog);
-
- if (is_up && !old_bpf_prog) {
- rc = ena_up(adapter);
- if (rc)
- return rc;
- }
- xdp_features_set_redirect_target(netdev, false);
- } else if (old_bpf_prog) {
- xdp_features_clear_redirect_target(netdev);
- rc = ena_destroy_and_free_all_xdp_queues(adapter);
- if (rc)
- return rc;
- }
-
- prev_mtu = netdev->max_mtu;
- netdev->max_mtu = prog ? ENA_XDP_MAX_MTU : adapter->max_mtu;
-
- if (!old_bpf_prog)
- netif_info(adapter, drv, adapter->netdev,
- "XDP program is set, changing the max_mtu from %d to %d",
- prev_mtu, netdev->max_mtu);
-
- } else if (rc == ENA_XDP_CURRENT_MTU_TOO_LARGE) {
- netif_err(adapter, drv, adapter->netdev,
- "Failed to set xdp program, the current MTU (%d) is larger than the maximum allowed MTU (%lu) while xdp is on",
- netdev->mtu, ENA_XDP_MAX_MTU);
- NL_SET_ERR_MSG_MOD(bpf->extack,
- "Failed to set xdp program, the current MTU is larger than the maximum allowed MTU. Check the dmesg for more info");
- return -EINVAL;
- } else if (rc == ENA_XDP_NO_ENOUGH_QUEUES) {
- netif_err(adapter, drv, adapter->netdev,
- "Failed to set xdp program, the Rx/Tx channel count should be at most half of the maximum allowed channel count. The current queue count (%d), the maximal queue count (%d)\n",
- adapter->num_io_queues, adapter->max_num_io_queues);
- NL_SET_ERR_MSG_MOD(bpf->extack,
- "Failed to set xdp program, there is no enough space for allocating XDP queues, Check the dmesg for more info");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* This is the main xdp callback, it's used by the kernel to set/unset the xdp
- * program as well as to query the current xdp program id.
- */
-static int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
-{
- switch (bpf->command) {
- case XDP_SETUP_PROG:
- return ena_xdp_set(netdev, bpf);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
static int ena_init_rx_cpu_rmap(struct ena_adapter *adapter)
{
#ifdef CONFIG_RFS_ACCEL
@@ -688,8 +180,8 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
u64_stats_init(&ring->syncp);
}
-static void ena_init_io_rings(struct ena_adapter *adapter,
- int first_index, int count)
+void ena_init_io_rings(struct ena_adapter *adapter,
+ int first_index, int count)
{
struct ena_com_dev *ena_dev;
struct ena_ring *txr, *rxr;
@@ -820,9 +312,8 @@ static void ena_free_tx_resources(struct ena_adapter *adapter, int qid)
tx_ring->push_buf_intermediate_buf = NULL;
}
-static int ena_setup_tx_resources_in_range(struct ena_adapter *adapter,
- int first_index,
- int count)
+int ena_setup_tx_resources_in_range(struct ena_adapter *adapter,
+ int first_index, int count)
{
int i, rc = 0;
@@ -845,8 +336,8 @@ err_setup_tx:
return rc;
}
-static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter,
- int first_index, int count)
+void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter,
+ int first_index, int count)
{
int i;
@@ -859,7 +350,7 @@ static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter,
*
* Free all transmit software resources
*/
-static void ena_free_all_io_tx_resources(struct ena_adapter *adapter)
+void ena_free_all_io_tx_resources(struct ena_adapter *adapter)
{
ena_free_all_io_tx_resources_in_range(adapter,
0,
@@ -1169,8 +660,8 @@ static void ena_free_all_rx_bufs(struct ena_adapter *adapter)
ena_free_rx_bufs(adapter, i);
}
-static void ena_unmap_tx_buff(struct ena_ring *tx_ring,
- struct ena_tx_buffer *tx_info)
+void ena_unmap_tx_buff(struct ena_ring *tx_ring,
+ struct ena_tx_buffer *tx_info)
{
struct ena_com_buf *ena_buf;
u32 cnt;
@@ -1272,8 +763,8 @@ static void ena_destroy_all_io_queues(struct ena_adapter *adapter)
ena_destroy_all_rx_queues(adapter);
}
-static int handle_invalid_req_id(struct ena_ring *ring, u16 req_id,
- struct ena_tx_buffer *tx_info, bool is_xdp)
+int handle_invalid_req_id(struct ena_ring *ring, u16 req_id,
+ struct ena_tx_buffer *tx_info, bool is_xdp)
{
if (tx_info)
netif_err(ring->adapter,
@@ -1305,17 +796,6 @@ static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
return handle_invalid_req_id(tx_ring, req_id, tx_info, false);
}
-static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id)
-{
- struct ena_tx_buffer *tx_info;
-
- tx_info = &xdp_ring->tx_buffer_info[req_id];
- if (likely(tx_info->xdpf))
- return 0;
-
- return handle_invalid_req_id(xdp_ring, req_id, tx_info, true);
-}
-
static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
{
struct netdev_queue *txq;
@@ -1688,6 +1168,7 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp, u
return ret;
}
+
/* ena_clean_rx_irq - Cleanup RX irq
* @rx_ring: RX ring to clean
* @napi: napi handler
@@ -1880,8 +1361,8 @@ static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
rx_ring->per_napi_packets = 0;
}
-static void ena_unmask_interrupt(struct ena_ring *tx_ring,
- struct ena_ring *rx_ring)
+void ena_unmask_interrupt(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
{
u32 rx_interval = tx_ring->smoothed_interval;
struct ena_eth_io_intr_reg intr_reg;
@@ -1913,8 +1394,8 @@ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
ena_com_unmask_intr(tx_ring->ena_com_io_cq, &intr_reg);
}
-static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
- struct ena_ring *rx_ring)
+void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
{
int cpu = get_cpu();
int numa_node;
@@ -1949,67 +1430,6 @@ out:
put_cpu();
}
-static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget)
-{
- u32 total_done = 0;
- u16 next_to_clean;
- int tx_pkts = 0;
- u16 req_id;
- int rc;
-
- if (unlikely(!xdp_ring))
- return 0;
- next_to_clean = xdp_ring->next_to_clean;
-
- while (tx_pkts < budget) {
- struct ena_tx_buffer *tx_info;
- struct xdp_frame *xdpf;
-
- rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq,
- &req_id);
- if (rc) {
- if (unlikely(rc == -EINVAL))
- handle_invalid_req_id(xdp_ring, req_id, NULL,
- true);
- break;
- }
-
- /* validate that the request id points to a valid xdp_frame */
- rc = validate_xdp_req_id(xdp_ring, req_id);
- if (rc)
- break;
-
- tx_info = &xdp_ring->tx_buffer_info[req_id];
- xdpf = tx_info->xdpf;
-
- tx_info->xdpf = NULL;
- tx_info->last_jiffies = 0;
- ena_unmap_tx_buff(xdp_ring, tx_info);
-
- netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
- "tx_poll: q %d skb %p completed\n", xdp_ring->qid,
- xdpf);
-
- tx_pkts++;
- total_done += tx_info->tx_descs;
-
- xdp_return_frame(xdpf);
- xdp_ring->free_ids[next_to_clean] = req_id;
- next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
- xdp_ring->ring_size);
- }
-
- xdp_ring->next_to_clean = next_to_clean;
- ena_com_comp_ack(xdp_ring->ena_com_io_sq, total_done);
- ena_com_update_dev_comp_head(xdp_ring->ena_com_io_cq);
-
- netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
- "tx_poll: q %d done. total pkts: %d\n",
- xdp_ring->qid, tx_pkts);
-
- return tx_pkts;
-}
-
static int ena_io_poll(struct napi_struct *napi, int budget)
{
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
@@ -2475,8 +1895,8 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
return rc;
}
-static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter,
- int first_index, int count)
+int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter,
+ int first_index, int count)
{
struct ena_com_dev *ena_dev = adapter->ena_dev;
int rc, i;
@@ -2686,7 +2106,7 @@ err_setup_tx:
}
}
-static int ena_up(struct ena_adapter *adapter)
+int ena_up(struct ena_adapter *adapter)
{
int io_queue_count, rc, i;
@@ -2748,7 +2168,7 @@ err_req_irq:
return rc;
}
-static void ena_down(struct ena_adapter *adapter)
+void ena_down(struct ena_adapter *adapter)
{
int io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 33c923e..041f08d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -110,19 +110,6 @@
#define ENA_MMIO_DISABLE_REG_READ BIT(0)
-/* The max MTU size is configured to be the ethernet frame size without
- * the overhead of the ethernet header, which can have a VLAN header, and
- * a frame check sequence (FCS).
- * The buffer size we share with the device is defined to be ENA_PAGE_SIZE
- */
-
-#define ENA_XDP_MAX_MTU (ENA_PAGE_SIZE - ETH_HLEN - ETH_FCS_LEN - \
- VLAN_HLEN - XDP_PACKET_HEADROOM - \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-
-#define ENA_IS_XDP_INDEX(adapter, index) (((index) >= (adapter)->xdp_first_ring) && \
- ((index) < (adapter)->xdp_first_ring + (adapter)->xdp_num_queues))
-
struct ena_irq {
irq_handler_t handler;
void *data;
@@ -421,47 +408,44 @@ static inline void ena_reset_device(struct ena_adapter *adapter,
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
}
-enum ena_xdp_errors_t {
- ENA_XDP_ALLOWED = 0,
- ENA_XDP_CURRENT_MTU_TOO_LARGE,
- ENA_XDP_NO_ENOUGH_QUEUES,
-};
-
-enum ENA_XDP_ACTIONS {
- ENA_XDP_PASS = 0,
- ENA_XDP_TX = BIT(0),
- ENA_XDP_REDIRECT = BIT(1),
- ENA_XDP_DROP = BIT(2)
-};
-
-#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
-
-static inline bool ena_xdp_present(struct ena_adapter *adapter)
-{
- return !!adapter->xdp_bpf_prog;
-}
-
-static inline bool ena_xdp_present_ring(struct ena_ring *ring)
-{
- return !!ring->xdp_bpf_prog;
-}
+int handle_invalid_req_id(struct ena_ring *ring, u16 req_id,
+ struct ena_tx_buffer *tx_info, bool is_xdp);
-static inline bool ena_xdp_legal_queue_count(struct ena_adapter *adapter,
- u32 queues)
+/* Increase a stat by cnt while holding syncp seqlock on 32bit machines */
+static inline void ena_increase_stat(u64 *statp, u64 cnt,
+ struct u64_stats_sync *syncp)
{
- return 2 * queues <= adapter->max_num_io_queues;
+ u64_stats_update_begin(syncp);
+ (*statp) += cnt;
+ u64_stats_update_end(syncp);
}
-static inline enum ena_xdp_errors_t ena_xdp_allowed(struct ena_adapter *adapter)
+static inline void ena_ring_tx_doorbell(struct ena_ring *tx_ring)
{
- enum ena_xdp_errors_t rc = ENA_XDP_ALLOWED;
-
- if (adapter->netdev->mtu > ENA_XDP_MAX_MTU)
- rc = ENA_XDP_CURRENT_MTU_TOO_LARGE;
- else if (!ena_xdp_legal_queue_count(adapter, adapter->num_io_queues))
- rc = ENA_XDP_NO_ENOUGH_QUEUES;
-
- return rc;
+ ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
+ ena_increase_stat(&tx_ring->tx_stats.doorbells, 1, &tx_ring->syncp);
}
+int ena_xmit_common(struct net_device *dev,
+ struct ena_ring *ring,
+ struct ena_tx_buffer *tx_info,
+ struct ena_com_tx_ctx *ena_tx_ctx,
+ u16 next_to_use,
+ u32 bytes);
+void ena_unmap_tx_buff(struct ena_ring *tx_ring,
+ struct ena_tx_buffer *tx_info);
+void ena_init_io_rings(struct ena_adapter *adapter,
+ int first_index, int count);
+int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter,
+ int first_index, int count);
+int ena_setup_tx_resources_in_range(struct ena_adapter *adapter,
+ int first_index, int count);
+void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter,
+ int first_index, int count);
+void ena_free_all_io_tx_resources(struct ena_adapter *adapter);
+void ena_down(struct ena_adapter *adapter);
+int ena_up(struct ena_adapter *adapter);
+void ena_unmask_interrupt(struct ena_ring *tx_ring, struct ena_ring *rx_ring);
+void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring);
#endif /* !(ENA_H) */
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
new file mode 100644
index 0000000..d0c8a2d
--- /dev/null
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * Copyright 2015-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
+ */
+
+#include "ena_xdp.h"
+
+static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id)
+{
+ struct ena_tx_buffer *tx_info;
+
+ tx_info = &xdp_ring->tx_buffer_info[req_id];
+ if (likely(tx_info->xdpf))
+ return 0;
+
+ return handle_invalid_req_id(xdp_ring, req_id, tx_info, true);
+}
+
+static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
+ struct ena_tx_buffer *tx_info,
+ struct xdp_frame *xdpf,
+ struct ena_com_tx_ctx *ena_tx_ctx)
+{
+ struct ena_adapter *adapter = xdp_ring->adapter;
+ struct ena_com_buf *ena_buf;
+ int push_len = 0;
+ dma_addr_t dma;
+ void *data;
+ u32 size;
+
+ tx_info->xdpf = xdpf;
+ data = tx_info->xdpf->data;
+ size = tx_info->xdpf->len;
+
+ if (xdp_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+ /* Designate part of the packet for LLQ */
+ push_len = min_t(u32, size, xdp_ring->tx_max_header_size);
+
+ ena_tx_ctx->push_header = data;
+
+ size -= push_len;
+ data += push_len;
+ }
+
+ ena_tx_ctx->header_len = push_len;
+
+ if (size > 0) {
+ dma = dma_map_single(xdp_ring->dev,
+ data,
+ size,
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(xdp_ring->dev, dma)))
+ goto error_report_dma_error;
+
+ tx_info->map_linear_data = 0;
+
+ ena_buf = tx_info->bufs;
+ ena_buf->paddr = dma;
+ ena_buf->len = size;
+
+ ena_tx_ctx->ena_bufs = ena_buf;
+ ena_tx_ctx->num_bufs = tx_info->num_of_bufs = 1;
+ }
+
+ return 0;
+
+error_report_dma_error:
+ ena_increase_stat(&xdp_ring->tx_stats.dma_mapping_err, 1,
+ &xdp_ring->syncp);
+ netif_warn(adapter, tx_queued, adapter->netdev, "Failed to map xdp buff\n");
+
+ return -EINVAL;
+}
+
+int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
+ struct net_device *dev,
+ struct xdp_frame *xdpf,
+ int flags)
+{
+ struct ena_com_tx_ctx ena_tx_ctx = {};
+ struct ena_tx_buffer *tx_info;
+ u16 next_to_use, req_id;
+ int rc;
+
+ next_to_use = xdp_ring->next_to_use;
+ req_id = xdp_ring->free_ids[next_to_use];
+ tx_info = &xdp_ring->tx_buffer_info[req_id];
+ tx_info->num_of_bufs = 0;
+
+ rc = ena_xdp_tx_map_frame(xdp_ring, tx_info, xdpf, &ena_tx_ctx);
+ if (unlikely(rc))
+ return rc;
+
+ ena_tx_ctx.req_id = req_id;
+
+ rc = ena_xmit_common(dev,
+ xdp_ring,
+ tx_info,
+ &ena_tx_ctx,
+ next_to_use,
+ xdpf->len);
+ if (rc)
+ goto error_unmap_dma;
+
+ /* trigger the dma engine. ena_ring_tx_doorbell()
+ * calls a memory barrier inside it.
+ */
+ if (flags & XDP_XMIT_FLUSH)
+ ena_ring_tx_doorbell(xdp_ring);
+
+ return rc;
+
+error_unmap_dma:
+ ena_unmap_tx_buff(xdp_ring, tx_info);
+ tx_info->xdpf = NULL;
+ return rc;
+}
+
+int ena_xdp_xmit(struct net_device *dev, int n,
+ struct xdp_frame **frames, u32 flags)
+{
+ struct ena_adapter *adapter = netdev_priv(dev);
+ struct ena_ring *xdp_ring;
+ int qid, i, nxmit = 0;
+
+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+ return -EINVAL;
+
+ if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+ return -ENETDOWN;
+
+ /* We assume that all rings have the same XDP program */
+ if (!READ_ONCE(adapter->rx_ring->xdp_bpf_prog))
+ return -ENXIO;
+
+ qid = smp_processor_id() % adapter->xdp_num_queues;
+ qid += adapter->xdp_first_ring;
+ xdp_ring = &adapter->tx_ring[qid];
+
+ /* Other CPU ids might try to send thorugh this queue */
+ spin_lock(&xdp_ring->xdp_tx_lock);
+
+ for (i = 0; i < n; i++) {
+ if (ena_xdp_xmit_frame(xdp_ring, dev, frames[i], 0))
+ break;
+ nxmit++;
+ }
+
+ /* Ring doorbell to make device aware of the packets */
+ if (flags & XDP_XMIT_FLUSH)
+ ena_ring_tx_doorbell(xdp_ring);
+
+ spin_unlock(&xdp_ring->xdp_tx_lock);
+
+ /* Return number of packets sent */
+ return nxmit;
+}
+
+static void ena_init_all_xdp_queues(struct ena_adapter *adapter)
+{
+ adapter->xdp_first_ring = adapter->num_io_queues;
+ adapter->xdp_num_queues = adapter->num_io_queues;
+
+ ena_init_io_rings(adapter,
+ adapter->xdp_first_ring,
+ adapter->xdp_num_queues);
+}
+
+int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter)
+{
+ u32 xdp_first_ring = adapter->xdp_first_ring;
+ u32 xdp_num_queues = adapter->xdp_num_queues;
+ int rc = 0;
+
+ rc = ena_setup_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues);
+ if (rc)
+ goto setup_err;
+
+ rc = ena_create_io_tx_queues_in_range(adapter, xdp_first_ring, xdp_num_queues);
+ if (rc)
+ goto create_err;
+
+ return 0;
+
+create_err:
+ ena_free_all_io_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues);
+setup_err:
+ return rc;
+}
+
+/* Provides a way for both kernel and bpf-prog to know
+ * more about the RX-queue a given XDP frame arrived on.
+ */
+static int ena_xdp_register_rxq_info(struct ena_ring *rx_ring)
+{
+ int rc;
+
+ rc = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, rx_ring->qid, 0);
+
+ if (rc) {
+ netif_err(rx_ring->adapter, ifup, rx_ring->netdev,
+ "Failed to register xdp rx queue info. RX queue num %d rc: %d\n",
+ rx_ring->qid, rc);
+ goto err;
+ }
+
+ rc = xdp_rxq_info_reg_mem_model(&rx_ring->xdp_rxq, MEM_TYPE_PAGE_SHARED, NULL);
+
+ if (rc) {
+ netif_err(rx_ring->adapter, ifup, rx_ring->netdev,
+ "Failed to register xdp rx queue info memory model. RX queue num %d rc: %d\n",
+ rx_ring->qid, rc);
+ xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
+ }
+
+err:
+ return rc;
+}
+
+static void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring)
+{
+ xdp_rxq_info_unreg_mem_model(&rx_ring->xdp_rxq);
+ xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
+}
+
+void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
+ struct bpf_prog *prog,
+ int first, int count)
+{
+ struct bpf_prog *old_bpf_prog;
+ struct ena_ring *rx_ring;
+ int i = 0;
+
+ for (i = first; i < count; i++) {
+ rx_ring = &adapter->rx_ring[i];
+ old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
+
+ if (!old_bpf_prog && prog) {
+ ena_xdp_register_rxq_info(rx_ring);
+ rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
+ } else if (old_bpf_prog && !prog) {
+ ena_xdp_unregister_rxq_info(rx_ring);
+ rx_ring->rx_headroom = NET_SKB_PAD;
+ }
+ }
+}
+
+static void ena_xdp_exchange_program(struct ena_adapter *adapter,
+ struct bpf_prog *prog)
+{
+ struct bpf_prog *old_bpf_prog = xchg(&adapter->xdp_bpf_prog, prog);
+
+ ena_xdp_exchange_program_rx_in_range(adapter,
+ prog,
+ 0,
+ adapter->num_io_queues);
+
+ if (old_bpf_prog)
+ bpf_prog_put(old_bpf_prog);
+}
+
+static int ena_destroy_and_free_all_xdp_queues(struct ena_adapter *adapter)
+{
+ bool was_up;
+ int rc;
+
+ was_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+
+ if (was_up)
+ ena_down(adapter);
+
+ adapter->xdp_first_ring = 0;
+ adapter->xdp_num_queues = 0;
+ ena_xdp_exchange_program(adapter, NULL);
+ if (was_up) {
+ rc = ena_up(adapter);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
+{
+ struct ena_adapter *adapter = netdev_priv(netdev);
+ struct bpf_prog *prog = bpf->prog;
+ struct bpf_prog *old_bpf_prog;
+ int rc, prev_mtu;
+ bool is_up;
+
+ is_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+ rc = ena_xdp_allowed(adapter);
+ if (rc == ENA_XDP_ALLOWED) {
+ old_bpf_prog = adapter->xdp_bpf_prog;
+ if (prog) {
+ if (!is_up) {
+ ena_init_all_xdp_queues(adapter);
+ } else if (!old_bpf_prog) {
+ ena_down(adapter);
+ ena_init_all_xdp_queues(adapter);
+ }
+ ena_xdp_exchange_program(adapter, prog);
+
+ if (is_up && !old_bpf_prog) {
+ rc = ena_up(adapter);
+ if (rc)
+ return rc;
+ }
+ xdp_features_set_redirect_target(netdev, false);
+ } else if (old_bpf_prog) {
+ xdp_features_clear_redirect_target(netdev);
+ rc = ena_destroy_and_free_all_xdp_queues(adapter);
+ if (rc)
+ return rc;
+ }
+
+ prev_mtu = netdev->max_mtu;
+ netdev->max_mtu = prog ? ENA_XDP_MAX_MTU : adapter->max_mtu;
+
+ if (!old_bpf_prog)
+ netif_info(adapter, drv, adapter->netdev,
+ "XDP program is set, changing the max_mtu from %d to %d",
+ prev_mtu, netdev->max_mtu);
+
+ } else if (rc == ENA_XDP_CURRENT_MTU_TOO_LARGE) {
+ netif_err(adapter, drv, adapter->netdev,
+ "Failed to set xdp program, the current MTU (%d) is larger than the maximum allowed MTU (%lu) while xdp is on",
+ netdev->mtu, ENA_XDP_MAX_MTU);
+ NL_SET_ERR_MSG_MOD(bpf->extack,
+ "Failed to set xdp program, the current MTU is larger than the maximum allowed MTU. Check the dmesg for more info");
+ return -EINVAL;
+ } else if (rc == ENA_XDP_NO_ENOUGH_QUEUES) {
+ netif_err(adapter, drv, adapter->netdev,
+ "Failed to set xdp program, the Rx/Tx channel count should be at most half of the maximum allowed channel count. The current queue count (%d), the maximal queue count (%d)\n",
+ adapter->num_io_queues, adapter->max_num_io_queues);
+ NL_SET_ERR_MSG_MOD(bpf->extack,
+ "Failed to set xdp program, there is no enough space for allocating XDP queues, Check the dmesg for more info");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* This is the main xdp callback, it's used by the kernel to set/unset the xdp
+ * program as well as to query the current xdp program id.
+ */
+int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
+{
+ switch (bpf->command) {
+ case XDP_SETUP_PROG:
+ return ena_xdp_set(netdev, bpf);
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget)
+{
+ u32 total_done = 0;
+ u16 next_to_clean;
+ int tx_pkts = 0;
+ u16 req_id;
+ int rc;
+
+ if (unlikely(!xdp_ring))
+ return 0;
+ next_to_clean = xdp_ring->next_to_clean;
+
+ while (tx_pkts < budget) {
+ struct ena_tx_buffer *tx_info;
+ struct xdp_frame *xdpf;
+
+ rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq,
+ &req_id);
+ if (rc) {
+ if (unlikely(rc == -EINVAL))
+ handle_invalid_req_id(xdp_ring, req_id, NULL,
+ true);
+ break;
+ }
+
+ /* validate that the request id points to a valid xdp_frame */
+ rc = validate_xdp_req_id(xdp_ring, req_id);
+ if (rc)
+ break;
+
+ tx_info = &xdp_ring->tx_buffer_info[req_id];
+ xdpf = tx_info->xdpf;
+
+ tx_info->xdpf = NULL;
+ tx_info->last_jiffies = 0;
+ ena_unmap_tx_buff(xdp_ring, tx_info);
+
+ netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
+ "tx_poll: q %d skb %p completed\n", xdp_ring->qid,
+ xdpf);
+
+ tx_pkts++;
+ total_done += tx_info->tx_descs;
+
+ xdp_return_frame(xdpf);
+ xdp_ring->free_ids[next_to_clean] = req_id;
+ next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
+ xdp_ring->ring_size);
+ }
+
+ xdp_ring->next_to_clean = next_to_clean;
+ ena_com_comp_ack(xdp_ring->ena_com_io_sq, total_done);
+ ena_com_update_dev_comp_head(xdp_ring->ena_com_io_cq);
+
+ netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
+ "tx_poll: q %d done. total pkts: %d\n",
+ xdp_ring->qid, tx_pkts);
+
+ return tx_pkts;
+}
+
+/* This is the XDP napi callback. XDP queues use a separate napi callback
+ * than Rx/Tx queues.
+ */
+int ena_xdp_io_poll(struct napi_struct *napi, int budget)
+{
+ struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
+ u32 xdp_work_done, xdp_budget;
+ struct ena_ring *xdp_ring;
+ int napi_comp_call = 0;
+ int ret;
+
+ xdp_ring = ena_napi->xdp_ring;
+
+ xdp_budget = budget;
+
+ if (!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags) ||
+ test_bit(ENA_FLAG_TRIGGER_RESET, &xdp_ring->adapter->flags)) {
+ napi_complete_done(napi, 0);
+ return 0;
+ }
+
+ xdp_work_done = ena_clean_xdp_irq(xdp_ring, xdp_budget);
+
+ /* If the device is about to reset or down, avoid unmask
+ * the interrupt and return 0 so NAPI won't reschedule
+ */
+ if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags))) {
+ napi_complete_done(napi, 0);
+ ret = 0;
+ } else if (xdp_budget > xdp_work_done) {
+ napi_comp_call = 1;
+ if (napi_complete_done(napi, xdp_work_done))
+ ena_unmask_interrupt(xdp_ring, NULL);
+ ena_update_ring_numa_node(xdp_ring, NULL);
+ ret = xdp_work_done;
+ } else {
+ ret = xdp_budget;
+ }
+
+ u64_stats_update_begin(&xdp_ring->syncp);
+ xdp_ring->tx_stats.napi_comp += napi_comp_call;
+ xdp_ring->tx_stats.tx_poll++;
+ u64_stats_update_end(&xdp_ring->syncp);
+ xdp_ring->tx_stats.last_napi_jiffies = jiffies;
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.h b/drivers/net/ethernet/amazon/ena/ena_xdp.h
new file mode 100644
index 0000000..80c7496
--- /dev/null
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/*
+ * Copyright 2015-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
+ */
+
+#ifndef ENA_XDP_H
+#define ENA_XDP_H
+
+#include "ena_netdev.h"
+#include <linux/bpf_trace.h>
+
+/* The max MTU size is configured to be the ethernet frame size without
+ * the overhead of the ethernet header, which can have a VLAN header, and
+ * a frame check sequence (FCS).
+ * The buffer size we share with the device is defined to be ENA_PAGE_SIZE
+ */
+#define ENA_XDP_MAX_MTU (ENA_PAGE_SIZE - ETH_HLEN - ETH_FCS_LEN - \
+ VLAN_HLEN - XDP_PACKET_HEADROOM - \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
+#define ENA_IS_XDP_INDEX(adapter, index) (((index) >= (adapter)->xdp_first_ring) && \
+ ((index) < (adapter)->xdp_first_ring + (adapter)->xdp_num_queues))
+
+enum ENA_XDP_ACTIONS {
+ ENA_XDP_PASS = 0,
+ ENA_XDP_TX = BIT(0),
+ ENA_XDP_REDIRECT = BIT(1),
+ ENA_XDP_DROP = BIT(2)
+};
+
+#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
+
+int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter);
+void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
+ struct bpf_prog *prog,
+ int first, int count);
+int ena_xdp_io_poll(struct napi_struct *napi, int budget);
+int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
+ struct net_device *dev,
+ struct xdp_frame *xdpf,
+ int flags);
+int ena_xdp_xmit(struct net_device *dev, int n,
+ struct xdp_frame **frames, u32 flags);
+int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf);
+
+enum ena_xdp_errors_t {
+ ENA_XDP_ALLOWED = 0,
+ ENA_XDP_CURRENT_MTU_TOO_LARGE,
+ ENA_XDP_NO_ENOUGH_QUEUES,
+};
+
+static inline bool ena_xdp_present(struct ena_adapter *adapter)
+{
+ return !!adapter->xdp_bpf_prog;
+}
+
+static inline bool ena_xdp_present_ring(struct ena_ring *ring)
+{
+ return !!ring->xdp_bpf_prog;
+}
+
+static inline bool ena_xdp_legal_queue_count(struct ena_adapter *adapter,
+ u32 queues)
+{
+ return 2 * queues <= adapter->max_num_io_queues;
+}
+
+static inline enum ena_xdp_errors_t ena_xdp_allowed(struct ena_adapter *adapter)
+{
+ enum ena_xdp_errors_t rc = ENA_XDP_ALLOWED;
+
+ if (adapter->netdev->mtu > ENA_XDP_MAX_MTU)
+ rc = ENA_XDP_CURRENT_MTU_TOO_LARGE;
+ else if (!ena_xdp_legal_queue_count(adapter, adapter->num_io_queues))
+ rc = ENA_XDP_NO_ENOUGH_QUEUES;
+
+ return rc;
+}
+
+static inline int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+{
+ u32 verdict = ENA_XDP_PASS;
+ struct bpf_prog *xdp_prog;
+ struct ena_ring *xdp_ring;
+ struct xdp_frame *xdpf;
+ u64 *xdp_stat;
+
+ xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog);
+
+ if (!xdp_prog)
+ return verdict;
+
+ verdict = bpf_prog_run_xdp(xdp_prog, xdp);
+
+ switch (verdict) {
+ case XDP_TX:
+ xdpf = xdp_convert_buff_to_frame(xdp);
+ if (unlikely(!xdpf)) {
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+ verdict = ENA_XDP_DROP;
+ break;
+ }
+
+ /* Find xmit queue */
+ xdp_ring = rx_ring->xdp_ring;
+
+ /* The XDP queues are shared between XDP_TX and XDP_REDIRECT */
+ spin_lock(&xdp_ring->xdp_tx_lock);
+
+ if (ena_xdp_xmit_frame(xdp_ring, rx_ring->netdev, xdpf,
+ XDP_XMIT_FLUSH))
+ xdp_return_frame(xdpf);
+
+ spin_unlock(&xdp_ring->xdp_tx_lock);
+ xdp_stat = &rx_ring->rx_stats.xdp_tx;
+ verdict = ENA_XDP_TX;
+ break;
+ case XDP_REDIRECT:
+ if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
+ xdp_stat = &rx_ring->rx_stats.xdp_redirect;
+ verdict = ENA_XDP_REDIRECT;
+ break;
+ }
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_ABORTED:
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_DROP:
+ xdp_stat = &rx_ring->rx_stats.xdp_drop;
+ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_PASS:
+ xdp_stat = &rx_ring->rx_stats.xdp_pass;
+ verdict = ENA_XDP_PASS;
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_invalid;
+ verdict = ENA_XDP_DROP;
+ }
+
+ ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
+
+ return verdict;
+}
+#endif /* ENA_XDP_H */
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 02/11] net: ena: Pass ena_adapter instead of net_device to ena_xmit_common()
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 01/11] net: ena: Move XDP code to its new files darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 03/11] net: ena: Put orthogonal fields in ena_tx_buffer in a union darinzon
` (10 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
This change will enable the ability to use ena_xmit_common()
in functions that don't have a net_device pointer.
While it can be retrieved by dereferencing
ena_adapter (adapter->netdev), there's no reason to do it in
fast path code where this pointer is only needed for
debug prints.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 ++++-----
drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
drivers/net/ethernet/amazon/ena/ena_xdp.c | 6 +++---
drivers/net/ethernet/amazon/ena/ena_xdp.h | 4 ++--
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 0a0d97c..b7f300b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -88,19 +88,18 @@ static int ena_change_mtu(struct net_device *dev, int new_mtu)
return ret;
}
-int ena_xmit_common(struct net_device *dev,
+int ena_xmit_common(struct ena_adapter *adapter,
struct ena_ring *ring,
struct ena_tx_buffer *tx_info,
struct ena_com_tx_ctx *ena_tx_ctx,
u16 next_to_use,
u32 bytes)
{
- struct ena_adapter *adapter = netdev_priv(dev);
int rc, nb_hw_desc;
if (unlikely(ena_com_is_doorbell_needed(ring->ena_com_io_sq,
ena_tx_ctx))) {
- netif_dbg(adapter, tx_queued, dev,
+ netif_dbg(adapter, tx_queued, adapter->netdev,
"llq tx max burst size of queue %d achieved, writing doorbell to send burst\n",
ring->qid);
ena_ring_tx_doorbell(ring);
@@ -115,7 +114,7 @@ int ena_xmit_common(struct net_device *dev,
* ena_com_prepare_tx() are fatal and therefore require a device reset.
*/
if (unlikely(rc)) {
- netif_err(adapter, tx_queued, dev,
+ netif_err(adapter, tx_queued, adapter->netdev,
"Failed to prepare tx bufs\n");
ena_increase_stat(&ring->tx_stats.prepare_ctx_err, 1,
&ring->syncp);
@@ -2599,7 +2598,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* set flags and meta data */
ena_tx_csum(&ena_tx_ctx, skb, tx_ring->disable_meta_caching);
- rc = ena_xmit_common(dev,
+ rc = ena_xmit_common(adapter,
tx_ring,
tx_info,
&ena_tx_ctx,
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 041f08d..236d1f8 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -426,7 +426,7 @@ static inline void ena_ring_tx_doorbell(struct ena_ring *tx_ring)
ena_increase_stat(&tx_ring->tx_stats.doorbells, 1, &tx_ring->syncp);
}
-int ena_xmit_common(struct net_device *dev,
+int ena_xmit_common(struct ena_adapter *adapter,
struct ena_ring *ring,
struct ena_tx_buffer *tx_info,
struct ena_com_tx_ctx *ena_tx_ctx,
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
index d0c8a2d..42370fa 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -73,7 +73,7 @@ error_report_dma_error:
}
int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
- struct net_device *dev,
+ struct ena_adapter *adapter,
struct xdp_frame *xdpf,
int flags)
{
@@ -93,7 +93,7 @@ int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
ena_tx_ctx.req_id = req_id;
- rc = ena_xmit_common(dev,
+ rc = ena_xmit_common(adapter,
xdp_ring,
tx_info,
&ena_tx_ctx,
@@ -141,7 +141,7 @@ int ena_xdp_xmit(struct net_device *dev, int n,
spin_lock(&xdp_ring->xdp_tx_lock);
for (i = 0; i < n; i++) {
- if (ena_xdp_xmit_frame(xdp_ring, dev, frames[i], 0))
+ if (ena_xdp_xmit_frame(xdp_ring, adapter, frames[i], 0))
break;
nxmit++;
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.h b/drivers/net/ethernet/amazon/ena/ena_xdp.h
index 80c7496..6e472ba 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.h
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.h
@@ -36,7 +36,7 @@ void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
int first, int count);
int ena_xdp_io_poll(struct napi_struct *napi, int budget);
int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
- struct net_device *dev,
+ struct ena_adapter *adapter,
struct xdp_frame *xdpf,
int flags);
int ena_xdp_xmit(struct net_device *dev, int n,
@@ -108,7 +108,7 @@ static inline int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp
/* The XDP queues are shared between XDP_TX and XDP_REDIRECT */
spin_lock(&xdp_ring->xdp_tx_lock);
- if (ena_xdp_xmit_frame(xdp_ring, rx_ring->netdev, xdpf,
+ if (ena_xdp_xmit_frame(xdp_ring, rx_ring->adapter, xdpf,
XDP_XMIT_FLUSH))
xdp_return_frame(xdpf);
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 03/11] net: ena: Put orthogonal fields in ena_tx_buffer in a union
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 01/11] net: ena: Move XDP code to its new files darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 02/11] net: ena: Pass ena_adapter instead of net_device to ena_xmit_common() darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 04/11] net: ena: Introduce total_tx_size field in ena_tx_buffer struct darinzon
` (9 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
The skb and xdpf pointers cannot be set together in the driver
(each TX descriptor can send either an SKB or an XDP frame), and so it
makes more sense to put them both in a union.
This decreases the overall size of the ena_tx_buffer struct which
improves cache locality.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 236d1f8..78a4dee 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -131,7 +131,13 @@ struct ena_napi {
};
struct ena_tx_buffer {
- struct sk_buff *skb;
+ union {
+ struct sk_buff *skb;
+ /* XDP buffer structure which is used for sending packets in
+ * the xdp queues
+ */
+ struct xdp_frame *xdpf;
+ };
/* num of ena desc for this specific skb
* (includes data desc and metadata desc)
*/
@@ -139,10 +145,6 @@ struct ena_tx_buffer {
/* num of buffers used by this skb */
u32 num_of_bufs;
- /* XDP buffer structure which is used for sending packets in
- * the xdp queues
- */
- struct xdp_frame *xdpf;
/* Indicate if bufs[0] map the linear data of the skb. */
u8 map_linear_data;
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 04/11] net: ena: Introduce total_tx_size field in ena_tx_buffer struct
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (2 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 03/11] net: ena: Put orthogonal fields in ena_tx_buffer in a union darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 05/11] net: ena: Use tx_ring instead of xdp_ring for XDP channel TX darinzon
` (8 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
To avoid de-referencing skb or xdp_frame when we poll for TX completion
(where they might not be in the cache), save the total TX packet size in
the ena_tx_buffer object representing the packet.
Also the 'print_once' field's type was changed from u32 to u8 to allow
adding the 'total_tx_size' without changing the total size of the
struct.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++-
drivers/net/ethernet/amazon/ena/ena_netdev.h | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index b7f300b..3c84259 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -130,6 +130,7 @@ int ena_xmit_common(struct ena_adapter *adapter,
u64_stats_update_end(&ring->syncp);
tx_info->tx_descs = nb_hw_desc;
+ tx_info->total_tx_size = bytes;
tx_info->last_jiffies = jiffies;
tx_info->print_once = 0;
@@ -842,7 +843,7 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
"tx_poll: q %d skb %p completed\n", tx_ring->qid,
skb);
- tx_bytes += skb->len;
+ tx_bytes += tx_info->total_tx_size;
dev_kfree_skb(skb);
tx_pkts++;
total_done += tx_info->tx_descs;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 78a4dee..d3fc03f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -145,12 +145,14 @@ struct ena_tx_buffer {
/* num of buffers used by this skb */
u32 num_of_bufs;
+ /* Total size of all buffers in bytes */
+ u32 total_tx_size;
/* Indicate if bufs[0] map the linear data of the skb. */
u8 map_linear_data;
/* Used for detect missing tx packets to limit the number of prints */
- u32 print_once;
+ u8 print_once;
/* Save the last jiffies to detect missing tx packets
*
* sets to non zero value on ena_start_xmit and set to zero on
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 05/11] net: ena: Use tx_ring instead of xdp_ring for XDP channel TX
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (3 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 04/11] net: ena: Introduce total_tx_size field in ena_tx_buffer struct darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 06/11] net: ena: Don't check if XDP program is loaded in ena_xdp_execute() darinzon
` (7 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
When an XDP program is loaded the existing channels in the driver split
into two halves:
- The first half of the channels contain RX and TX rings, these queues
are used for receiving traffic and sending packets originating from
kernel.
- The second half of the channels contain only a TX ring. These queues
are used for sending packets that were redirected using XDP_TX
or XDP_REDIRECT.
Referring to the queues in the second half of the channels as "xdp_ring"
can be confusing and may give the impression that ENA has the capability
to generate an additional special queue.
This patch ensures that the xdp_ring field is exclusively used to
describe the XDP TX queue that a specific RX queue needs to utilize when
forwarding packets with XDP TX and XDP REDIRECT, preserving the
integrity of the xdp_ring field in ena_ring.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 12 +-
drivers/net/ethernet/amazon/ena/ena_netdev.h | 1 -
drivers/net/ethernet/amazon/ena/ena_xdp.c | 111 +++++++++----------
drivers/net/ethernet/amazon/ena/ena_xdp.h | 2 +-
4 files changed, 61 insertions(+), 65 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 3c84259..6ababac 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1746,8 +1746,8 @@ static void ena_del_napi_in_range(struct ena_adapter *adapter,
for (i = first_index; i < first_index + count; i++) {
netif_napi_del(&adapter->ena_napi[i].napi);
- WARN_ON(!ENA_IS_XDP_INDEX(adapter, i) &&
- adapter->ena_napi[i].xdp_ring);
+ WARN_ON(ENA_IS_XDP_INDEX(adapter, i) &&
+ adapter->ena_napi[i].rx_ring);
}
}
@@ -1762,12 +1762,10 @@ static void ena_init_napi_in_range(struct ena_adapter *adapter,
netif_napi_add(adapter->netdev, &napi->napi,
ENA_IS_XDP_INDEX(adapter, i) ? ena_xdp_io_poll : ena_io_poll);
- if (!ENA_IS_XDP_INDEX(adapter, i)) {
+ if (!ENA_IS_XDP_INDEX(adapter, i))
napi->rx_ring = &adapter->rx_ring[i];
- napi->tx_ring = &adapter->tx_ring[i];
- } else {
- napi->xdp_ring = &adapter->tx_ring[i];
- }
+
+ napi->tx_ring = &adapter->tx_ring[i];
napi->qid = i;
}
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index d3fc03f..6d2cc20 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -125,7 +125,6 @@ struct ena_napi {
struct napi_struct napi;
struct ena_ring *tx_ring;
struct ena_ring *rx_ring;
- struct ena_ring *xdp_ring;
u32 qid;
struct dim dim;
};
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
index 42370fa..363e361 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -5,23 +5,23 @@
#include "ena_xdp.h"
-static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id)
+static int validate_xdp_req_id(struct ena_ring *tx_ring, u16 req_id)
{
struct ena_tx_buffer *tx_info;
- tx_info = &xdp_ring->tx_buffer_info[req_id];
+ tx_info = &tx_ring->tx_buffer_info[req_id];
if (likely(tx_info->xdpf))
return 0;
- return handle_invalid_req_id(xdp_ring, req_id, tx_info, true);
+ return handle_invalid_req_id(tx_ring, req_id, tx_info, true);
}
-static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
+static int ena_xdp_tx_map_frame(struct ena_ring *tx_ring,
struct ena_tx_buffer *tx_info,
struct xdp_frame *xdpf,
struct ena_com_tx_ctx *ena_tx_ctx)
{
- struct ena_adapter *adapter = xdp_ring->adapter;
+ struct ena_adapter *adapter = tx_ring->adapter;
struct ena_com_buf *ena_buf;
int push_len = 0;
dma_addr_t dma;
@@ -32,9 +32,9 @@ static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
data = tx_info->xdpf->data;
size = tx_info->xdpf->len;
- if (xdp_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+ if (tx_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
/* Designate part of the packet for LLQ */
- push_len = min_t(u32, size, xdp_ring->tx_max_header_size);
+ push_len = min_t(u32, size, tx_ring->tx_max_header_size);
ena_tx_ctx->push_header = data;
@@ -45,11 +45,11 @@ static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
ena_tx_ctx->header_len = push_len;
if (size > 0) {
- dma = dma_map_single(xdp_ring->dev,
+ dma = dma_map_single(tx_ring->dev,
data,
size,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(xdp_ring->dev, dma)))
+ if (unlikely(dma_mapping_error(tx_ring->dev, dma)))
goto error_report_dma_error;
tx_info->map_linear_data = 0;
@@ -65,14 +65,14 @@ static int ena_xdp_tx_map_frame(struct ena_ring *xdp_ring,
return 0;
error_report_dma_error:
- ena_increase_stat(&xdp_ring->tx_stats.dma_mapping_err, 1,
- &xdp_ring->syncp);
+ ena_increase_stat(&tx_ring->tx_stats.dma_mapping_err, 1,
+ &tx_ring->syncp);
netif_warn(adapter, tx_queued, adapter->netdev, "Failed to map xdp buff\n");
return -EINVAL;
}
-int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
+int ena_xdp_xmit_frame(struct ena_ring *tx_ring,
struct ena_adapter *adapter,
struct xdp_frame *xdpf,
int flags)
@@ -82,19 +82,19 @@ int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
u16 next_to_use, req_id;
int rc;
- next_to_use = xdp_ring->next_to_use;
- req_id = xdp_ring->free_ids[next_to_use];
- tx_info = &xdp_ring->tx_buffer_info[req_id];
+ next_to_use = tx_ring->next_to_use;
+ req_id = tx_ring->free_ids[next_to_use];
+ tx_info = &tx_ring->tx_buffer_info[req_id];
tx_info->num_of_bufs = 0;
- rc = ena_xdp_tx_map_frame(xdp_ring, tx_info, xdpf, &ena_tx_ctx);
+ rc = ena_xdp_tx_map_frame(tx_ring, tx_info, xdpf, &ena_tx_ctx);
if (unlikely(rc))
return rc;
ena_tx_ctx.req_id = req_id;
rc = ena_xmit_common(adapter,
- xdp_ring,
+ tx_ring,
tx_info,
&ena_tx_ctx,
next_to_use,
@@ -106,12 +106,12 @@ int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
* calls a memory barrier inside it.
*/
if (flags & XDP_XMIT_FLUSH)
- ena_ring_tx_doorbell(xdp_ring);
+ ena_ring_tx_doorbell(tx_ring);
return rc;
error_unmap_dma:
- ena_unmap_tx_buff(xdp_ring, tx_info);
+ ena_unmap_tx_buff(tx_ring, tx_info);
tx_info->xdpf = NULL;
return rc;
}
@@ -120,7 +120,7 @@ int ena_xdp_xmit(struct net_device *dev, int n,
struct xdp_frame **frames, u32 flags)
{
struct ena_adapter *adapter = netdev_priv(dev);
- struct ena_ring *xdp_ring;
+ struct ena_ring *tx_ring;
int qid, i, nxmit = 0;
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
@@ -135,22 +135,22 @@ int ena_xdp_xmit(struct net_device *dev, int n,
qid = smp_processor_id() % adapter->xdp_num_queues;
qid += adapter->xdp_first_ring;
- xdp_ring = &adapter->tx_ring[qid];
+ tx_ring = &adapter->tx_ring[qid];
/* Other CPU ids might try to send thorugh this queue */
- spin_lock(&xdp_ring->xdp_tx_lock);
+ spin_lock(&tx_ring->xdp_tx_lock);
for (i = 0; i < n; i++) {
- if (ena_xdp_xmit_frame(xdp_ring, adapter, frames[i], 0))
+ if (ena_xdp_xmit_frame(tx_ring, adapter, frames[i], 0))
break;
nxmit++;
}
/* Ring doorbell to make device aware of the packets */
if (flags & XDP_XMIT_FLUSH)
- ena_ring_tx_doorbell(xdp_ring);
+ ena_ring_tx_doorbell(tx_ring);
- spin_unlock(&xdp_ring->xdp_tx_lock);
+ spin_unlock(&tx_ring->xdp_tx_lock);
/* Return number of packets sent */
return nxmit;
@@ -355,7 +355,7 @@ int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
return 0;
}
-static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget)
+static int ena_clean_xdp_irq(struct ena_ring *tx_ring, u32 budget)
{
u32 total_done = 0;
u16 next_to_clean;
@@ -363,55 +363,54 @@ static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget)
u16 req_id;
int rc;
- if (unlikely(!xdp_ring))
+ if (unlikely(!tx_ring))
return 0;
- next_to_clean = xdp_ring->next_to_clean;
+ next_to_clean = tx_ring->next_to_clean;
while (tx_pkts < budget) {
struct ena_tx_buffer *tx_info;
struct xdp_frame *xdpf;
- rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq,
+ rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq,
&req_id);
if (rc) {
if (unlikely(rc == -EINVAL))
- handle_invalid_req_id(xdp_ring, req_id, NULL,
- true);
+ handle_invalid_req_id(tx_ring, req_id, NULL, true);
break;
}
/* validate that the request id points to a valid xdp_frame */
- rc = validate_xdp_req_id(xdp_ring, req_id);
+ rc = validate_xdp_req_id(tx_ring, req_id);
if (rc)
break;
- tx_info = &xdp_ring->tx_buffer_info[req_id];
+ tx_info = &tx_ring->tx_buffer_info[req_id];
xdpf = tx_info->xdpf;
tx_info->xdpf = NULL;
tx_info->last_jiffies = 0;
- ena_unmap_tx_buff(xdp_ring, tx_info);
+ ena_unmap_tx_buff(tx_ring, tx_info);
- netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
- "tx_poll: q %d skb %p completed\n", xdp_ring->qid,
+ netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
+ "tx_poll: q %d skb %p completed\n", tx_ring->qid,
xdpf);
tx_pkts++;
total_done += tx_info->tx_descs;
xdp_return_frame(xdpf);
- xdp_ring->free_ids[next_to_clean] = req_id;
+ tx_ring->free_ids[next_to_clean] = req_id;
next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
- xdp_ring->ring_size);
+ tx_ring->ring_size);
}
- xdp_ring->next_to_clean = next_to_clean;
- ena_com_comp_ack(xdp_ring->ena_com_io_sq, total_done);
- ena_com_update_dev_comp_head(xdp_ring->ena_com_io_cq);
+ tx_ring->next_to_clean = next_to_clean;
+ ena_com_comp_ack(tx_ring->ena_com_io_sq, total_done);
+ ena_com_update_dev_comp_head(tx_ring->ena_com_io_cq);
- netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev,
+ netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
"tx_poll: q %d done. total pkts: %d\n",
- xdp_ring->qid, tx_pkts);
+ tx_ring->qid, tx_pkts);
return tx_pkts;
}
@@ -423,43 +422,43 @@ int ena_xdp_io_poll(struct napi_struct *napi, int budget)
{
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
u32 xdp_work_done, xdp_budget;
- struct ena_ring *xdp_ring;
+ struct ena_ring *tx_ring;
int napi_comp_call = 0;
int ret;
- xdp_ring = ena_napi->xdp_ring;
+ tx_ring = ena_napi->tx_ring;
xdp_budget = budget;
- if (!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags) ||
- test_bit(ENA_FLAG_TRIGGER_RESET, &xdp_ring->adapter->flags)) {
+ if (!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags) ||
+ test_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags)) {
napi_complete_done(napi, 0);
return 0;
}
- xdp_work_done = ena_clean_xdp_irq(xdp_ring, xdp_budget);
+ xdp_work_done = ena_clean_xdp_irq(tx_ring, xdp_budget);
/* If the device is about to reset or down, avoid unmask
* the interrupt and return 0 so NAPI won't reschedule
*/
- if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags))) {
+ if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags))) {
napi_complete_done(napi, 0);
ret = 0;
} else if (xdp_budget > xdp_work_done) {
napi_comp_call = 1;
if (napi_complete_done(napi, xdp_work_done))
- ena_unmask_interrupt(xdp_ring, NULL);
- ena_update_ring_numa_node(xdp_ring, NULL);
+ ena_unmask_interrupt(tx_ring, NULL);
+ ena_update_ring_numa_node(tx_ring, NULL);
ret = xdp_work_done;
} else {
ret = xdp_budget;
}
- u64_stats_update_begin(&xdp_ring->syncp);
- xdp_ring->tx_stats.napi_comp += napi_comp_call;
- xdp_ring->tx_stats.tx_poll++;
- u64_stats_update_end(&xdp_ring->syncp);
- xdp_ring->tx_stats.last_napi_jiffies = jiffies;
+ u64_stats_update_begin(&tx_ring->syncp);
+ tx_ring->tx_stats.napi_comp += napi_comp_call;
+ tx_ring->tx_stats.tx_poll++;
+ u64_stats_update_end(&tx_ring->syncp);
+ tx_ring->tx_stats.last_napi_jiffies = jiffies;
return ret;
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.h b/drivers/net/ethernet/amazon/ena/ena_xdp.h
index 6e472ba..3fa8e80 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.h
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.h
@@ -35,7 +35,7 @@ void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
struct bpf_prog *prog,
int first, int count);
int ena_xdp_io_poll(struct napi_struct *napi, int budget);
-int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,
+int ena_xdp_xmit_frame(struct ena_ring *tx_ring,
struct ena_adapter *adapter,
struct xdp_frame *xdpf,
int flags);
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 06/11] net: ena: Don't check if XDP program is loaded in ena_xdp_execute()
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (4 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 05/11] net: ena: Use tx_ring instead of xdp_ring for XDP channel TX darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 07/11] net: ena: Refactor napi functions darinzon
` (6 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
This check is already done in ena_clean_rx_irq() which indirectly
calls it.
This function is called in napi context and the driver doesn't
allow to change the XDP program without performing destruction and
reinitialization of napi context (part of ena_down/ena_up sequence).
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_xdp.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.h b/drivers/net/ethernet/amazon/ena/ena_xdp.h
index 3fa8e80..25204fb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.h
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.h
@@ -87,9 +87,6 @@ static inline int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp
xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog);
- if (!xdp_prog)
- return verdict;
-
verdict = bpf_prog_run_xdp(xdp_prog, xdp);
switch (verdict) {
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 07/11] net: ena: Refactor napi functions
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (5 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 06/11] net: ena: Don't check if XDP program is loaded in ena_xdp_execute() darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-04 2:00 ` Jakub Kicinski
2024-01-01 19:08 ` [PATCH v2 net-next 08/11] net: ena: Add more debug prints to XDP related function darinzon
` (5 subsequent siblings)
12 siblings, 1 reply; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
This patch focuses on changes to the XDP part of the napi
polling routine.
1. Update the `napi_comp` stat only when napi is actually
complete.
2. Simplify the code by using a function pointer to the right
napi routine (XDP vs non-XDP path)
3. Remove unnecessary local variables.
4. Adjust a debug print to show the processed XDP frame index
rather than the pointer.
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 18 +++++++---
drivers/net/ethernet/amazon/ena/ena_xdp.c | 35 +++++++++-----------
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 6ababac..d65ee64 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1754,18 +1754,28 @@ static void ena_del_napi_in_range(struct ena_adapter *adapter,
static void ena_init_napi_in_range(struct ena_adapter *adapter,
int first_index, int count)
{
+ int (*napi_handler)(struct napi_struct *napi, int budget);
int i;
for (i = first_index; i < first_index + count; i++) {
struct ena_napi *napi = &adapter->ena_napi[i];
+ struct ena_ring *rx_ring, *tx_ring;
- netif_napi_add(adapter->netdev, &napi->napi,
- ENA_IS_XDP_INDEX(adapter, i) ? ena_xdp_io_poll : ena_io_poll);
+ memset(napi, 0, sizeof(*napi));
+
+ rx_ring = &adapter->rx_ring[i];
+ tx_ring = &adapter->tx_ring[i];
+
+ napi_handler = ena_io_poll;
+ if (ENA_IS_XDP_INDEX(adapter, i))
+ napi_handler = ena_xdp_io_poll;
+
+ netif_napi_add(adapter->netdev, &napi->napi, napi_handler);
if (!ENA_IS_XDP_INDEX(adapter, i))
- napi->rx_ring = &adapter->rx_ring[i];
+ napi->rx_ring = rx_ring;
- napi->tx_ring = &adapter->tx_ring[i];
+ napi->tx_ring = tx_ring;
napi->qid = i;
}
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
index 363e361..dd01b41 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -385,23 +385,22 @@ static int ena_clean_xdp_irq(struct ena_ring *tx_ring, u32 budget)
break;
tx_info = &tx_ring->tx_buffer_info[req_id];
- xdpf = tx_info->xdpf;
- tx_info->xdpf = NULL;
tx_info->last_jiffies = 0;
- ena_unmap_tx_buff(tx_ring, tx_info);
- netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
- "tx_poll: q %d skb %p completed\n", tx_ring->qid,
- xdpf);
+ xdpf = tx_info->xdpf;
+ tx_info->xdpf = NULL;
+ ena_unmap_tx_buff(tx_ring, tx_info);
+ xdp_return_frame(xdpf);
tx_pkts++;
total_done += tx_info->tx_descs;
-
- xdp_return_frame(xdpf);
tx_ring->free_ids[next_to_clean] = req_id;
next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
tx_ring->ring_size);
+
+ netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
+ "tx_poll: q %d pkt #%d req_id %d\n", tx_ring->qid, tx_pkts, req_id);
}
tx_ring->next_to_clean = next_to_clean;
@@ -421,22 +420,19 @@ static int ena_clean_xdp_irq(struct ena_ring *tx_ring, u32 budget)
int ena_xdp_io_poll(struct napi_struct *napi, int budget)
{
struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
- u32 xdp_work_done, xdp_budget;
struct ena_ring *tx_ring;
- int napi_comp_call = 0;
+ u32 work_done;
int ret;
tx_ring = ena_napi->tx_ring;
- xdp_budget = budget;
-
if (!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags) ||
test_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags)) {
napi_complete_done(napi, 0);
return 0;
}
- xdp_work_done = ena_clean_xdp_irq(tx_ring, xdp_budget);
+ work_done = ena_clean_xdp_irq(tx_ring, budget);
/* If the device is about to reset or down, avoid unmask
* the interrupt and return 0 so NAPI won't reschedule
@@ -444,18 +440,19 @@ int ena_xdp_io_poll(struct napi_struct *napi, int budget)
if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags))) {
napi_complete_done(napi, 0);
ret = 0;
- } else if (xdp_budget > xdp_work_done) {
- napi_comp_call = 1;
- if (napi_complete_done(napi, xdp_work_done))
+ } else if (budget > work_done) {
+ ena_increase_stat(&tx_ring->tx_stats.napi_comp, 1,
+ &tx_ring->syncp);
+ if (napi_complete_done(napi, work_done))
ena_unmask_interrupt(tx_ring, NULL);
+
ena_update_ring_numa_node(tx_ring, NULL);
- ret = xdp_work_done;
+ ret = work_done;
} else {
- ret = xdp_budget;
+ ret = budget;
}
u64_stats_update_begin(&tx_ring->syncp);
- tx_ring->tx_stats.napi_comp += napi_comp_call;
tx_ring->tx_stats.tx_poll++;
u64_stats_update_end(&tx_ring->syncp);
tx_ring->tx_stats.last_napi_jiffies = jiffies;
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 08/11] net: ena: Add more debug prints to XDP related function
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (6 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 07/11] net: ena: Refactor napi functions darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 09/11] net: ena: Always register RX queue info darinzon
` (4 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
Used for better readability and debugging of XDP
flow.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_xdp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
index dd01b41..c9992ce 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -301,6 +301,8 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
}
ena_xdp_exchange_program(adapter, prog);
+ netif_dbg(adapter, drv, adapter->netdev, "Set a new XDP program\n");
+
if (is_up && !old_bpf_prog) {
rc = ena_up(adapter);
if (rc)
@@ -309,6 +311,8 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
xdp_features_set_redirect_target(netdev, false);
} else if (old_bpf_prog) {
xdp_features_clear_redirect_target(netdev);
+ netif_dbg(adapter, drv, adapter->netdev, "Removing XDP program\n");
+
rc = ena_destroy_and_free_all_xdp_queues(adapter);
if (rc)
return rc;
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 09/11] net: ena: Always register RX queue info
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (7 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 08/11] net: ena: Add more debug prints to XDP related function darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 10/11] net: ena: Make queue stats code cleaner by removing the if block darinzon
` (3 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
The RX queue info contains information about the RX queue which might
be relevant to the kernel.
To avoid configuring this queue for different scenarios, this patch
moves the RX queue configuration to ena_up()/ena_down() function and
makes it configured every interface state toggle.
Signed-off-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++++
drivers/net/ethernet/amazon/ena/ena_xdp.c | 11 +++++++----
drivers/net/ethernet/amazon/ena/ena_xdp.h | 2 ++
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index d65ee64..c5a84ea 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -753,6 +753,7 @@ static void ena_destroy_all_rx_queues(struct ena_adapter *adapter)
for (i = 0; i < adapter->num_io_queues; i++) {
ena_qid = ENA_IO_RXQ_IDX(i);
cancel_work_sync(&adapter->ena_napi[i].dim.work);
+ ena_xdp_unregister_rxq_info(&adapter->rx_ring[i]);
ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
}
}
@@ -1984,12 +1985,15 @@ static int ena_create_all_io_rx_queues(struct ena_adapter *adapter)
if (rc)
goto create_err;
INIT_WORK(&adapter->ena_napi[i].dim.work, ena_dim_work);
+
+ ena_xdp_register_rxq_info(&adapter->rx_ring[i]);
}
return 0;
create_err:
while (i--) {
+ ena_xdp_unregister_rxq_info(&adapter->rx_ring[i]);
cancel_work_sync(&adapter->ena_napi[i].dim.work);
ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i));
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.c b/drivers/net/ethernet/amazon/ena/ena_xdp.c
index c9992ce..fc1c4ef 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -191,12 +191,14 @@ setup_err:
/* Provides a way for both kernel and bpf-prog to know
* more about the RX-queue a given XDP frame arrived on.
*/
-static int ena_xdp_register_rxq_info(struct ena_ring *rx_ring)
+int ena_xdp_register_rxq_info(struct ena_ring *rx_ring)
{
int rc;
rc = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, rx_ring->qid, 0);
+ netif_dbg(rx_ring->adapter, ifup, rx_ring->netdev, "Registering RX info for queue %d",
+ rx_ring->qid);
if (rc) {
netif_err(rx_ring->adapter, ifup, rx_ring->netdev,
"Failed to register xdp rx queue info. RX queue num %d rc: %d\n",
@@ -217,8 +219,11 @@ err:
return rc;
}
-static void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring)
+void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring)
{
+ netif_dbg(rx_ring->adapter, ifdown, rx_ring->netdev,
+ "Unregistering RX info for queue %d",
+ rx_ring->qid);
xdp_rxq_info_unreg_mem_model(&rx_ring->xdp_rxq);
xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
}
@@ -236,10 +241,8 @@ void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
if (!old_bpf_prog && prog) {
- ena_xdp_register_rxq_info(rx_ring);
rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
} else if (old_bpf_prog && !prog) {
- ena_xdp_unregister_rxq_info(rx_ring);
rx_ring->rx_headroom = NET_SKB_PAD;
}
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_xdp.h b/drivers/net/ethernet/amazon/ena/ena_xdp.h
index 25204fb..cfd8272 100644
--- a/drivers/net/ethernet/amazon/ena/ena_xdp.h
+++ b/drivers/net/ethernet/amazon/ena/ena_xdp.h
@@ -42,6 +42,8 @@ int ena_xdp_xmit_frame(struct ena_ring *tx_ring,
int ena_xdp_xmit(struct net_device *dev, int n,
struct xdp_frame **frames, u32 flags);
int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf);
+int ena_xdp_register_rxq_info(struct ena_ring *rx_ring);
+void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring);
enum ena_xdp_errors_t {
ENA_XDP_ALLOWED = 0,
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 10/11] net: ena: Make queue stats code cleaner by removing the if block
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (8 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 09/11] net: ena: Always register RX queue info darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 11/11] net: ena: Take xdp packets stats into account in ena_get_stats64() darinzon
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
Also shorten comment related to it.
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_ethtool.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 724af7d..0cb6cc1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -263,17 +263,14 @@ static void ena_queue_strings(struct ena_adapter *adapter, u8 **data)
ena_stats->name);
}
- if (!is_xdp) {
- /* RX stats, in XDP there isn't a RX queue
- * counterpart
- */
- for (j = 0; j < ENA_STATS_ARRAY_RX; j++) {
- ena_stats = &ena_stats_rx_strings[j];
+ /* In XDP there isn't an RX queue counterpart */
+ if (is_xdp)
+ continue;
- ethtool_sprintf(data,
- "queue_%u_rx_%s", i,
- ena_stats->name);
- }
+ for (j = 0; j < ENA_STATS_ARRAY_RX; j++) {
+ ena_stats = &ena_stats_rx_strings[j];
+
+ ethtool_sprintf(data, "queue_%u_rx_%s", i, ena_stats->name);
}
}
}
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 11/11] net: ena: Take xdp packets stats into account in ena_get_stats64()
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (9 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 10/11] net: ena: Make queue stats code cleaner by removing the if block darinzon
@ 2024-01-01 19:08 ` darinzon
2024-01-02 18:08 ` [PATCH v2 net-next 00/11] ENA driver XDP changes Jakub Kicinski
2024-01-04 2:10 ` patchwork-bot+netdevbpf
12 siblings, 0 replies; 18+ messages in thread
From: darinzon @ 2024-01-01 19:08 UTC (permalink / raw)
To: David Miller, Jakub Kicinski, netdev
Cc: David Arinzon, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
From: David Arinzon <darinzon@amazon.com>
Queue stats using ifconfig and ip are retrieved
via ena_get_stats64(). This function currently does not take
the xdp sent or dropped packets stats into account.
This commit adds the following xdp stats to ena_get_stats64():
tx bytes sent
tx packets sent
rx dropped packets
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index c5a84ea..1c0a782 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2795,6 +2795,7 @@ static void ena_get_stats64(struct net_device *netdev,
{
struct ena_adapter *adapter = netdev_priv(netdev);
struct ena_ring *rx_ring, *tx_ring;
+ u64 total_xdp_rx_drops = 0;
unsigned int start;
u64 rx_drops;
u64 tx_drops;
@@ -2803,8 +2804,8 @@ static void ena_get_stats64(struct net_device *netdev,
if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
return;
- for (i = 0; i < adapter->num_io_queues; i++) {
- u64 bytes, packets;
+ for (i = 0; i < adapter->num_io_queues + adapter->xdp_num_queues; i++) {
+ u64 bytes, packets, xdp_rx_drops;
tx_ring = &adapter->tx_ring[i];
@@ -2817,16 +2818,22 @@ static void ena_get_stats64(struct net_device *netdev,
stats->tx_packets += packets;
stats->tx_bytes += bytes;
+ /* In XDP there isn't an RX queue counterpart */
+ if (ENA_IS_XDP_INDEX(adapter, i))
+ continue;
+
rx_ring = &adapter->rx_ring[i];
do {
start = u64_stats_fetch_begin(&rx_ring->syncp);
packets = rx_ring->rx_stats.cnt;
bytes = rx_ring->rx_stats.bytes;
+ xdp_rx_drops = rx_ring->rx_stats.xdp_drop;
} while (u64_stats_fetch_retry(&rx_ring->syncp, start));
stats->rx_packets += packets;
stats->rx_bytes += bytes;
+ total_xdp_rx_drops += xdp_rx_drops;
}
do {
@@ -2835,7 +2842,7 @@ static void ena_get_stats64(struct net_device *netdev,
tx_drops = adapter->dev_stats.tx_drops;
} while (u64_stats_fetch_retry(&adapter->syncp, start));
- stats->rx_dropped = rx_drops;
+ stats->rx_dropped = rx_drops + total_xdp_rx_drops;
stats->tx_dropped = tx_drops;
stats->multicast = 0;
--
2.40.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 00/11] ENA driver XDP changes
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (10 preceding siblings ...)
2024-01-01 19:08 ` [PATCH v2 net-next 11/11] net: ena: Take xdp packets stats into account in ena_get_stats64() darinzon
@ 2024-01-02 18:08 ` Jakub Kicinski
2024-01-03 7:08 ` Arinzon, David
2024-01-04 2:10 ` patchwork-bot+netdevbpf
12 siblings, 1 reply; 18+ messages in thread
From: Jakub Kicinski @ 2024-01-02 18:08 UTC (permalink / raw)
To: darinzon
Cc: David Miller, netdev, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
On Mon, 1 Jan 2024 19:08:44 +0000 darinzon@amazon.com wrote:
> Changes in v2:
> - Moved changes to right commits in order to avoid compilation errors
Please read:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#tl-dr
--
pv-bot: 24h
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v2 net-next 00/11] ENA driver XDP changes
2024-01-02 18:08 ` [PATCH v2 net-next 00/11] ENA driver XDP changes Jakub Kicinski
@ 2024-01-03 7:08 ` Arinzon, David
2024-01-03 22:18 ` Jakub Kicinski
0 siblings, 1 reply; 18+ messages in thread
From: Arinzon, David @ 2024-01-03 7:08 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David Miller, netdev@vger.kernel.org, Woodhouse, David,
Machulsky, Zorik, Matushevsky, Alexander, Bshara, Saeed,
Wilson, Matt, Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel,
Saidi, Ali, Herrenschmidt, Benjamin, Kiyanovski, Arthur,
Dagan, Noam, Agroskin, Shay, Itzko, Shahar, Abboud, Osama,
Ostrovsky, Evgeny, Tabachnik, Ofir
> On Mon, 1 Jan 2024 19:08:44 +0000 darinzon@amazon.com wrote:
> > Changes in v2:
> > - Moved changes to right commits in order to avoid compilation errors
>
> Please read:
>
> https://www.kernel.org/doc/html/next/process/maintainer-
> netdev.html#tl-dr
> --
> pv-bot: 24h
Apologies, I've noticed the failures in patchwork and decided to act quickly.
Thank you for the guidelines link.
Shall I resend v3 after the waiting time?
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 00/11] ENA driver XDP changes
2024-01-03 7:08 ` Arinzon, David
@ 2024-01-03 22:18 ` Jakub Kicinski
0 siblings, 0 replies; 18+ messages in thread
From: Jakub Kicinski @ 2024-01-03 22:18 UTC (permalink / raw)
To: Arinzon, David
Cc: David Miller, netdev@vger.kernel.org, Woodhouse, David,
Machulsky, Zorik, Matushevsky, Alexander, Bshara, Saeed,
Wilson, Matt, Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel,
Saidi, Ali, Herrenschmidt, Benjamin, Kiyanovski, Arthur,
Dagan, Noam, Agroskin, Shay, Itzko, Shahar, Abboud, Osama,
Ostrovsky, Evgeny, Tabachnik, Ofir
On Wed, 3 Jan 2024 07:08:02 +0000 Arinzon, David wrote:
> Apologies, I've noticed the failures in patchwork and decided to act quickly.
> Thank you for the guidelines link.
>
> Shall I resend v3 after the waiting time?
No need, just a note for future submissions.
I'll get to reviewing the code itself later today, fingers crossed,
and then we'll see if v3 is in order :)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 07/11] net: ena: Refactor napi functions
2024-01-01 19:08 ` [PATCH v2 net-next 07/11] net: ena: Refactor napi functions darinzon
@ 2024-01-04 2:00 ` Jakub Kicinski
2024-01-04 6:49 ` Arinzon, David
0 siblings, 1 reply; 18+ messages in thread
From: Jakub Kicinski @ 2024-01-04 2:00 UTC (permalink / raw)
To: darinzon
Cc: David Miller, netdev, Woodhouse, David, Machulsky, Zorik,
Matushevsky, Alexander, Saeed Bshara, Wilson, Matt,
Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel, Saidi, Ali,
Herrenschmidt, Benjamin, Kiyanovski, Arthur, Dagan, Noam,
Agroskin, Shay, Itzko, Shahar, Abboud, Osama, Ostrovsky, Evgeny,
Tabachnik, Ofir
On Mon, 1 Jan 2024 19:08:51 +0000 darinzon@amazon.com wrote:
> - xdp_work_done = ena_clean_xdp_irq(tx_ring, xdp_budget);
> + work_done = ena_clean_xdp_irq(tx_ring, budget);
Not related to this series, but please make sure that if budget is
0 you do *no* XDP processing, Rx or Tx. XDP expects to run in softirq
context, when budget is 0 we may be in hard IRQ.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 00/11] ENA driver XDP changes
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
` (11 preceding siblings ...)
2024-01-02 18:08 ` [PATCH v2 net-next 00/11] ENA driver XDP changes Jakub Kicinski
@ 2024-01-04 2:10 ` patchwork-bot+netdevbpf
12 siblings, 0 replies; 18+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-01-04 2:10 UTC (permalink / raw)
To: Arinzon, David
Cc: davem, kuba, netdev, dwmw, zorik, matua, saeedb, msw, aliguori,
nafea, netanel, alisaidi, benh, akiyano, ndagan, shayagr, itzko,
osamaabb, evostrov, ofirt
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 1 Jan 2024 19:08:44 +0000 you wrote:
> From: David Arinzon <darinzon@amazon.com>
>
> This patchset contains multiple XDP-related changes
> in the ENA driver, including moving the XDP code to
> dedicated files.
>
> Changes in v2:
> - Moved changes to right commits in order to avoid compilation errors
>
> [...]
Here is the summary with links:
- [v2,net-next,01/11] net: ena: Move XDP code to its new files
https://git.kernel.org/netdev/net-next/c/d000574d0287
- [v2,net-next,02/11] net: ena: Pass ena_adapter instead of net_device to ena_xmit_common()
https://git.kernel.org/netdev/net-next/c/39a044f4dcfe
- [v2,net-next,03/11] net: ena: Put orthogonal fields in ena_tx_buffer in a union
https://git.kernel.org/netdev/net-next/c/009b387659d3
- [v2,net-next,04/11] net: ena: Introduce total_tx_size field in ena_tx_buffer struct
https://git.kernel.org/netdev/net-next/c/23ec97498026
- [v2,net-next,05/11] net: ena: Use tx_ring instead of xdp_ring for XDP channel TX
https://git.kernel.org/netdev/net-next/c/911a8c960110
- [v2,net-next,06/11] net: ena: Don't check if XDP program is loaded in ena_xdp_execute()
https://git.kernel.org/netdev/net-next/c/436c79358595
- [v2,net-next,07/11] net: ena: Refactor napi functions
https://git.kernel.org/netdev/net-next/c/b626fd9627d4
- [v2,net-next,08/11] net: ena: Add more debug prints to XDP related function
https://git.kernel.org/netdev/net-next/c/2b02e332c151
- [v2,net-next,09/11] net: ena: Always register RX queue info
https://git.kernel.org/netdev/net-next/c/ea5c460023aa
- [v2,net-next,10/11] net: ena: Make queue stats code cleaner by removing the if block
https://git.kernel.org/netdev/net-next/c/4f28e789be76
- [v2,net-next,11/11] net: ena: Take xdp packets stats into account in ena_get_stats64()
https://git.kernel.org/netdev/net-next/c/782345d24874
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v2 net-next 07/11] net: ena: Refactor napi functions
2024-01-04 2:00 ` Jakub Kicinski
@ 2024-01-04 6:49 ` Arinzon, David
0 siblings, 0 replies; 18+ messages in thread
From: Arinzon, David @ 2024-01-04 6:49 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David Miller, netdev@vger.kernel.org, Woodhouse, David,
Machulsky, Zorik, Matushevsky, Alexander, Bshara, Saeed,
Wilson, Matt, Liguori, Anthony, Bshara, Nafea, Belgazal, Netanel,
Saidi, Ali, Herrenschmidt, Benjamin, Kiyanovski, Arthur,
Dagan, Noam, Agroskin, Shay, Itzko, Shahar, Abboud, Osama,
Ostrovsky, Evgeny, Tabachnik, Ofir
> On Mon, 1 Jan 2024 19:08:51 +0000 darinzon@amazon.com wrote:
> > - xdp_work_done = ena_clean_xdp_irq(tx_ring, xdp_budget);
> > + work_done = ena_clean_xdp_irq(tx_ring, budget);
>
> Not related to this series, but please make sure that if budget is
> 0 you do *no* XDP processing, Rx or Tx. XDP expects to run in softirq
> context, when budget is 0 we may be in hard IRQ.
Thank you for the feedback, Jakub, we will look into it and will make the needed changes.
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2024-01-04 6:49 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-01 19:08 [PATCH v2 net-next 00/11] ENA driver XDP changes darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 01/11] net: ena: Move XDP code to its new files darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 02/11] net: ena: Pass ena_adapter instead of net_device to ena_xmit_common() darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 03/11] net: ena: Put orthogonal fields in ena_tx_buffer in a union darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 04/11] net: ena: Introduce total_tx_size field in ena_tx_buffer struct darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 05/11] net: ena: Use tx_ring instead of xdp_ring for XDP channel TX darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 06/11] net: ena: Don't check if XDP program is loaded in ena_xdp_execute() darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 07/11] net: ena: Refactor napi functions darinzon
2024-01-04 2:00 ` Jakub Kicinski
2024-01-04 6:49 ` Arinzon, David
2024-01-01 19:08 ` [PATCH v2 net-next 08/11] net: ena: Add more debug prints to XDP related function darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 09/11] net: ena: Always register RX queue info darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 10/11] net: ena: Make queue stats code cleaner by removing the if block darinzon
2024-01-01 19:08 ` [PATCH v2 net-next 11/11] net: ena: Take xdp packets stats into account in ena_get_stats64() darinzon
2024-01-02 18:08 ` [PATCH v2 net-next 00/11] ENA driver XDP changes Jakub Kicinski
2024-01-03 7:08 ` Arinzon, David
2024-01-03 22:18 ` Jakub Kicinski
2024-01-04 2:10 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).