Перейти к содержанию
    

Двухсокетный сервер с 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?

Изменено пользователем yarock

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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, где хочу выделить память. пробовал указывать конкретную, рядом с которой мое устройсто висит на шине. но тоже без результата положительного

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, mantech said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, dtmf73 said:

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

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

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...