Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'ena-next'



Netanel Belgazal says:

====================
update ENA driver to version 1.5.0

This patchset contains two changes:
* Add a robust mechanism for detection of stuck Rx/Tx rings due to
  missed or misrouted MSI-X
* Increase the driver version to 1.5.0
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents acfbf3ca 70097445
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -504,3 +504,14 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id)

	return 0;
}

bool ena_com_cq_empty(struct ena_com_io_cq *io_cq)
{
	struct ena_eth_io_rx_cdesc_base *cdesc;

	cdesc = ena_com_get_next_rx_cdesc(io_cq);
	if (cdesc)
		return false;
	else
		return true;
}
+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ int ena_com_add_single_rx_desc(struct ena_com_io_sq *io_sq,

int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id);

bool ena_com_cq_empty(struct ena_com_io_cq *io_cq);

static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq,
				       struct ena_eth_io_intr_reg *intr_reg)
{
+61 −7
Original line number Diff line number Diff line
@@ -158,6 +158,8 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
	ring->per_napi_packets = 0;
	ring->per_napi_bytes = 0;
	ring->cpu = 0;
	ring->first_interrupt = false;
	ring->no_interrupt_event_cnt = 0;
	u64_stats_init(&ring->syncp);
}

@@ -1274,6 +1276,9 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
{
	struct ena_napi *ena_napi = data;

	ena_napi->tx_ring->first_interrupt = true;
	ena_napi->rx_ring->first_interrupt = true;

	napi_schedule_irqoff(&ena_napi->napi);

	return IRQ_HANDLED;
@@ -2648,7 +2653,31 @@ static void ena_fw_reset_device(struct work_struct *work)
	rtnl_unlock();
}

static int check_missing_comp_in_queue(struct ena_adapter *adapter,
static int check_for_rx_interrupt_queue(struct ena_adapter *adapter,
					struct ena_ring *rx_ring)
{
	if (likely(rx_ring->first_interrupt))
		return 0;

	if (ena_com_cq_empty(rx_ring->ena_com_io_cq))
		return 0;

	rx_ring->no_interrupt_event_cnt++;

	if (rx_ring->no_interrupt_event_cnt == ENA_MAX_NO_INTERRUPT_ITERATIONS) {
		netif_err(adapter, rx_err, adapter->netdev,
			  "Potential MSIX issue on Rx side Queue = %d. Reset the device\n",
			  rx_ring->qid);
		adapter->reset_reason = ENA_REGS_RESET_MISS_INTERRUPT;
		smp_mb__before_atomic();
		set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
		return -EIO;
	}

	return 0;
}

static int check_missing_comp_in_tx_queue(struct ena_adapter *adapter,
					  struct ena_ring *tx_ring)
{
	struct ena_tx_buffer *tx_buf;
@@ -2659,8 +2688,27 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
	for (i = 0; i < tx_ring->ring_size; i++) {
		tx_buf = &tx_ring->tx_buffer_info[i];
		last_jiffies = tx_buf->last_jiffies;
		if (unlikely(last_jiffies &&
			     time_is_before_jiffies(last_jiffies + adapter->missing_tx_completion_to))) {

		if (last_jiffies == 0)
			/* no pending Tx at this location */
			continue;

		if (unlikely(!tx_ring->first_interrupt && time_is_before_jiffies(last_jiffies +
			     2 * adapter->missing_tx_completion_to))) {
			/* If after graceful period interrupt is still not
			 * received, we schedule a reset
			 */
			netif_err(adapter, tx_err, adapter->netdev,
				  "Potential MSIX issue on Tx side Queue = %d. Reset the device\n",
				  tx_ring->qid);
			adapter->reset_reason = ENA_REGS_RESET_MISS_INTERRUPT;
			smp_mb__before_atomic();
			set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
			return -EIO;
		}

		if (unlikely(time_is_before_jiffies(last_jiffies +
				adapter->missing_tx_completion_to))) {
			if (!tx_buf->print_once)
				netif_notice(adapter, tx_err, adapter->netdev,
					     "Found a Tx that wasn't completed on time, qid %d, index %d.\n",
@@ -2689,9 +2737,10 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
	return rc;
}

static void check_for_missing_tx_completions(struct ena_adapter *adapter)
static void check_for_missing_completions(struct ena_adapter *adapter)
{
	struct ena_ring *tx_ring;
	struct ena_ring *rx_ring;
	int i, budget, rc;

	/* Make sure the driver doesn't turn the device in other process */
@@ -2710,8 +2759,13 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)

	for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
		tx_ring = &adapter->tx_ring[i];
		rx_ring = &adapter->rx_ring[i];

		rc = check_missing_comp_in_tx_queue(adapter, tx_ring);
		if (unlikely(rc))
			return;

		rc = check_missing_comp_in_queue(adapter, tx_ring);
		rc = check_for_rx_interrupt_queue(adapter, rx_ring);
		if (unlikely(rc))
			return;

@@ -2870,7 +2924,7 @@ static void ena_timer_service(struct timer_list *t)

	check_for_admin_com_state(adapter);

	check_for_missing_tx_completions(adapter);
	check_for_missing_completions(adapter);

	check_for_empty_rx_ring(adapter);

+5 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@
#include "ena_eth_com.h"

#define DRV_MODULE_VER_MAJOR	1
#define DRV_MODULE_VER_MINOR	3
#define DRV_MODULE_VER_MINOR	5
#define DRV_MODULE_VER_SUBMINOR 0

#define DRV_MODULE_NAME		"ena"
@@ -122,6 +122,7 @@
 * We wait for 6 sec just to be on the safe side.
 */
#define ENA_DEVICE_KALIVE_TIMEOUT	(6 * HZ)
#define ENA_MAX_NO_INTERRUPT_ITERATIONS 3

#define ENA_MMIO_DISABLE_REG_READ	BIT(0)

@@ -236,6 +237,9 @@ struct ena_ring {
	/* The maximum header length the device can handle */
	u8 tx_max_header_size;

	bool first_interrupt;
	u16 no_interrupt_event_cnt;

	/* cpu for TPH */
	int cpu;
	 /* number of tx/rx_buffer_info's entries */
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ enum ena_regs_reset_reason_types {
	ENA_REGS_RESET_USER_TRIGGER		= 12,

	ENA_REGS_RESET_GENERIC			= 13,

	ENA_REGS_RESET_MISS_INTERRUPT		= 14,
};

/* ena_registers offsets */