Я пишу собственный драйвер Linux, которому требуется память DMA между несколькими устройствами PCIE. У меня следующая ситуация:
- Я использую dma_alloc_coherent для выделения памяти для DeviceA
- Затем я использую DeviceA для заполнения буфера памяти.
Пока все в порядке, но на данный момент я хотел бы DMA памяти для DeviceB, и я не уверен, как правильно это сделать.
Сейчас я вызываю dma_map_single для DeviceB, используя адрес, возвращенный из dma_alloc_coherent, вызванного для DeviceA. Кажется, это нормально работает в x86_64, но кажется, что я нарушаю правила, потому что:
Предполагается, что dma_map_single вызывается с памятью, выделенной из kmalloc (и других). Это проблема вызова с адресом, возвращенным из вызова dma_alloc_coherent другого устройства?
Если с #1 все в порядке, то я все еще не уверен, нужно ли вызывать функции dma_sync_*, которые необходимы для памяти dma_map_single. Поскольку память изначально была выделена из dma_alloc_coherent, это должна быть некэшированная память, поэтому я считаю, что вызовы dma_sync_* не нужны, но я не уверен.
Я беспокоюсь, что мне просто повезло с этой работой, и будущее обновление ядра сломает меня, поскольку неясно, правильно ли я следую правилам API. Мой код в конечном итоге должен будет работать и на ARM, и на PPC, поэтому мне нужно убедиться, что я делаю что-то независимо от платформы, а не обходюсь каким-то хаком с архитектурой x86_64.
Я использую это как ссылку: https://www.kernel.org/doc/html/latest/core-api/dma-api.html
dma_map_single()
пахнет взломом. Поскольку вы работаете с устройствами PCIe, вы должны иметь возможность использовать передачу DMA p2p. - person 0andriy   schedule 27.07.2021