提交 8159ecab 编写于 作者: A Anssi Hannula 提交者: David S. Miller

net: macb: fix dropped RX frames due to a race

Bit RX_USED set to 0 in the address field allows the controller to write
data to the receive buffer descriptor.

The driver does not ensure the ctrl field is ready (cleared) when the
controller sees the RX_USED=0 written by the driver. The ctrl field might
only be cleared after the controller has already updated it according to
a newly received frame, causing the frame to be discarded in gem_rx() due
to unexpected ctrl field contents.

A message is logged when the above scenario occurs:

  macb ff0b0000.ethernet eth0: not whole frame pointed by descriptor

Fix the issue by ensuring that when the controller sees RX_USED=0 the
ctrl field is already cleared.

This issue was observed on a ZynqMP based system.

Fixes: 4df95131 ("net/macb: change RX path for GEM")
Signed-off-by: NAnssi Hannula <anssi.hannula@bitwise.fi>
Tested-by: NClaudiu Beznea <claudiu.beznea@microchip.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 e100a897
......@@ -934,14 +934,19 @@ static void gem_rx_refill(struct macb_queue *queue)
if (entry == bp->rx_ring_size - 1)
paddr |= MACB_BIT(RX_WRAP);
macb_set_addr(bp, desc, paddr);
desc->ctrl = 0;
/* Setting addr clears RX_USED and allows reception,
* make sure ctrl is cleared first to avoid a race.
*/
dma_wmb();
macb_set_addr(bp, desc, paddr);
/* properly align Ethernet header */
skb_reserve(skb, NET_IP_ALIGN);
} else {
desc->addr &= ~MACB_BIT(RX_USED);
desc->ctrl = 0;
dma_wmb();
desc->addr &= ~MACB_BIT(RX_USED);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册