]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[ena] Limit submission queue fill level to completion queue size
authorMichael Brown <mcb30@ipxe.org>
Fri, 26 Aug 2022 13:13:52 +0000 (14:13 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 26 Aug 2022 18:37:54 +0000 (19:37 +0100)
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>
src/drivers/net/ena.c
src/drivers/net/ena.h

index 85da1c090c63bb9e901855c6bcc79cfbfa48dc41..9f52a658e35778ff1467fdf9ce305cfdc684cec7 100644 (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;
        }
index 676c5b87876b0f10fe67227dcab989afd7effad9..2832b67e56bbb14da119fe0abf1882eed67519c1 100644 (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;
 };
 
 /**