napi_complete_done() releases ownership of the NAPI instance, but the Gemini poll keeps the RX statistics writer section open and updates the free queue after calling it. A new poll can therefore start while the old writer is still active. Finish the statistics and free queue updates before releasing ownership. Only re-enable RX interrupts when napi_complete_done() reports successful completion.
Unified · Split
| @@ -1581,12 +1581,10 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget) · 1580 unmodified lines | ||
| 1581 | 1581 | u64_stats_update_begin(&port->rx_stats_syncp); |
| 1582 | 1582 | |
| 1583 | 1583 | received = gmac_rx(napi->dev, budget); |
| 1584 | − if (received < budget) { | |
| 1585 | − napi_gro_flush(napi, false); | |
| 1586 | − napi_complete_done(napi, received); | |
| 1587 | − gmac_enable_rx_irq(napi->dev, 1); | |
| 1584 | + if (received < budget) | |
| 1588 | 1585 | ++port->rx_napi_exits; |
| 1589 | − } | |
| 1586 | + | |
| 1587 | + u64_stats_update_end(&port->rx_stats_syncp); | |
| 1590 | 1588 | |
| 1591 | 1589 | port->freeq_refill += received; |
| 1592 | 1590 | if (port->freeq_refill > freeq_threshold) { |
| @@ -1594,7 +1592,9 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget) · 1 unmodified line | ||
| 1594 | 1592 | geth_fill_freeq(geth, true); |
| 1595 | 1593 | } |
| 1596 | 1594 | |
| 1597 | − u64_stats_update_end(&port->rx_stats_syncp); | |
| 1595 | + if (received < budget && napi_complete_done(napi, received)) | |
| 1596 | + gmac_enable_rx_irq(napi->dev, 1); | |
| 1597 | + | |
| 1598 | 1598 | return received; |
| 1599 | 1599 | } |
| 1600 | 1600 | |