[ena] Limit submission queue fill level to completion queue size

The CREATE_CQ command is permitted to return a size smaller than
requested, which could leave us in a situation where the completion
queue could overflow.

Avoid overflow by limiting the submission queue fill level to the
actual size of the completion queue.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/732/head
Michael Brown 2022-08-26 14:13:52 +01:00
parent c5af41a6f5
commit 856ffe000e
2 changed files with 11 additions and 4 deletions

View File

@ -391,11 +391,16 @@ static int ena_create_sq ( struct ena_nic *ena, struct ena_sq *sq,
sq->prod = 0;
sq->phase = ENA_SQE_PHASE;
DBGC ( ena, "ENA %p %s SQ%d at [%08lx,%08lx) db +%04x CQ%d\n",
/* Calculate fill level */
sq->fill = sq->count;
if ( sq->fill > cq->actual )
sq->fill = cq->actual;
DBGC ( ena, "ENA %p %s SQ%d at [%08lx,%08lx) fill %d db +%04x CQ%d\n",
ena, ena_direction ( sq->direction ), sq->id,
virt_to_phys ( sq->sqe.raw ),
( virt_to_phys ( sq->sqe.raw ) + sq->len ),
sq->doorbell, cq->id );
sq->fill, sq->doorbell, cq->id );
return 0;
err_admin:
@ -658,7 +663,7 @@ static void ena_refill_rx ( struct net_device *netdev ) {
unsigned int refilled = 0;
/* Refill queue */
while ( ( ena->rx.sq.prod - ena->rx.cq.cons ) < ENA_RX_COUNT ) {
while ( ( ena->rx.sq.prod - ena->rx.cq.cons ) < ena->rx.sq.fill ) {
/* Allocate I/O buffer */
iobuf = alloc_iob ( len );
@ -783,7 +788,7 @@ static int ena_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
size_t len;
/* Get next submission queue entry */
if ( ( ena->tx.sq.prod - ena->tx.cq.cons ) >= ENA_TX_COUNT ) {
if ( ( ena->tx.sq.prod - ena->tx.cq.cons ) >= ena->tx.sq.fill ) {
DBGC ( ena, "ENA %p out of transmit descriptors\n", ena );
return -ENOBUFS;
}

View File

@ -496,6 +496,8 @@ struct ena_sq {
uint8_t direction;
/** Number of entries */
uint8_t count;
/** Fill level (limited to completion queue size) */
uint8_t fill;
};
/**