Commit 355979de authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'Introduce-XDP-to-ena'



Sameeh Jubran says:

====================
Introduce XDP to ena

This patchset includes 3 patches:
* XDP_DROP implementation
* XDP_TX implementation
* A fix for an issue which might occur due to the XDP_TX patch. I see fit
  to place it as a standalone patch for clarity.

Difference from v2:
* Fixed the usage of rx headroom (XDP_PACKET_HEADROOM)
* Aligned the page_offset of the packet when passing it to the stack
* Switched to using xdp_frame in xdp xmit queue
* Dropped the print for unsupported commands
* Cosmetic changes

Difference from RFC v1 (XDP_DROP patch):
* Initialized xdp.rxq pointer
* Updated max_mtu on attachment of xdp and removed the check from
  ena_change_mtu()
* Moved the xdp execution from ena_rx_skb() to ena_clean_rx_irq()
* Moved xdp buff (struct xdp_buff) from rx_ring to the local stack
* Started using netlink's extack mechanism to deliver error messages to
  the user
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents aabf23d1 913b0bfd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -744,7 +744,9 @@ static int ena_set_channels(struct net_device *netdev,
	struct ena_adapter *adapter = netdev_priv(netdev);
	u32 count = channels->combined_count;
	/* The check for max value is already done in ethtool */
	if (count < ENA_MIN_NUM_IO_QUEUES)
	if (count < ENA_MIN_NUM_IO_QUEUES ||
	    (ena_xdp_present(adapter) &&
	    !ena_xdp_legal_queue_count(adapter, channels->combined_count)))
		return -EINVAL;

	return ena_update_queue_count(adapter, count);
+813 −147

File changed.

Preview size limit exceeded, changes collapsed.

+73 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/bitops.h>
#include <linux/dim.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/inetdevice.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
@@ -142,6 +143,18 @@

#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)

#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;
@@ -155,6 +168,8 @@ struct ena_napi {
	struct napi_struct napi ____cacheline_aligned;
	struct ena_ring *tx_ring;
	struct ena_ring *rx_ring;
	struct ena_ring *xdp_ring;
	bool first_interrupt;
	u32 qid;
	struct dim dim;
};
@@ -180,6 +195,17 @@ 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;
	/* The rx page for the rx buffer that was received in rx and
	 * re transmitted on xdp tx queues as a result of XDP_TX action.
	 * We need to free the page once we finished cleaning the buffer in
	 * clean_xdp_irq()
	 */
	struct page *xdp_rx_page;

	/* Indicate if bufs[0] map the linear data of the skb. */
	u8 map_linear_data;

@@ -258,10 +284,13 @@ struct ena_ring {
	struct ena_adapter *adapter;
	struct ena_com_io_cq *ena_com_io_cq;
	struct ena_com_io_sq *ena_com_io_sq;
	struct bpf_prog *xdp_bpf_prog;
	struct xdp_rxq_info xdp_rxq;

	u16 next_to_use;
	u16 next_to_clean;
	u16 rx_copybreak;
	u16 rx_headroom;
	u16 qid;
	u16 mtu;
	u16 sgl_size;
@@ -379,6 +408,10 @@ struct ena_adapter {
	u32 last_monitored_tx_qid;

	enum ena_regs_reset_reason_types reset_reason;

	struct bpf_prog *xdp_bpf_prog;
	u32 xdp_first_ring;
	u32 xdp_num_queues;
};

void ena_set_ethtool_ops(struct net_device *netdev);
@@ -390,8 +423,48 @@ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf);
int ena_update_queue_sizes(struct ena_adapter *adapter,
			   u32 new_tx_size,
			   u32 new_rx_size);

int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count);

int ena_get_sset_count(struct net_device *netdev, int sset);

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_queues_present(struct ena_adapter *adapter)
{
	return adapter->xdp_first_ring != 0;
}

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 int 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;
}

#endif /* !(ENA_H) */