02-14-2017 12:02 AM
I'm trying to write windows driver for xdma core(pcie dma subsystem), but not quite understand the adjacent descriptors description section in PG195.pdf
can anyone provide some more info.
what's the relation between adjacent and normal descriptors?
04-25-2019 05:43 AM - edited 04-25-2019 05:44 AM
"The number of additional adjacent descriptors after the descriptor located at the next descriptor address field. A block of adjacent descriptors cannot cross a 4k boundary."
So i suspect that the FIFO fetches a descriptor looks at the adjacent if there are some
he uses the base address of the current descriptor and loads all the adjacent ones
with the descriptor offset. The last of them should have next set if you want to add more
descriptors to the chain.
The other possible thing could be that this is purely for optimization so that it can fetch a bigger block of memory and
the next addresses need to be all set even if there are adjacent descriptors. (From there example driver it looks more like the second case is true)
Suspect it doesn't need to be set if the descriptors are not adjacent in memory (dma memory!).
I have no clue if it is true and they also didn't answer.
06-12-2019 01:53 PM
The next address points to at least one descriptor (of course). So the XDMA core will fetch at least one descriptor from that address.
The extra_adjacent field provides the amount of extra (or additional) descriptors that are adjacent to the first descriptor. I.e. if this number is 0, only 1 descriptor is fetched. If the number is 3, then XDMA is allowed to fetch up to 4 descriptors from the next address.
Setting the field to 0 is always valid, but might prevent efficient (pre)fetching of descriptors.
08-12-2020 11:14 AM
See page 24 of PG195:
"The size of the initial block of adjacent descriptors are specified with the Dsc_Adj register. After
the initial fetch, the descriptor channel uses the Nxt_adj field of the last fetched descriptor to
determine the number of descriptors at the next descriptor address. A block of adjacent
descriptors must not cross a 4K address boundary. The descriptor channel fetches as many
descriptors in a single request as it can, limited by MRRS, the number the adjacent descriptors,
and the available space in the channel's descriptor buffer."
Following what @arminh and @likewise said, it is clearly an optimization feature. When the DMA engine fetches descriptors, if two or more are adjacent in physical host memory, the DMA channel can fetch the first descriptor and prefetch the adjacent ones next to it, improving performance.
I believe this is also why the total number of adjacent descriptors cannot cross the 4kB memory boundary, which is the smallest page size in most systems (e.g. x86). This would imply the adjacent descriptors need to be literally adjacent in physical memory. I am not 100% on this, but that is my reasoning.
This feature is optional (dsc_adj register) and only serves to improve performance. If you are using the provided Xilinx driver for XDMA, this feature is already used and optimized.
09-23-2020 12:24 AM
The idea is to be able to read them with a single PCIe read request. And PCIe read requests cannot cross 4KB address boundaries as per the PCIe specification. Reading multiple descriptors in the same read request means less PCIe TLP headers need to be transferred, reducing PCIe link utilization. And there is a limited number of requests that the core can keep track of at the same time, so reading multiple descriptors in the same operation means that this limited pool of concurrent operations can be utilized more effectively, increasing performance.
10-19-2020 07:21 AM
> what's the relation between adjacent and normal descriptors?
Just to go back to your question:
There is only one type of descriptor.
"Adjacent" means the descriptors are in physically contiguous areas of memory.
This (indeed, like Alex explained) is an optimization to fetch multiple descriptors with only one memory read request.
The burden of not crossing the PCIe read request 4kiB address boundary is left to the device driver (and not the FPGA IP), as it quite easy to ensure this in the driver, especially since multiple descriptors fit in 4 kiB nicely, as long as the descriptors are naturally aligned.