Commit 548c4940 authored by Sameeh Jubran's avatar Sameeh Jubran Committed by David S. Miller
Browse files

net: ena: Implement XDP_TX action



This commit implements the XDP_TX action in the ena driver. We allocate
separate tx queues for the XDP_TX. We currently allow xdp only when
there is enough queues to allocate for xdp.

Signed-off-by: default avatarSameeh Jubran <sameehj@amazon.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 838c93dc
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);
+655 −183

File changed.

Preview size limit exceeded, changes collapsed.

+43 −2
Original line number Diff line number Diff line
@@ -152,6 +152,9 @@
#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;
@@ -165,6 +168,7 @@ struct ena_napi {
	struct napi_struct napi ____cacheline_aligned;
	struct ena_ring *tx_ring;
	struct ena_ring *rx_ring;
	struct ena_ring *xdp_ring;
	u32 qid;
	struct dim dim;
};
@@ -190,6 +194,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;

@@ -394,6 +409,8 @@ struct ena_adapter {
	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);
@@ -410,6 +427,17 @@ 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;
@@ -420,9 +448,22 @@ static inline bool ena_xdp_present_ring(struct ena_ring *ring)
	return !!ring->xdp_bpf_prog;
}

static inline bool ena_xdp_allowed(struct ena_adapter *adapter)
static inline int ena_xdp_legal_queue_count(struct ena_adapter *adapter,
					    u32 queues)
{
	return adapter->netdev->mtu <= ENA_XDP_MAX_MTU;
	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) */