mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 04:23:03 +02:00
net: ethernet: cortina: Count RX descriptors for freeq refill
The software free queue provides one buffer fragment for every descriptor
moved to an RX queue. The refill heuristic instead advances by NAPI work,
which counts frames. A fragmented or discarded frame can consume several
queue entries while adding only one to the refill count.
Count the RX descriptors as they are consumed and report that separately
from NAPI work. Use the descriptor count to drive free queue refills.
Fixes: 4d5ae32f5e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Assisted-by: LLM
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-5-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
6520198c43
commit
e89e88ad41
|
|
@ -1440,7 +1440,8 @@ static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port,
|
|||
return skb;
|
||||
}
|
||||
|
||||
static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
|
||||
static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget,
|
||||
unsigned int *freeq_consumed)
|
||||
{
|
||||
struct gemini_ethernet_port *port = netdev_priv(netdev);
|
||||
unsigned short m = (1 << port->rxq_order) - 1;
|
||||
|
|
@ -1448,6 +1449,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
|
|||
void __iomem *ptr_reg = port->rxq_rwptr;
|
||||
unsigned int frag_nr = port->rx_frag_nr;
|
||||
struct sk_buff *skb = port->rx_skb;
|
||||
unsigned int consumed = 0;
|
||||
unsigned int frame_len, frag_len;
|
||||
struct gmac_rxdesc *rx = NULL;
|
||||
struct gmac_queue_page *gpage;
|
||||
|
|
@ -1483,6 +1485,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
|
|||
|
||||
r++;
|
||||
r &= m;
|
||||
consumed++;
|
||||
|
||||
frag_len = word0.bits.buffer_size;
|
||||
frame_len = word1.bits.byte_count;
|
||||
|
|
@ -1575,6 +1578,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
|
|||
port->rx_skb = skb;
|
||||
port->rx_frag_nr = frag_nr;
|
||||
port->rx_dropping = dropping;
|
||||
*freeq_consumed = consumed;
|
||||
writew(r, ptr_reg);
|
||||
return received;
|
||||
}
|
||||
|
|
@ -1584,18 +1588,19 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget)
|
|||
struct gemini_ethernet_port *port = netdev_priv(napi->dev);
|
||||
struct gemini_ethernet *geth = port->geth;
|
||||
unsigned int freeq_threshold;
|
||||
unsigned int freeq_consumed;
|
||||
unsigned int received;
|
||||
|
||||
freeq_threshold = 1 << (geth->freeq_order - 1);
|
||||
u64_stats_update_begin(&port->rx_stats_syncp);
|
||||
|
||||
received = gmac_rx(napi->dev, budget);
|
||||
received = gmac_rx(napi->dev, budget, &freeq_consumed);
|
||||
if (received < budget)
|
||||
++port->rx_napi_exits;
|
||||
|
||||
u64_stats_update_end(&port->rx_stats_syncp);
|
||||
|
||||
port->freeq_refill += received;
|
||||
port->freeq_refill += freeq_consumed;
|
||||
if (port->freeq_refill > freeq_threshold) {
|
||||
port->freeq_refill -= freeq_threshold;
|
||||
geth_fill_freeq(geth, true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user