Skip to content

Commit b2e8468

Browse files
committed
[ena] Limit receive queue size to work around hardware bugs
Commit a801244 ("[ena] Increase receive ring size to 128 entries") increased the receive ring size to 128 entries (while leaving the fill level at 16), since using a smaller receive ring caused unexplained failures on some instance types. The original hardware bug that resulted in that commit seems to have been fixed: experiments suggest that the original failure (observed on a c6i.large instance in eu-west-2) will no longer reproduce when using a receive ring containing only 16 entries (as was the case prior to that commit). Newer generations of the ENA hardware (observed on an m8i.large instance in eu-south-2) seem to have a new and exciting hardware bug: these instance types appear to use a hash of the received packet header to determine which portion of the (out-of-order) receive ring to use. If that portion of the ring happens to be empty (e.g. because only 32 entries of the 128-entry ring are filled at any one time), then the packet will be silently dropped. Work around this new hardware bug by reducing the receive ring size down to the current fill level of 32 entries. This appears to work on all current instance types (but has not been exhaustively tested). Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent 846c505 commit b2e8468

2 files changed

Lines changed: 5 additions & 12 deletions

File tree

src/drivers/net/ena.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ static int ena_create_sq ( struct ena_nic *ena, struct ena_sq *sq,
494494
sq->phase = ENA_SQE_PHASE;
495495

496496
/* Calculate fill level */
497-
sq->fill = sq->max;
497+
sq->fill = sq->count;
498498
if ( sq->fill > cq->actual )
499499
sq->fill = cq->actual;
500500

@@ -1358,11 +1358,11 @@ static int ena_probe ( struct pci_device *pci ) {
13581358
ena->acq.phase = ENA_ACQ_PHASE;
13591359
ena_cq_init ( &ena->tx.cq, ENA_TX_COUNT,
13601360
sizeof ( ena->tx.cq.cqe.tx[0] ) );
1361-
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT, ENA_TX_COUNT,
1361+
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT,
13621362
sizeof ( ena->tx.sq.sqe.tx[0] ), ena->tx_ids );
13631363
ena_cq_init ( &ena->rx.cq, ENA_RX_COUNT,
13641364
sizeof ( ena->rx.cq.cqe.rx[0] ) );
1365-
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT, ENA_RX_FILL,
1365+
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT,
13661366
sizeof ( ena->rx.sq.sqe.rx[0] ), ena->rx_ids );
13671367

13681368
/* Fix up PCI device */

src/drivers/net/ena.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
3737
#define ENA_TX_COUNT 32
3838

3939
/** Number of receive queue entries */
40-
#define ENA_RX_COUNT 128
41-
42-
/** Receive queue maximum fill level */
43-
#define ENA_RX_FILL 32
40+
#define ENA_RX_COUNT 32
4441

4542
/** Base address low register offset */
4643
#define ENA_BASE_LO 0x0
@@ -753,8 +750,6 @@ struct ena_sq {
753750
uint8_t direction;
754751
/** Number of entries */
755752
uint8_t count;
756-
/** Maximum fill level */
757-
uint8_t max;
758753
/** Fill level (limited to completion queue size) */
759754
uint8_t fill;
760755
/** Maximum inline header length */
@@ -767,19 +762,17 @@ struct ena_sq {
767762
* @v sq Submission queue
768763
* @v direction Direction
769764
* @v count Number of entries
770-
* @v max Maximum fill level
771765
* @v size Size of each entry
772766
* @v ids Buffer IDs
773767
*/
774768
static inline __attribute__ (( always_inline )) void
775769
ena_sq_init ( struct ena_sq *sq, unsigned int direction, unsigned int count,
776-
unsigned int max, size_t size, uint8_t *ids ) {
770+
size_t size, uint8_t *ids ) {
777771

778772
sq->len = ( count * size );
779773
sq->policy = ( ENA_SQ_HOST_MEMORY | ENA_SQ_CONTIGUOUS );
780774
sq->direction = direction;
781775
sq->count = count;
782-
sq->max = max;
783776
sq->ids = ids;
784777
}
785778

0 commit comments

Comments
 (0)