memcpy () зависает в __memcpy_neon при копировании в буфер DMA - PullRequest
1 голос
/ 06 мая 2019

Я циклически заполняю буфер DMA mmap-ed своими данными, копируя их из «нормальной» памяти кусками по 290 байт.

В первом цикле memcpy всегда проходит ОК. Во втором цикле он зависает __memcpy_neon (по крайней мере, так говорит GDB каждый раз, когда я нажимаю Ctrl-C).

дизассемблер всегда показывает, что инструкция strmi застряла.

Просто для целей тестирования я заменил memcpy() своим простым байтом memcpy1(), и все прекрасно работает на всем 3 МБ буфере DMA (но, очевидно, медленнее ... :-)). Чтобы исключить проблему с выравниванием, я протестировал библиотеку memcpy() для копирования невыровненных буферов - проблем не обнаружено.

Я использую linux 2.6.37 с glibc 2.23 (gcc 6.3.1 linaro) на DM8148 CPU.

Почему этот memcpy зависает вообще и во второй раз особенно?

ОБНОВЛЕНИЕ: После множества экспериментов с различными вариантами memcpy на ассемблере я могу сказать, что зависает инструкция копирования копии NEON, как с предзагрузкой, так и без нее:

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

Все остальные "нормальные" варианты memcpy () работают нормально. Есть ли какие-то загадки в использовании не кэшированной (!) Памяти DMA с инструкциями NEON?

1 Ответ

0 голосов
/ 11 мая 2019

Что ж, похоже, ответ «да! Есть загадки в использовании не кэшированной (!) Mmaped памяти DMA с инструкциями NEON».Как говорится в руководстве ARM, «Cortex A8 поддерживает доступ к памяти без выравнивания. Однако доступ к строго упорядоченной памяти не поддерживается». Поскольку буфер DMA, скорее всего, является строго упорядоченной памятью, glibc memcpy, использующий NEON, завершает работу при доступе к этой памяти DMA.В моем случае это происходит во втором цикле, потому что первый доступ был выровнен, а второй - нет.

...