summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2016-05-03 16:38:53 +0200
committerSasha Levin <sasha.levin@oracle.com>2016-07-12 08:48:13 -0400
commit361d2edcb4bd07fa7b0b4758bbb020e121ebc840 (patch)
treee5f98741303b6f1ad15f73e8f96f36b7c2166339
parent3f6683aa55a4be9867b4128f396aa955b19db78b (diff)
downloadlwn-361d2edcb4bd07fa7b0b4758bbb020e121ebc840.tar.gz
lwn-361d2edcb4bd07fa7b0b4758bbb020e121ebc840.zip
net: fec: only clear a queue's work bit if the queue was emptied
[ Upstream commit 1c021bb717a70aaeaa4b25c91f43c2aeddd922de ] In the receive path a queue's work bit was cleared unconditionally even if fec_enet_rx_queue only read out a part of the available packets from the hardware. This resulted in not reading any packets in the next napi turn and so packets were delayed or lost. The obvious fix is to only clear a queue's bit when the queue was emptied. Fixes: 4d494cdc92b3 ("net: fec: change data structure to support multiqueue") Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Tested-by: Fugang Duan <fugang.duan@nxp.com> Acked-by: Fugang Duan <fugang.duan@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 96ba23e90111..2ee3c9537772 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1539,9 +1539,15 @@ fec_enet_rx(struct net_device *ndev, int budget)
struct fec_enet_private *fep = netdev_priv(ndev);
for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
- clear_bit(queue_id, &fep->work_rx);
- pkt_received += fec_enet_rx_queue(ndev,
+ int ret;
+
+ ret = fec_enet_rx_queue(ndev,
budget - pkt_received, queue_id);
+
+ if (ret < budget - pkt_received)
+ clear_bit(queue_id, &fep->work_rx);
+
+ pkt_received += ret;
}
return pkt_received;
}