复制到DMA缓冲区时,memcpy()挂在__memcpy_neon中

时间:2019-05-06 14:06:07

标签: linux arm memcpy neon dma

我通过将数据从290字节的块中的“普通”存储器中复制出来,来周期性地用我的数据填充mmap-ed DMA缓冲区。

在第一个周期memcpy始终通过OK。在第二个周期,它挂在__memcpy_neon中(至少这是我每次按Ctrl-C时gdb所说的内容)。

反汇编程序始终显示strmi指令被卡在其中。

仅出于测试目的,我用简单的字节字节memcpy()替换了memcpy1(),并且在所有3MB DMA缓冲区上一切正常(但显然速度较慢... :-)。为了排除对齐问题,我测试了库memcpy()以复制未对齐的缓冲区-未检测到问题。

我在linux 2.6.37 CPU上将glibc 2.23 (gcc 6.3.1 linaro)DM8148一起使用。

为什么此memcpy挂起,尤其是第二次挂起?

更新:经过多次针对memcpy的不同汇编程序变体的实验,我可以说挂起的是带有和不带有预加载的NEON内存复制指令:

Loop:
  PLD [r1, #0xC0]
  VLDM r1!,{d0-d7}
  VSTM r0!,{d0-d7}
  SUBS r2,r2,#0x40
  BNE Loop

memcpy()的所有其他“正常”变体都可以正常工作。 使用带有NEON指令的DMA未缓存(!)映射内存有什么奥秘吗?

1 个答案:

答案 0 :(得分:0)

好吧,答案似乎是“是的!使用带有NEON指令的DMA uncached(!)mmaped内存有很多奥秘”。正如ARM手册所述,“ Cortex A8支持未对齐的内存访问。但是,不支持对强排序内存的未对齐访问” 由于DMA缓冲区很可能是有序内存,因此使用NEON的glibc memcpy在访问该DMA内存时会失败。就我而言,它发生在第二个周期,因为第一次访问是对齐的,而第二次访问是未对齐的。