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 | u64_stats_update_begin(&port->rx_stats_syncp); | 1581 | u64_stats_update_begin(&port->rx_stats_syncp); |
| 1582 | 1582 | ||
| 1583 | received = gmac_rx(napi->dev, budget); | 1583 | received = gmac_rx(napi->dev, budget); |
| 1584 | if (received < 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); | ||
| 1588 | ++port->rx_napi_exits; | 1585 | ++port->rx_napi_exits; |
| 1589 | } | 1586 | |
| 1587 | u64_stats_update_end(&port->rx_stats_syncp); | ||
| 1590 | 1588 | ||
| 1591 | port->freeq_refill += received; | 1589 | port->freeq_refill += received; |
| 1592 | if (port->freeq_refill > freeq_threshold) { | 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 | geth_fill_freeq(geth, true); | 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 | return received; | 1598 | return received; |
| 1599 | } | 1599 | } |
| 1600 | 1600 | ||