UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Scholar wzab
Scholar
8,052 Views
Registered: ‎08-24-2011

AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

My experiments have shown, that to generate the interrupt (and call the completion callback), the AXI DMA must receive the tlast='1' during the transfer of particular dma_async_tx_descriptor.

 

It means, that if the AXI Stream data source transfers data in packets of dynamically changing length, I must allocate the descriptor for the maximum possible length of the packet, and after the callback is called, I should check the number of the really transferred bytes.

 

Unfortunately, I can't see any official method to do it.

There was a patch proposed adding the "transferred" field to the dma_async_tx_descriptor, however it was finally rejected, as it should be possible to check the number of not transferred bytes in the dma_tx_state structure accessible via dmaengine_tx_status. The final conclusion was, that the documentation should be updated to confirm, that the "residue" field in the "dma_tx_state" may be used to check the number of non-transferred bytes even after the transfer is completed.

However in the current Xilinx flavor of the Linux kernel, there is still information, that the residue field should be used only when the transfer is in the DMA_IN_PROGRESS or DMA_PAUSED state.

The same applies to the standard 4.4 version of the kernel and even for the newest 4.7 version of the kernel.

 

So the question is. How the driver should check the number of bytes transferred in a transfer described by the dma_async_tx_descriptor and finished by tlast='1' ?

 

With best regards,

Wojtek

 

12 Replies
Scholar wzab
Scholar
8,033 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

In the "AXI DMA Debug Guide" I have found the information (page 2):

 

If tlast occurrs before the number of bytes set in the length register, the SG engine updates the length
register with the actual number of bytes transferred and then starts working on the next descriptor as
the next packet is coming in.

 

There is even API defined to obtain the information about the actual number of transferred bytes:

 

The actual transfer length for receive could be smaller than the requested  transfer length. The hardware sets the actual transfer length in the completed BD. The API to retrieve the actual transfer length is XAxiDma_GetActualLength().

 

However the above apply to non-Linux API.

Is there equivalent function to get the actual number of transferred bytes available for Linux driver?

 

I have checked the approach with "dmaengine_tx_status" described in the previous post, and it seems that after the transfer is completed, the "residue" field in the "tx_state" is set to 0 regardless of the number of actually transferred bytes.

 

Regards,

Wojtek

 

0 Kudos
Scholar wzab
Scholar
8,023 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

Implementation of the xilinx_dma_tx_status  correctly fills the "residue" field only if the transfer status is NOT DMA_COMPLETE. So now the question is:

How can I keep my transfer in a state in which I can read the "residue"?

 

Regards,

Wojtek

0 Kudos
Scholar wzab
Scholar
7,977 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

I have tried to add the patch shown below, so that the residue is calculated even for completed transfer, but unfortunately it doesn't work. Probably at the moment when the callback is executed, the list of segments for the descriptor is already empty.

 

 

diff --git a/linux-xilinx-v2016.2/drivers/dma/xilinx/xilinx_dma.c b/linux-xilinx-v2016.2/drivers/dma/xilinx/xilinx_dma.c
index 47c1641..99cb039 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -558,7 +558,7 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
 	u32 residue = 0;
 
 	ret = dma_cookie_status(dchan, cookie, txstate);
-	if (ret == DMA_COMPLETE || !txstate)
+	if  (!txstate)
 		return ret;
 
 	desc = list_last_entry(&chan->active_list,

 

Regards,

Wojtek

0 Kudos
Scholar vanmierlo
Scholar
7,906 Views
Registered: ‎06-10-2008

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

I discussed this before in a xilinx issue on github, but unfortunately all issues seem to have been taken offline.

warning: dead link: https://github.com/Xilinx/linux-xlnx/issues/20

 

 

I would have to search if I still have the patch that I proposed there.

0 Kudos
Scholar wzab
Scholar
7,853 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

I'd be glad to see your patches.

However it seems, that the problem is not Xilinx specific.

It is rather related to the whole dmaengine infrastructure.

 

 

0 Kudos
Scholar vanmierlo
Scholar
7,760 Views
Registered: ‎06-10-2008

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

I think this was the patch that I proposed on a 3.17 kernel. Beware, the 4.x kernel has quite some changes for dma.

Visitor andrei_hres
Visitor
6,905 Views
Registered: ‎06-18-2015

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

Hi.

Have you found answer for question about transfer length?

0 Kudos
Visitor slocke
Visitor
3,370 Views
Registered: ‎01-26-2018

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

Has this really not been fixed yet? This severely limits the real-world use of the Linux AXI DMA driver.

0 Kudos
Scholar wzab
Scholar
3,288 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

As I can see, in 2017.4 still the length is filled only when the status is not DMA_COMPLETE: https://github.com/Xilinx/linux-xlnx/blob/xilinx-v2017.4/drivers/dma/xilinx/xilinx_dma.c#L955

 

As a workaround, I have finally developed a solution based on DataMover controlled by FIFO.

It is described in
http://dx.doi.org/10.1117/12.2280937

The presentation is available at
https://indico.gsi.de/event/6233/contribution/1/material/slides/0.pdf

Sources of that particular DMA solution are available in https://github.com/wzab/Z-turn-examples/tree/master/axi_dma_prj2

0 Kudos
Explorer
Explorer
1,806 Views
Registered: ‎03-22-2016

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

I ran into this same issue with AXI DMA in streaming mode where the size of messages aren't known in advance.

I modified xilinx_dma.c to populate the residue field of xilinx_dma_chan when xilinx_dma_complete_descriptor() is called. Then, when xilinx_dma_tx_status is called, I return that value (or, in the event of non-complete DMA, the calculated result from adding up the remaining bytes in the active segments, as it was doing previously).

 

This seems to work well for my use case. Would this sort of a patch be more likely to be accepted since it only modifies xilinx_dma.c, rather than modifying the dma engine framework? Is this something that Xilinx is interested in?

0 Kudos
Scholar wzab
Scholar
1,783 Views
Registered: ‎08-24-2011

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor

Are you sure, that this solution works correctly for chained descriptors? I tried that approach, and experienced the problem that the engine was already initialized for the next transfer, and the information about the number of transferred bytes was already lost when my complete handler was executed.
0 Kudos
Explorer
Explorer
1,770 Views
Registered: ‎03-22-2016

Re: AXI DMA - checking the number of really transferred bytes for particular dma_async_tx_descriptor


@wzab wrote:
Are you sure, that this solution works correctly for chained descriptors? I tried that approach, and experienced the problem that the engine was already initialized for the next transfer, and the information about the number of transferred bytes was already lost when my complete handler was executed.

I knew there was something I was missing. I don't see how this can work for chained descriptors or even multiple descriptors in flight.

 

I'm storing residue in the residue field of the xilinx_dma_chan struct in each call to xilinx_dma_complete_descriptor(). I believe that will catch every completed descriptor, but I'm only storing a single value - not one for each descriptor. That works fine when you don't start another transaction until you've called xilinx_dma_tx_status() to check the completion state (and retrieve residue) for the most recently completed one. But like you said, that's not going to happen if there's already another descriptor in flight.

I think in order to support chained descriptors I would need to store the residue of each completed descriptor. That's tricky because as far as I can tell, there's no persistent storage for descriptors other than what is accessed via cookie using dma_cookie_status(). And now that I'm looking into that mechanism, it doesn't have persistent storage either - it just does a <= comparison of the cookie itself to the current cookie, assuming that it's complete if the dma engine went on to the next one.

0 Kudos