rtnet rt_igb I210 not working with ARM

Yann Le Chevoir yann.lechevoir at cae.com
Tue Mar 29 20:42:19 CEST 2022

> > I finally have something working with the patch bellow.
> > So:
> >     - pci=nomsi to have the irq counter incrementing.
> >     - dma_sync_single_for_device in igb_tx_map to have rt_igb sending
> >       good data.
> >
> > My questions:
> > What are your feeling about that?
> > Is dma_sync real-time? Is it a good fix/workaround?
> In the best case, it's just a barrier (but there is already a wmb()). In the worst
> case, Linux code is triggered that actually does more, e.g.
> because DMA is not cache-coherent. You will have to analyze what is actually
> done in that function on your platform.
> > Why do I need to add such a dma_sync with my arm SoC?
> >     - I suspect that this driver would work on a regular x86...
> >     - Can you tell if it works on other arm SoC?
> I don't think this was tried on ARM so far, but then the topic will actually be
> rather SoC-specific.

Maybe worth mentioning for those who face the same problem:
I did not go deeper with the DMA yet. I was happy with the tx performances.
But I faced a different issue with the rx, with 1 packets over 500 which was lost at high frequency.
I got to do a similar patch (dma_sync) for the rx. See below (tx + rx). That works for me and performances are validated.

--- a/kernel/drivers/net/drivers/igb/igb_main.c
+++ b/kernel/drivers/net/drivers/igb/igb_main.c
@@ -4143,6 +4143,7 @@ static void igb_tx_map(struct igb_ring *tx_ring,
 	 * We also need this memory barrier to make certain all of the
 	 * status bits have been updated before next_to_watch is written.
+	dma_sync_single_for_device(tx_ring->dev, dma, size, DMA_TO_DEVICE);
 	if (skb->xmit_stamp)
@@ -4764,13 +4765,19 @@ static struct rtskb *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
 	struct igb_rx_buffer *rx_buffer;
 	struct rtskb *skb;
+	dma_addr_t dma;
+	unsigned int size;
 	rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
 	skb = rx_buffer->skb;
+	dma = rtskb_data_dma_addr(skb, 0);
+	size = le16_to_cpu(rx_desc->wb.upper.length);
+	dma_sync_single_for_cpu(rx_ring->dev, dma, size, DMA_FROM_DEVICE);
 	/* pull the header of the skb in */
-	rtskb_put(skb, le16_to_cpu(rx_desc->wb.upper.length));
+	rtskb_put(skb, size);
 	rx_buffer->skb = NULL;
 	rx_buffer->dma = 0;

More information about the Xenomai mailing list