Jump to content
    

Двухсокетный сервер с Linux зависает при DMA записи в память

Доброго времени суток!

Я разрабатываю устройство на основе FPGA с поддержкой PCI Express (PCIe), которое должно работать под управлением Linux OS, поэтому я также пишу драйвер ядра Linux. Одной из особенностей устройства является его способность записывать данные в оперативную память хост-системы Linux в режиме прямого доступа к памяти (DMA) с использованием самого простого механизма:

  1. Драйвер устройства выделяет непрерывный участок памяти (128 КБ) и получает DMA (bus) адрес для этого участка.
  2. Драйвер записывает DMA-адрес в устройство FPGA PCIe.
  3. Устройство FPGA PCIe просто генерирует транзакции по записи в память с адресом, начиная с этого DMA-адреса (конечно же, драйвер устанавливает бит Bus Master).

Всё работает отлично на простом персональном компьютере с одним процессором под управлением Ubuntu OS. Но когда я пытаюсь запустить тот же код (как rtl, так и драйвер/приложение для Linux) на сервере Supermicro с двумя физическими процессорами Intel, компьютер зависает прямо на транзакции записи в память, генерируемой моим устройством.

Вот некоторый код из драйвера:

// использую 64 битную адресацию
if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) 
    printk(KERN_WARNING "%s: using 64bit DMA addressing\n", DRIVER_NAME);

...

// выделение и отображение памяти
struct page *dma_pages;
dma_pages = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_NOWARN | __GFP_COMP | __GFP_MEMALLOC, mem_order); 
    
virt_addr = (unsigned long)page_address(dma_pages);

// этот dma адрес передается в устройство
dma_addr = dma_map_single(&fpga_dev->pdev->dev, virt_addr, size, DMA_BIDIRECTIONAL);

Что я уже попробовал на сервере:

  1. Проверил линк PCIe, все в порядке. CPU может читать/писать регистры FPGA и передавать данные в FPGA.
  2. Отключил IOMMU при загрузке ядра Linux (iommu=off intel_iommu amd_iommu=off).
  3. Отключил Intel VT-d в BIOS.
  4. Попробовал экспериментировать с NUMA (включал/выключал, пробовал выделять память на разных узлах - близким к устройству и не очень).
  5. Проверил разные слоты PCIe, разные процессоры. Теперь карта FPGA подключена к слоту, где ранее корректно работала другая PCIe-карта (сетевой адаптер).

Я много гуглил и даже обсудил этот вопрос с ChatGPT - безуспешно. Есть ли идеи, что делать дальше?

В чем может быть разница между персональным компьютером с одним CPU (где всё работает нормально) и сервером Supermicro с двумя физическими процессорами Intel?

Edited by yarock

Share this post


Link to post
Share on other sites

1 час назад, yarock сказал:

В чем может быть разница между персональным компьютером с одним CPU (где всё работает нормально) и сервером Supermicro с двумя физическими процессорами Intel

Может режим SMP, не?))

1 час назад, yarock сказал:

даже обсудил этот вопрос с ChatGPT

Долой всех прогеров, чат ГПТ всех заменит)))))))))

Share this post


Link to post
Share on other sites

On 10/31/2023 at 4:40 PM, yarock said:
// выделение и отображение памяти
struct page *dma_pages;
dma_pages = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_NOWARN | __GFP_COMP | __GFP_MEMALLOC, mem_order); 
    
virt_addr = (unsigned long)page_address(dma_pages);

// этот dma адрес передается в устройство
dma_addr = dma_map_single(&fpga_dev->pdev->dev, virt_addr, size, DMA_BIDIRECTIONAL);

как то вы замысловато выделяете память DMA

https://www.kernel.org/doc/Documentation/DMA-API.txt

там сразу есть описание dma_alloc_coherent()

примеры

https://elixir.bootlin.com/linux/latest/C/ident/dma_alloc_coherent

Share this post


Link to post
Share on other sites

On 10/31/2023 at 5:58 PM, mantech said:

Может режим SMP, не?))

Долой всех прогеров, чат ГПТ всех заменит)))))))))

окей, SMP. я понимаю, что это symmentrical multiprocessing. а что вы пожете тут посоветовать?)

ГПТ обучился на многих тех форумах тоже, часто может дать ответ. Который конечно проверить надо еще 

On 10/31/2023 at 6:13 PM, sasamy said:

как то вы замысловато выделяете память DMA

https://www.kernel.org/doc/Documentation/DMA-API.txt

там сразу есть описание dma_alloc_coherent()

примеры

https://elixir.bootlin.com/linux/latest/C/ident/dma_alloc_coherent

dma_alloc_coherent() - так я тоже выделял память, она сразу выдает dma_addr, но так тоже не работает)

точнее работает на desktop и не работает на сервере. Доку эту я уже наизусть знаю наверное

я использую alloc_pages_node() потому что так можно указать numa node, где хочу выделить память. пробовал указывать конкретную, рядом с которой мое устройсто висит на шине. но тоже без результата положительного

Share this post


Link to post
Share on other sites

4 часа назад, yarock сказал:

окей, SMP. я понимаю, что это symmentrical multiprocessing. а что вы пожете тут посоветовать?)

Вопрос был "В чем может быть разница между персональным компьютером с одним CPU..." предположил, что это. Что тут делать, очевидно, что разобраться в том, что ваш код каким-то образом не способен работать в симметричном режиме, может прерывания от первого ядра, а обработчик во втором, может нет какой-либо синхронизации между вашими процессами...  Коль есть подозрение на выделение памяти, может сначала убрать из кода все лишнее и проверить именно этот кусок?

4 часа назад, yarock сказал:

ГПТ обучился на многих тех форумах тоже, часто может дать ответ.

Очень сомневаюсь, что после этого он сможет сказать что-то лучше, чем "а вы не пробовали выключить и снова включить" :biggrin:

Edited by mantech

Share this post


Link to post
Share on other sites

6 minutes ago, mantech said:

каким-то образом не способен работать в симметричном режиме

Думаю, персональный компьютер с одним процессором с большой вероятностью имеет больше одного ядра.

Share this post


Link to post
Share on other sites

Попробуйте собрать проект под Vivado более поздней версии.

У меня были проблемы при сборке в Vivado 2020.2

В версии 2021 все заработало.

Share this post


Link to post
Share on other sites

4 hours ago, dtmf73 said:

Попробуйте собрать проект под Vivado более поздней версии.

Автор даже нигде не упомянул, что у него Xilinx 🙂

On 10/31/2023 at 4:40 PM, yarock said:

В чем может быть разница между персональным компьютером с одним CPU (где всё работает нормально) и сервером Supermicro с двумя физическими процессорами Intel?

Один из возможных вариантов, что на персоналке система отдает драйверу 32-битные адреса (т.е. 64-разрядные с нулевой старшей частью), а на серверной плате идут реальные 64-битные адреса. Можно исключить этот момент, распечатав физические адреса и ограничив адресацию 32-битной маской.

 

Понять, связана ли проблема именно с двухсокетностью (и соответственно наличием далекой памяти в соседнем сокете) можно, убрав из серверной платы один из процессоров.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...