Как сделать IPC с задействованным процессом DPDK?

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

Пока что я пытался сделать что-то в меньшем масштабе. Вместо использования VMM я создал фиктивный процесс на языке C. Мне удалось привязать фиктивный процесс к процессу DPDK, используя именованные семафоры и разделяемую память. В основном в этой небольшой демонстрации приложение DPDK читает из буфера RX и помещает контент в общую память. Затем фиктивный процесс получает данные и выводит их на стандартный вывод.

Вся поддержка DPDK для многопроцессного взаимодействия нацелена на конкретный случай, когда оба приложения используют библиотеки dpdk. Мне интересно, есть ли какая-то поддержка для этого случая где одно приложение не использует эти библиотеки. Почему? Потому что VMM написан на Rust, и я не знаю, как добавить библиотеки DPDK в Rust.

Как вы думаете, какой способ общения был бы наиболее эффективным? Я думал, можно ли поместить мемпул в общую память и получить доступ к mbufs непосредственно из фиктивного процесса.

В настоящее время я использую dpdk 20.11 Ubuntu 20.04

Спасибо!

ОБНОВЛЕНИЕ 1:

это ваш вопрос Могу ли я взаимодействовать / взаимодействовать с приложением DPDK с приложением, отличным от DPDK

На самом деле я пытаюсь найти вот что: как эффективно переместить данные, полученные в буфере RX, в приложение, отличное от dpdk?

Мой текущий подход таков: https://imgur.com/a/cF2lq29

Это основной логический цикл для приложения dpdk, которое получает данные из буфера RX и отправляет их в приложение, отличное от dpdk.

Как это происходит:

  1. Прочитать данные из буфера приема.
  2. Подождите, пока приложение, отличное от dpdk, не сообщит, что я не использую разделяемую память, вы можете писать на ней
  3. Запись в разделяемую память (для простоты вместо всего пакета записывается nb_rx)
  4. Сообщите приложению без dpdk, что теперь общая память доступна для чтения.

Как видите, это не совсем эффективно, и я боюсь, что мой метод синхронизации создаст узкое место.

Так что это заставляет меня задаться вопросом, есть ли какие-нибудь лучшие способы достижения этого общения?


person Mihai    schedule 19.03.2021    source источник
comment
@Mihal из твоего текущего объяснения is your question Can I interface/interact DPDK application with non DPDK application. Простой ответ - да, можно и нет предела. Но что мне непонятно в вашем процессе совместного использования RX-пакета. Поскольку в DPDK пакет RX хранится в rte_mbuf, который создается с использованием mempool over hugepages. Из вашего объяснения вы закончите копированием пакета в разделяемую память. Если вы намерены избежать копирования памяти, ваше вторичное приложение должно иметь доступ к области памяти mbuf (огромная страница) как приложение DPDK. Так что не могли бы вы обновить.   -  person Vipin Varghese    schedule 20.03.2021
comment
Обновленный вопрос, спасибо! @VipinVarghese ›› _ Из вашего объяснения вы закончите тем, что скопируете пакет в разделяемую память. _ Мне не обязательно копировать пакеты в разделяемую память. Это только первый подход, о котором я подумал. ›› Если вы намерены избежать копирования с помощью memcopy, ваше дополнительное приложение должно иметь доступ к области памяти mbuf (огромная страница) как приложение DPDK. Вы говорите, что единственный способ избежать копирования с помощью memcopy должно быть приложение DPDK на другой стороне? Значит, в этом сценарии необходимо, чтобы оба приложения использовали библиотеки dpdk?   -  person Mihai    schedule 20.03.2021
comment
спасибо за обновление в комментарии. Как уже говорилось в моем предыдущем комментарии, у вас всегда есть возможность использовать ovs или SPP (в качестве основного приложения dpdk) и поделиться пакетом через библиотеку vhost с хост-приложением или гостевым приложением. Но поскольку вы пробуете новый метод, есть 2 возможности (первая) выполнить копирование памяти в общий IPC и (вторая) создать общую память как область DMA. Используйте адресуемую область DMA как внешний Mbuf. Управляйте ресурсами с помощью атомарного бита, установленного в каждой области памяти в Shared IPC как допустимые / недопустимые пакеты. Или самый простой способ вторичного вызова rte_eal_init и в IPC использовать PTR mbuf.   -  person Vipin Varghese    schedule 22.03.2021
comment
Если эти 3 подхода ясны, я могу поделиться этим в качестве ответа. Обратите внимание: я предполагаю, что существует какая-то фундаментальная причина для отказа от подачи иска на VPP, DPDK-OVS, SPP или другие приложения, которые не используют primary-secodnary. Следовательно, ваш вопрос размещен как использующий IPC.   -  person Vipin Varghese    schedule 22.03.2021
comment
Ага, похоже, это то, что я ищу. В своем ответе не могли бы вы подробнее рассказать о втором и третьем подходах? Боюсь, я не совсем понимаю, как сделать следующее: ›› создать общую память как область DMA. Я тоже не понимаю, что делает rte_eal_init в нашем контексте, я новичок в dpdk и подумал, что функция init предназначена только для инициализации компонента eal ›› Или самый простой способ вторичного вызова rte_eal_init, а в IPC использовать PTR mbuf. Спасибо еще раз!   -  person Mihai    schedule 22.03.2021
comment
Я обновил ответ на основе беседы в комментариях. Я тоже поделился шагами, чтобы сделать то же самое. Пожалуйста, просмотрите и примите / проголосуйте.   -  person Vipin Varghese    schedule 25.03.2021


Ответы (1)


Есть 3 способа решить проблему HOST to GUEST / Docker.

  1. Обычный способ: разрешить всем физическим сетевым адаптерам в приложении dpdk, таком как SPP, OVS, VPP и DPDK priamry-secodnary, использовать virtio, библиотеку vhost, memif или общую страницу MMAP Огромная, чтобы разрешить режим копирования / нулевого копирования для виртуальной машины / Docker.
  2. Способ сложного копирования: создайте общую область памяти между приложением DPDK на хосте и приложением, не относящимся к DPDK, которое работает в HOST / GUEST / Docker.
  3. Способ Mimic Zero Copy: приложение, отличное от DPDK, создает буферные области DMA в общей памяти в фиксированном месте. В приложении DPDK используйте внешний буфер памяти MBUF для физических портов. DPDK PMD (который поддерживает внешний MBUF) может затем DMA пакет в общую область.

Поскольку варианты 2 и 3 встречаются нечасто, позвольте мне объяснить, как вы можете в конечном итоге разработать решение.

Вариант-2:

  • разработать простое приложение без DPDK, используя общую область mmap, разделите область на фиксированный размер пакета (максимальный размер). Затем распределите половину для TX и половину для RX.
  • Инициализируйте приложение DPDK, чтобы использовать созданную область mmap.
  • Поддерживайте доступ к пакетам с помощью атомарных указателей заголовка и хвоста
  • Приложение DPDK после пакета RX при получении пакетов получит пустой индекс, запросив указатель заголовка, а затем скопируйте его в пакет по определенному индексу. После завершения приложение DPDK вызовет rte_mbuf_free.
  • Приложение, не относящееся к DPDK, может использовать указатель хвоста для получения действительного пакета RX из общей памяти.
  • Выполните аналогичную операцию для TX, используя отдельный индекс местоположения и указатели головы / хвоста.

Недостатки:

  1. пропускная способность пакетов сильно снижена.
  2. копирование пакетной памяти использует ЦИКЛЫ ЦП
  3. сложная общая библиотека для поддержки указателей индекса, заголовка и хвоста для rx и tx.
  4. пространство памяти перепрофилировано для самого большого пакета, так как трафик нельзя предсказать.

вариант-3:

  1. Создайте общий mmap с API posix_memalign, несколько областей размером 2000 байт.
  2. Используйте простую структуру данных (дескриптор) для хранения {виртуальный адрес, физический адрес, длина, значение}
  3. Создайте область SHM с каждым индексом, заполненным в указанном выше формате.
  4. инициализировать приложение DPDK для доступа к SHM и MMAPed области
  5. В приложении DPDK для заполнения rte_pktmbuf_pool_create_extbuf, где ext_mem представляет собой область DMA, заполненную физическим адресом SHM (не уверен, будет ли это работать, поскольку исходное намерение было другой целью).
  6. зарегистрируйте обработчик обратного вызова, чтобы он выполнял сборку мусора, когда мы rx_burst пакета.
  7. В TX есть 2 варианта: а) самый простой способ просто скопировать буфер в rte_mbuf и б) создать косвенный буфер для подключения rte_mbuf с внешним буфером, дождаться, пока сетевой адаптер действительно отправит пакет (через очередь завершения)

Недостатки варианта-2:

  1. сложный способ использования нулевой копии на стороне RX
  2. режим копирования - самый простой способ реализовать.
  3. Управление буфером хрупкое.
  4. предполагая, что 1 поток для RX-TX применим.

Рекомендация: если намерение не заключается в использовании VPP, SPP, OVS, тогда простейшим подходом является использование первично-вторичного формата DPDK, в котором все mbuf RX и mbuf TX доступны между двумя процессами, поскольку они отображаются на огромной странице.

person Vipin Varghese    schedule 25.03.2021