Message ID | 1484563521-12009-1-git-send-email-horms+renesas@verge.net.au |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
On 01/16/2017 01:45 PM, Simon Horman wrote: > From: Masaru Nagai <masaru.nagai.vx@renesas.com> > > Due to alignment requirements of the hardware transmissions are split into > two DMA descriptors, a small padding descriptor of 0 - 3 bytes in length > followed by a descriptor for rest of the packet. > > In the case of IP packets the first descriptor will never be zero due to > the way that the stack aligns buffers for IP packets. However, for non-IP > packets it may be zero. > > In that case it has been reported that timeouts occur, presumably because > transmission stops at the first zero-length DMA descriptor and thus the > packet is not transmitted. However, in my environment a BUG is triggered as > follows: [...] > Fixes: 2f45d1902acf ("ravb: minimize TX data copying") > Signed-off-by: Masaru Nagai <masaru.nagai.vx@renesas.com > Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> MBR, Sergei
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Date: Mon, 16 Jan 2017 16:01:49 +0300 > On 01/16/2017 01:45 PM, Simon Horman wrote: > >> From: Masaru Nagai <masaru.nagai.vx@renesas.com> >> >> Due to alignment requirements of the hardware transmissions are split >> into >> two DMA descriptors, a small padding descriptor of 0 - 3 bytes in >> length >> followed by a descriptor for rest of the packet. >> >> In the case of IP packets the first descriptor will never be zero due >> to >> the way that the stack aligns buffers for IP packets. However, for >> non-IP >> packets it may be zero. >> >> In that case it has been reported that timeouts occur, presumably >> because >> transmission stops at the first zero-length DMA descriptor and thus >> the >> packet is not transmitted. However, in my environment a BUG is >> triggered as >> follows: > [...] > >> Fixes: 2f45d1902acf ("ravb: minimize TX data copying") >> Signed-off-by: Masaru Nagai <masaru.nagai.vx@renesas.com >> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> > > Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Applied and queued up for -stable, thanks.
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 5e5ad978eab9..89ac1e3f6175 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1504,6 +1504,19 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) buffer = PTR_ALIGN(priv->tx_align[q], DPTR_ALIGN) + entry / NUM_TX_DESC * DPTR_ALIGN; len = PTR_ALIGN(skb->data, DPTR_ALIGN) - skb->data; + /* Zero length DMA descriptors are problematic as they seem to + * terminate DMA transfers. Avoid them by simply using a length of + * DPTR_ALIGN (4) when skb data is aligned to DPTR_ALIGN. + * + * As skb is guaranteed to have at least ETH_ZLEN (60) bytes of + * data by the call to skb_put_padto() above this is safe with + * respect to both the length of the first DMA descriptor (len) + * overflowing the available data and the length of the second DMA + * descriptor (skb->len - len) being negative. + */ + if (len == 0) + len = DPTR_ALIGN; + memcpy(buffer, skb->data, len); dma_addr = dma_map_single(ndev->dev.parent, buffer, len, DMA_TO_DEVICE); if (dma_mapping_error(ndev->dev.parent, dma_addr))