Драйвер ядра сетевой карты Intel E810-iRDMA-Linux и анализ исходного кода пользовательского режима
Драйвер ядра сетевой карты Intel E810-iRDMA-Linux и анализ исходного кода пользовательского режима

Введение

термин

Интерфейс очереди виртуальных машин (VMQ)

Прямой доступ к пользовательскому пространству (UDA) предназначен для предоставления доступа к очередям в пользовательском пространстве общим способом, но E810 Эта функция не поддерживается. UDA Доступно только в ядре и только с iWARP Настройка соединения и обработка ошибок. UDA Недоступно в пространстве пользователя

Кэш памяти хоста (HMC)

Руководство по чипу E810

В этом документе описывается двухпортовый 100 Gb Ethernet (GbE) Сетевое интерфейсное устройство Intel® Ethernet-контроллер E810 (E810) внешняя архитектура (включая операции устройства, описания контактов, регистры, определения и т. д.). Этот документ предназначен для архитекторов, проектировщиков логики, разработчиков встроенного и программного обеспечения, драйверов устройств, проектировщиков печатных плат, инженеров-испытателей или тех, кому может понадобиться E810 из Конкретная технология или информация о программировании из Кто-либо еще предоставляет ссылку. E810 Первый многоскоростной процессор Intel 100 GbE контроллер, поддержка 100 Mb/s к 100 Gb/s ставка между. E810 Основная цель – подобрать подходящую для предприятия конфигурацию.、Поставщик облачных и коммуникационных услуг должен использовать масштабируемый Ethernet-контроллер. E810 Основные поддерживаемые функции включают две 100 Gigabit Порт Ethernet, 100 Gigabit Пропускная способность, улучшенный программируемый конвейер обработки пакетов, виртуализация (улучшенная SR-IOV Поддержка, максимум 256 индивидуальный VF и обратная совместимость VF поддержка драйверов), новые возможности для общения Marketplace (детальный планировщик, поддержка удаления транспортных заголовков, корректировка кредита на основе различных заголовков, улучшенная QoS и улучшенный контроль пакетной передачи) и RDMA(iWARP и RoCEv2)。 поверхность 1-1 подведены итоги E810 функция. Для получения дополнительной информации о поддерживаемых функциях см. Intel®. Ethernet-контроллер E810 Функцияподдерживатьповерхность

PBLE/HMC для Intel E810

E810 из четырех хэш-поиска и Механизм протоколаиспользоватьпамять хостаделатьдляразличные контекстывернослонизРезервное хранилище。 Кэш памяти хоста (HMC) Отвечает за кэш и управление этим объектом контекста. верно Ю каждыйиндивидуальный RDMA соединение, механизм протокола использует QP объект контекста (хранилище TCP Серийный номер и т. д. TCP/IP контекст соединения) и входящий RDMA очередь чтения (IRRQ) Объект, который буферизует входящий трафик RDMA Запрос на чтение ожидает ответа на соответствующий ответ на чтение. Плановый трансфер. верно Ю каждыйиндивидуальный RDMA Область памяти, Механизм протоколаиспользоватьобласть памятиповерхностьвход (MRTE) Объект для хранения границ области и информации о правах доступа и использования набора записей поверхности столбцов физического буфера. (PBLE) Объект для хранения трансляции виртуального адреса в физический. этотиндивидуальныйобласть。 Эти и другие объекты контекста механизма протокола обсуждаются в разделе 11 Подробное введение в главе. Нет. 9 В разделе представлена ​​информация о HMC Эксплуатация и конфигурация и общая информация

E810 использоватьпамять хоста как можно больше объектов контекста из Резервное хранилище, объект контекста «Эти» используется для отслеживания состояния очереди и iWARP объект. Кэш памяти хоста (HMC) отвечает за управление данными, хранящимися в памяти хоста iWARP Компоненты объекта контекста. HMC существовать Каждыйиндивидуальный PCI функциональный Управление на основепамять хозяин, а дальше воля каждый индивидуально PCI функциональный HMC Пространство памяти разбито на то, что используется для управления данным PCI функциональный для каждого отдельного объекта контекста в памяти. Программное обеспечение хоста отвечает за распределение HMC Хост-страница, которую нужно использовать. Также доступен для конкретного функционального HMC Резервное Объем памяти определяется профилем активного ресурса, который определяется драйвером программного обеспечения и операционной средой. PCI Зависит от количества функций. Профили ресурсов можно выбрать во время инициализации драйвера.

HMC Для выполнения своей функции в памяти хоста должно находиться большое резервное хранилище структур данных. поверхность 9-11 Предоставляется структура данных по поверхности столбцов, а также объем памяти, который необходимо выделить для каждой отдельной структуры данных. “HMC Индикация столбца «Положение объекта» HMC Находится ли объект (и связанные с ним страницы резервного хранилища) только в PF HMC в объектном пространстве или расположенном в PF и VF HMC в объектном пространстве. Обычно механизм протокола HMC Объекты делятся на конкретные PF и VF из HMC пространство объекта. Ресурсов может быть недостаточно. Например, если отдельная функция назначает 512 индивидуальный QP, но только используется 8 индивидуальный QP, вам нужно только назначить 4K память не для всех 512 индивидуальный QP выделить весьиндивидуальный Память。 некоторый HMC Объект должен быть полностью заполнен при инициализации драйвера, например Механизм. протокола Хэшповерхностьвход. О механизме протоколаиз HMC Стратегия распределения ресурсов. Дополнительную информацию см. в главе 11.5 Фестиваль

512 Слово Фестиваль зарезервировано для QP контекст. Каждое устройство имеет максимум 256K QP контекст. Это число делится на все поддерживаемые механизмы. протоколаиз PCI Функция. VF Объект памяти состоит из PF Драйвер выделяет и использует PF Запрашивающая сторона ID (RID) для посещения. Для однофункциональных устройств аппаратное обеспечение остается 256K QP один для внутреннего использования

Каждыйиндивидуальныйподдерживать Механизм протоколаиз PCI Функции могут быть назначены до 256M PBLE вход. VF Объект памяти состоит из VF Драйвер выделяет и использует VF Запрашивающая сторона ID (RID) для посещения. Любой связанный дескриптор страницы представлен PF Драйвер выделяет и использует PF RID посетить

дляпосетил(и кэшсуществоватьвстроенная памятьсередина)поверхность 9-11 Структура данных, определенная в HMC использовать частное адресное пространство памяти из концепции. E810 иметь 8GB Адресное пространство частной памяти, которое может использовать память хоста для разреженной поддержки в зависимости от фактического использования контекста. Драйверы не требуются для драйверов, когда переадресация не используетсяиз HMC Страница размещения объектов. личная памятьадресное пространствоСначала делится на функцию PCI,Ранназадв соответствии свернослонилиданныеструктура Типовое деление,наконецв соответствии синдекс объектаразделять. закреплен за конкретным PCI функциональныйличная памятьадресное пространствоназвание частидля Функциячастная память (FPM)。 Также отметим, что ВФ FPM не по VF Драйвер программируется напрямую. PF привод использовать индекс функции HMC для выбора программы изVF FPM。 Как E810 обеспечивает личную память из сопоставления адресов между физическими адресами хостов, например картина9-5показано. картина показана слева из PM адресповерхность Показывать E810 Private Memory Адрес от 0 приезжать 8GB-1。 E810 использует внутреннее адресное пространство PM, преобразуя его в физический адрес хоста для доступа к памяти хоста.

картина 9-5, Кэш памяти хосталичная памятьадресное пространство

Информацию о кэшировании четырех хэшей см. на стр. 9.3.2 Фестиваль。 картина 9-5 в левой части показано местоположение на чипеиз HMC часть. Эта часть включает в себя актуальные изкэш объектов,он сохраняет память Некоторые данные в хостаиз предоставлены в виде высоких производительностьидескриптор сегмента (SD)。 SD находиться на чипе 32 KB RAM , называемый поверхностью дескриптора сегмента. Дескриптор сегмента поверхности сохранен. 4096 индивидуальныйориентированныйпамять страница хоста из указателя (8B * 4096=32KB)。 Дескриптор сегмента поверхностисерединаиз непрерывной SD уникальный объем присваивается каждому индивидуальному действию из PCI Функция. Дескриптор сегмента поверхности — это первый уровень, предоставляемый E810. память Перевод адреса

SD использовать PFHMC_SDCMD (нет. 13.2.2.20.35 Фестиваль)、PFHMC_SDDATALOW(Нет. 13.2.2.20.36 Фестиваль)и PFHMC_SDDATAHIGH(Нет. 13.2.2.20.37 Фестиваль) зарегистрируйтесь на программирование. Механизм протокола CQP Операции также можно использовать для программирования дескрипторов сегментов. картина 9-5 Средний дескриптор поверхности, правая сторона всего, находится в памяти. хостасередина。 Каждыйиндивидуальный PCI Каждая функция имеет набор регистров (GLHMC_SDPART[n] и GLHMC_VFSDPART[n]), используемый для определения PCI функциональный SD из базы и количества. GLHMC_SDPART[n] и GLHMC_VFSDPART[n] Зарегистрируйтесь из NVM программированием или прошивкой во время операции создания пары очереди управления (раздел 11.5.2.1 Фестиваль)。 E810 Обеспечивает проверку объема для каждого внутреннего доступа, чтобы гарантировать, что заданное PCI Функция не должна разрешать доступ к своим действительным SD объем памяти. E810 Внутреннее управление на основе профилей ресурсов. SD Регистр базового адреса и номера, файл конфигурации ресурса находится в NVM Загрузка при погрузке или первым человеком E810 Драйвер выбирает загрузку устройства во время операции создания пары очереди управления (раздел 11.5.2.1 Фестиваль)。 E810 Предоставление второго уровня личная перевод адреса памяти — это дескриптор страницы (PD)。 Каждый индивидуальный SD указывает на индивидуальную хост-страницу размером 2 МБ.,Главная страница разделена надля 512 индивидуальный ПД, эти PD только 64 бит адреса физической памяти, Размер каждого индивидуального PD составляет 4 КБ. Каждыйиндивидуальный PD Все указывают на личную Адресное пространство памяти представляет собой отдельную внутреннюю страницу. общий 8 GB(4096индивидуальныйSD * 2MB = 8GB) Используется личное адресное пространство памяти, полностью заполненное из поверхности дескриптора сегмента, экспорт из этой поверхности указывает на сохранение. 2M PD из 4096 индивидуальный 4KB Страница хоста. Каждыйиндивидуальный 2M PD Все указывает на память страница хостаподдержки,общий 8 GB адресное пространство. Как упоминалось в Forward, нет необходимости заполнять все адресное пространство памяти памятью, если программное обеспечение не выделяет эту часть адресного пространства памяти. SD или PD。 память хостасерединаPDструктураиз Формат такойповерхность9-12Место Показывать

HMC Физический адрес страницы поддержки — это адрес, выделенный драйвером, и страница сохраняется. HMC Контекст объекта. Адрес должен совпадать с памятью хостасерединаиз 4 KB Выравнивание адресов. PD Действительный бит позволяет программному обеспечению HMC Объект контекста заполняется редко по мере необходимости. PD вход. Программное обеспечение должно распространяться для сохранения PD Память упакованного массива хоста Страница,нравитьсякартина 9-5 показано. Эти PD Физический адрес страницы, используемый пользователем PFHMC_SDCMD (нет. 13.2.2.20.35 Фестиваль)、PFHMC_SDDATALOW(Нет. 13.2.2.20.36 Фестиваль)и PFHMC_SDDATAHIGH(Нет. 13.2.2.20.37 Фестиваль) зарегистрируйтесь, чтобы заполнить SD вход. О том, как регистрировать пары SD Программирование Более подробную информацию см. на стр. 9.3.8 Фестиваль。 Выделенная память далее делится на отдельные PCI функция выделенной памяти (FPM) адрес. PCI Функции могут быть физическими или виртуальными. вперед 8 индивидуальный FPM Адресное пространство зарезервировано для NIC PF。 Возьми это Приходитьизвосемьиндивидуальный FPM Адресное пространство используется для поддержки iWARP、RoCEv2 или UDA Обеспечить ускорение из Механизма протоколаиз PF。 наконец 32 индивидуальный FPM адресное пространствоиспользовать ВподдерживатьМеханизм протоколаиз VF,для iWARP、RoCEv2 или UDA Обеспечить ускорение. картина 9-6 Показывает, как делать для каждого человека PCI Функциональное подразделениеличная памятьадресное пространство. Может быть присвоена функция изминличная памятьколичестводля 2 MB (1 SD)。 Максимальное значение, которое может быть присвоено функции из, — это весь отдельный сегмент поверхности, в этом случае другие функции не могут иметь никаких личных значений. памятьресурс. Обратите внимание, кэш объектовиспользовать HMC Номер функции для обращения HMC объект для определения правильного из FPM。 Идентификатор FPM принадлежит изобъему функционального частного адресного пространства памяти PCI. потому что Каждыйиндивидуальный SD поколениеповерхность 2 MB HMC PM адресное пространство, следовательно FPM Также идентифицирует PCI функциональный SD объем

картина 9-6, Кэш памяти хоста Функцияличная памятькосмос

Каждыйиндивидуальный PCI функциональныйличная Пространство памяти далее делится на память Каждый индивидуальный объект хоста имеет отдельное пространство памяти. Каждыйиндивидуальный PCI Функции имеют набор регистров, используемых для определения FPM Базовый адрес объекта в пространстве и граница конкретного объекта (максимальное количество записей). картина 9-7 описанооставатьсясуществоватьличное сохранение некоторых объектов, находящихся впереди (полный список объектов с поверхности см. в разделе «Поверхность»). 9-11)。 Адрес FPM основан на типе объекта (идентифицирующий регистр базового адреса объекта). объект (базовый адрес FPM рассчитан) рассчитан из. В конечном итоге базовый адрес FPM, базовый адрес объекта, размер объекта и индекс объекта используются для определения адреса частной памяти.

картина 9-8описал Воляличная Адрес памяти декодируется в адрес хоста. этотснаружи,картина 9-8 описал SD Непосредственно в личную Пространство памяти поддерживает адресацию страниц вместо косвенной адресации второго уровня (PD). Каждыйиндивидуальный PCI функция может быть SD объем Внутриизани SD установить, чтобы указать на PD или указывает непосредственно на внутреннюю страницу. Тип сегмента находится в PFHMC_SDDATALOW.PMSDTYPE. указанный в поле реестра. Метод прямого сегмента может быть использован для FPM Не требует много места из-за PCI функции, позволяющие ограничить доступ к HMC Возникают накладные расходы на объект. Если драйвер способен выделить физически смежные страницы, достаточно большие, чтобы обеспечить поддержку конкретных PCI Функционально загружен, требуется драйвер FPM необходимыйизвсеиндивидуальный PD Space можно дополнительно использовать метод прямого сегмента. есливодитель Бывает, что физическое соседство назначаетсяиз Памятькусок,или Те, кто занимается спортомделатьсистемаподдерживать 2 MB страница, этот режим предотвращает дополнительный поиск адресов и обеспечивает высокую производительность

9.3.2 кэш объектов RDMA из Кэш памяти Хост разделен на два отдельных кэша. Индивидуальный кеш содержит все, кроме четырехзначной записи хеша. RDMA объект. Записи четырехзначного хеша размещаются в разных кэшах, чтобы механизм фильтрации мог ссылаться на них. RDMA при добавлении или удалении четырехъядерного хэш-объекта Прошивка отвечает за обновление кэша четырехъядерного хеша в объекте четырехъядерного хеша. Эти два кэша являются независимыми регистрами, но используют один и тот же базовый механизм. Поскольку есть два отдельных компонента, ссылающихся на четырехкратный хэш-кеш, два отдельных кэша из регистров должны быть согласованными. О четырех хэшах Кэш памяти хоста (включая регистры и прерывания) из Подробнее см. стр. 9 Фестиваль

E810 Конфигурация адресного пространства частной памяти разделена на два этапа: 1. Воля HMC Связанные ресурсы разделены на каждый индивидуальный PCI Функциональные ресурсы. 2. Волягенерироватьизфункциячастная память (FPM) Разделен на отдельные изобъекты. Чтобы упростить распределение ресурсов, E810 Предоставляет концепцию профиля ресурса, которая учитывает PCI функциональныйчислоколичество、начинатьиспользовать Механизм протоколаиз PCI Разделено по количеству функциональный и операционной системы HMC Выделенное пространство памяти и Механизм протокола Doorbell ресурс. Эти HMC Файлы конфигурации ресурсов используются для HMC дескриптор сегментаповерхностьи Механизм Ресурсы протокола дверного звонка разделены. Программное обеспечение в каждом индивидуальном PCI Выполнен на основе функционального FPM разделять. поверхность 9-13 серединаописанныйкогдапереслатьопределениеот HMC Файл конфигурации ресурса. Механизм Пара ресурсов дверного звонка протокола HMC Профили ресурсов накладывают ограничения, поскольку количество ресурсов на чипе фиксировано. Ресурсов для дверных звонков достаточно. 256K пара очередей протокола 512K Механизм протокола завершает очередь. Эти ресурсы должны потребоваться, когда Механизм протоколафункциональный PCI Выполните между функциями разделять. Механизм протоколаресурс Волясуществовать 11.1 Фестивальсерединадальнейшее обсуждение

Анализ исходного кода

Инициализация модуля и драйвер зонда E810

Язык кода:c
копировать
intel irdma/ice/e810 driver:
drivers/infiniband/hw/irdma/main.c
module_init(irdma_init_module); -> Инициализация модуля
    auxiliary_driver_register i40iw_auxiliary_drv
        .probe = i40iw_probe
    auxiliary_driver_register(&irdma_auxiliary_drv.adrv)
    irdma_register_notifiers
        register_inetaddr_notifier(&irdma_inetaddr_notifier);
        register_inet6addr_notifier(&irdma_inetaddr6_notifier);
        register_netevent_notifier(&irdma_net_notifier);
        register_netdevice_notifier(&irdma_netdevice_notifier);
...		
irdma_probe <- irdma_auxiliary_drv

irdma_ib_register_device
    irdma_init_rdma_device
        irdma_init_roce_device(iwdev)
        or
        irdma_init_iw_device
        ib_set_device_ops(&iwdev->ibdev, &irdma_dev_ops)
    ib_device_set_netdev
    dma_set_max_seg_size
    ib_register_device(&iwdev->ibdev, "irdma%d", iwdev->rf->hw.device)
    irdma_port_ibevent(iwdev)
        event.event = iwdev->iw_status ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR
        ib_dispatch_event(&event)


intel e810, drivers/infiniband/hw/irdma/main.c
irdma_probe
    ib_alloc_device -> #define ib_alloc_device(drv_struct, member) -> struct ib_device *_ib_alloc_device(size_t size)
        device = kzalloc(size, GFP_KERNEL)
        rdma_restrack_init
        rdma_init_coredev -> RDMA/core: реализовать совместимость в сетевом пространстве имен. Дерево устройств/sysfs, реализует записи sysfs слоя ib_coreиз совместимости для не-init_net Устройства rdma также могут быть обнаружены в пространстве имен net. Каждыйиндивидуальный Нет init_net В нем создаются сетевые пространства имен. ib_core_device。 Сюда ib_core_device sysfs дерево напоминает init_net Найдите жильеиз в пространстве имен rdma оборудование. Это позволяет пройти sysfs Записи в рубрике многоиндивидуальный не init_net Найдено в пространстве имен сети rdma оборудование, и чтобы rdma-core Пользовательское пространство полезно
            этот BUILD_BUG_ON предназначен для захвата ib_core_device и device Объединение изменений макета. dev Должен быть первым индивидуальным элементом, потому что ib_core и драйвер провайдера используйте его. существовать ib_core_device серединаиз device Добавление чего-либо еще разрушило бы это предположение.
            coredev->dev.class = &ib_class
            device_initialize -> device_initialize - Инициализируйте структуру устройства. @dev:оборудование. * Это подготавливает устройство для использования другими уровнями путем инициализации его полей. Если эта функция вызывается, это device_register() извпередполовина части,Хотя его тоже можно настроить отдельно.,потому чтоэтот Можетиспользовать @dev из поля. в частности,настраиватьиспользоватьэтотфункцияназад,Можетиспользовать get_device()/put_device() верно @dev Выполните подсчет ссылок. * @dev Все поля в из должны быть инициализированы вызывающей стороной 0,Если это не яснонастраиватьдлядругие ценностииз поля. Самый простой метод — использовать kzalloc() выделить @dev из структуры. * Уведомление:настраиватьиспользоватьэтотфункцияназад,использовать put_device() Откажитесь от ссылки вместо того, чтобы публиковать ее напрямую @dev
                INIT_LIST_HEAD(&dev->dma_pools)
                device_pm_init(dev)
                swiotlb_dev_init(dev)
                    dev->dma_io_tlb_mem = &io_tlb_default_mem
            INIT_LIST_HEAD(&coredev->port_list) -> RDMA/ядро: представлено ib_core_device сохранить устройство, чтобы поддержать rdma Устройство из индивидуального сетевого пространства имен из sysfs Вход, знакомство индивидуальное ib_core_device , его объем ограничен для сохранения основных устройств и каждого отдельного порта sysfs Связанныйвход. этот Это подготовкапластырь,так чтосуществоватьназад Продолжениепластырьсередина Можетсуществовать Каждыйиндивидуальныйсетевое пространство именсерединасоздаватьмногоиндивидуальный ib_core_device, Этими устройствами можно делиться ib_device。 (a) Воля sysfs Переместить определенные поля ib_core_device。 (b) делать sysfs èСуществуют процедуры, связанные с жизненным циклом устройства ib_core_device Иди на работу. (c) вестивходитьииспользовать rdma_init_coredev() вспомогательная программа для инициализации coredev Поле
            write_pnet(&coredev->rdma_net, net)
        INIT_LIST_HEAD(&device->event_handler_list)
        init_rwsem(&device->event_handler_rwsem) -> init_rwsem()из Функциядаинициализация Чтение и запись сигналовколичество,Воля СигналколичествоизcountПоленастраиватьдля0
        xa_init_flags(&device->client_data, XA_FLAGS_ALLOC) -> инициализировать массив
        init_completion(&device->unreg_completion) -> RDMA/основной:использовать netlink Команда синхронизации отмены регистрации, -> инициализациядинамическое размещениеиз Заканчиватьвернослон -> ссылка: https://zhuanlan.zhihu.com/p/504938832
        device->uverbs_cmd_mask = -> IB_USER_VERBS_CMD_ALLOC_MW... -> Установить маску/биты команды
    irdma_fill_device_info -> Заполните информацию об устройстве, конфигурация по умолчанию
        rf->gen_ops.register_qset = irdma_lan_register_qset;
            ice_add_rdma_qset(pf, &qset)
                ice_get_main_vsi
                ice_cfg_vsi_rdma
                    ice_cfg_vsi_qs
                        ice_sched_get_tc_node
                        ice_sched_cfg_vsi
                            ice_get_vsi_ctx
                            ice_sched_get_vsi_node
                            ...
                ice_ena_vsi_rdma_qset
                    ice_sched_get_free_qparent
        rf->gen_ops.unregister_qset = irdma_lan_unregister_qset
        rf->gen_ops.request_reset = irdma_request_reset
        rf->hw.hw_addr = pf->hw.hw_addr
        ...
    irdma_ctrl_init_hw -> Инициализация аппаратного обеспечения и части управления
        irdma_setup_init_state
            irdma_save_msix_info
            rf->obj_mem.size = ALIGN(8192, IRDMA_HW_PAGE_SIZE) -> С 4096 за верхнюю границу верно Ци, Выделить 8 КБ
            rf->obj_mem.va = dma_alloc_coherent(rf->hw.device, rf->obj_mem.size, &rf->obj_mem.pa, GFP_KERNEL) -> Подать заявку на непрерывный большой блок памяти (8 КБ)
            irdma_initialize_dev
                irdma_obj_aligned_mem -> irdma_obj_aligned_mem - от Распределение оборудованияиз Памятьсерединаполучатьверновместеиз Память,@rf:RDMA PCIфункция@memptr:ориентированный Памятьадрес@size:необходимыйиз Памятьразмер@mask:верновместе Памятьизмаскаполучатьпроситьразмеризверновместе Памятьи Даженовыйmemptr ориентированныйновыйверновместеиз Памятьуспехновозвращаться0,нетновозвращатьсяникто Памятьошибка -> rf: RDMA PCI function
                    rf->obj_next.pa = memptr->pa + size
                irdma_obj_aligned_mem(rf, &mem, IRDMA_COMMIT_FPM_BUF_SIZE,
                info.bar0 = rf->hw.hw_addr
                irdma_sc_dev_init -> Initialize control part of device
                    dev->hw->hw_addr = info->bar0
                    irdma_sc_init_hw(dev) -> RDMA/irdma: реализация аппаратно управляемых очередей ОП, водитель Воля выдал привилегированную команду приезжать в очередь управления оборудованием (управление QP или CQP) для запроса аппаратного обеспечения операций управления. выполнить CQP создавать/уничтожать и поддерживать функции, структуры данных и заголовки для обработки различных CQP Заказ
                        i40iw_init_hw(dev)
                            dev->hw_regs[i] = (u32 __iomem *)(i40iw_regs[i] + hw_addr)
                            dev->wqe_alloc_db = dev->hw_regs[IRDMA_WQEALLOC]
                            dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M -> RDMA/irdma: Не беспокойтесь о x722 уведомление 1GB Размер страницы, x722 Не поддерживается 1GB размер страницы, но irdma Ошибка драйвера Воля x722 Оборудование 1GB страницаразмерподдерживатьуведомление Давать ib_core,рассчитатьсуществоватьэтот MR Лучший размер страницы при использовании. Это может привести к MR Аппаратное обеспечение неправильно рассчитывает начальное смещение
                            dev->hw_attrs.max_qp_wr = I40IW_MAX_QP_WRS
                        or icrdma_init_hw(dev)
                            dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G;
                    irdma_wait_pe_ready(dev)
                        do {
                            statuscpu0 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS0])
                            mdelay(1000) -> mdelay занятждатьфункция,существоватьзадержка процессасередина Не могу запускать другие задачи.этотиндивидуальный Задерживатьиз Время точноеиз.Это необходимостьждатьмногонемногочасвремя будет реальнымждатьмногонемногочасмежду
                        }
                    val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL])
                    dev->db_addr = dev->hw->hw_addr + (uintptr_t)dev->hw_regs[IRDMA_DB_ADDR_OFFSET]
        irdma_create_cqp(rf)
            cqp->sq.va = dma_alloc_coherent(dev->hw->device, cqp->sq.size,
            irdma_obj_aligned_mem(rf, &mem, sizeof(struct irdma_cqp_ctx),
            irdma_sc_cqp_init(dev->cqp, &cqp_init_info) -> Initialize buffers for a control Queue Pair
                irdma_get_encoded_wqe_size IRDMA_QUEUE_TYPE_CQP
                cqp->rocev2_rto_policy = info->rocev2_rto_policy
                memcpy(&cqp->dcqcn_params, &info->dcqcn_params, sizeof(cqp->dcqcn_params))
                IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size)
                INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head)
                writel(0, cqp->dev->hw_regs[IRDMA_CQPTAIL]) -> db, register -> fpga, xt not call this db
                writel(0, cqp->dev->hw_regs[IRDMA_CQPDB])
                writel(0, cqp->dev->hw_regs[IRDMA_CCQPSTATUS])
            irdma_sc_cqp_create(dev->cqp, &maj_err, &min_err) -> create cqp during bringup
                cqp->sdbuf.size = ALIGN(IRDMA_UPDATE_SD_BUFF_SIZE * cqp->sq_size, IRDMA_SD_BUF_ALIGNMENT -> 128
                writel(p1, cqp->dev->hw_regs[IRDMA_CCQPHIGH])
                writel(p2, cqp->dev->hw_regs[IRDMA_CCQPLOW])
                udelay(cqp->dev->hw_attrs.max_sleep_count)
                readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS])
                cqp->process_cqp_sds = irdma_update_sds_noccq
            INIT_LIST_HEAD(&cqp->cqp_avail_reqs)
            INIT_LIST_HEAD(&cqp->cqp_pending_reqs)
            init_waitqueue_head(&cqp->cqp_requests[i].waitq) <- wake_up(&cqp_request->waitq)
        irdma_hmc_setup(rf)
            rf->sd_type = IRDMA_SD_TYPE_DIRECT
            irdma_cfg_fpm_val(&rf->sc_dev, qpcnt) -> алгоритм
                irdma_sc_init_iw_hmc(dev, dev->hmc_fn_id)
                    irdma_sc_query_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, &query_fpm_mem, true, wait_type)
                        wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch)
                        irdma_sc_cqp_post_sq(cqp)
                        irdma_cqp_poll_registers(cqp, tail,
                            irdma_get_cqp_reg_info(cqp, &val, &newtail, &error)
                            error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES])
                    irdma_sc_parse_fpm_query_buf(dev, query_fpm_mem.va, hmc_info,
                        irdma_sc_decode_fpm_query(buf, 32, obj_info, IRDMA_HMC_IW_HTE)
                        obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192
                sd_needed = irdma_est_sd(dev, hmc_info) -> возвращаться HMC из SD из Приблизительное количество
                    size += round_up(hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt *
                qpwanted = min(qp_count, hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt)
                while (irdma_q1_cnt(dev, hmc_info, qpwanted) > hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].max_cnt)
                    roundup_pow_of_two
                cfg_fpm_value_gen_1
                or
                cfg_fpm_value_gen_2
                irdma_sc_cfg_iw_fpm(dev, dev->hmc_fn_id) -> warp
                    irdma_sc_parse_fpm_commit_buf
                        irdma_sc_decode_fpm_commit
                            obj_info[rsrc_idx].cnt = (u32)FIELD_GET(IRDMA_COMMIT_FPM_QPCNT, temp) -> Получите поддерживаемые спецификации количества изQP во время инициализации.
                hmc_info->sd_table.sd_entry = virt_mem.va
            irdma_create_hmc_objs(rf, true, rf->rdma_ver) -> Во время инициализации драйвер подготовит HMC в соответствии со спецификациями поддерживаемого количества QP. -> create all hmc objects for the device
                for (i = 0; i < IW_HMC_OBJ_TYPE_NUM; i++)
                    irdma_create_hmc_obj_type(dev, &info) -> irdma_sc_create_hmc_obj
	                    irdma_find_sd_index_limit(info->hmc_info, info->rsrc_type, info->start_idx, info->count, &sd_idx, &sd_lmt) -> Найти предел индекса дескриптора сегмента, @hmc_info: указывает на HMC Структура информации о конфигурации из указателя @type: Мы ищем из HMC Тип ресурса @idx:вернослонизстартовый индекс @cnt:мы стараемсясоздаватьизвернослончислоколичество @ sd_idx:возвращаться Связанныйдескриптор сегмента Таквестиизуказатель @sd_limit:возвращатьсядескриптор сегментабольшинствобольшойчислоколичествоизуказатель Эта функция вычисляет irdma_hmc_rsrc_type Определите ресурс и индекс дескриптора сегмента и предел индекса.
                        irdma_find_pd_index_limit(info->hmc_info, info->rsrc_type, info->start_idx, info->count, &pd_idx, &pd_lmt) -> finds page descriptor index limit
                        for (j = sd_idx; j < sd_lmt; j++)
                            irdma_add_sd_table_entry(dev->hw, info->hmc_info, j, info->entry_type, IRDMA_HMC_DIRECT_BP_SIZE) -> RDMA/irdma: Добавить HMC Резервное функция настройки хранилища, HW использоватьпамять хостаделатьдлямногоиндивидуальныйконтекст протоколавернослонистатус очередиотслеживатьиз Резервное хранилище。 Кэш памяти хоста (HMC) отвечает за управление данными, хранящимися в памяти хоста Этивернослонизкомпоненты。 Добавляйте функции и структуры данных для управления HMC для Различныйвернослониспользоватьизподдерживатьстраницаизраспространять -> Adds a segment descriptor to the table
                                allocate a 4K pd page or 2M backing page
                                dma_mem.size = ALIGN(alloc_len, IRDMA_HMC_PD_BP_BUF_ALIGNMENT)
                                dma_mem.va = dma_alloc_coherent(hw->device, dma_mem.size,
                                if (type == IRDMA_SD_TYPE_PAGED)
                                    vmem->size = sizeof(struct irdma_hmc_pd_entry) * 512
                                    vmem->va = kzalloc(vmem->size, GFP_KERNEL)
                                    sd_entry->u.pd_table.pd_entry = vmem->va
                                    memcpy(&sd_entry->u.pd_table.pd_page_addr, &dma_mem, sizeof(sd_entry->u.pd_table.pd_page_addr))
                                else
                                    memcpy(&sd_entry->u.bp.addr, &dma_mem, sizeof(sd_entry->u.bp.addr))
                            irdma_add_pd_table_entry -> Adds page descriptor to the specified table -> Волястраницадескриптордобавить вприезжатьобозначениеизповерхностьсередина,@dev:ориентированныйнасизоборудованиеструктураизуказатель@hmc_info:ориентированныйHMCСтруктура информации о конфигурации из указателя@pd_index:хочу трахатьсяделатьизстраницадескриптор Таквести@rsrc_pg:если НетдляNULL,ноиспользоватьпредварительнораспространятьизстраницаи Нетдараспространять новыйизодининдивидуальный。 Эта функция: 1. инициализация pd вход 2. существовать pd_table Добавить pd_entry 3. существовать irdma_hmc_pd_entry структурасередина Отметить этот вход действительным 4. Воля pd_entry известииспользоватьсчитатьинициализациядля 1 Предположения: 1. pd Память должна быть фиксированной, физически непрерывной и существовать 4K на границеверновместеи Воля Память Вернуться к нулю。 2. Размер должен быть 4К.
                                page->size = ALIGN(IRDMA_HMC_PAGED_BP_SIZE, IRDMA_HMC_PD_BP_BUF_ALIGNMENT)
                                page->va = dma_alloc_coherent(dev->hw->device, page->size, &page->pa,GFP_KERNEL)
                                memcpy(&pd_entry->bp.addr, page, sizeof(pd_entry->bp.addr))
                                pd_entry->bp.entry_type = IRDMA_SD_TYPE_PAGED
                                irdma_invalidate_pf_hmc_pd(dev, sd_idx, rel_pd_idx) -> делать PF Аппаратное обеспечение pd Кэш недействителен
                                    writel(val, dev->hw_regs[IRDMA_PFHMC_PDINV])
                        irdma_hmc_finish_add_sd_reg(dev, info) -> irdma_hmc_sd_grp -> для cqp настраивать sd вход Группа
                            for (i = sd_index; i < sd_index + sd_cnt; i++)
                                irdma_set_sd_entry(pa, i, sd_entry->entry_type,
                                or irdma_clr_sd_entry(i, sd_entry->entry_type,
                                ret_code = dev->cqp->process_cqp_sds(dev, &sdinfo)
        irdma_initialize_hw_rsrc -> инициализацияаппаратное обеспечениересурсотслеживатьчисло Группа
            if (rf->rdma_ver != IRDMA_GEN_1)
                rf->allocated_ws_nodes = bitmap_zalloc(IRDMA_MAX_WS_NODES,
                set_bit(0, rf->allocated_ws_nodes)
            rsrc_size = irdma_calc_mem_rsrc_size(rf) -> Рассчитать размер ресурса памяти
                rsrc_size = sizeof(struct irdma_arp_entry) * rf->arp_table_size
                rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_qp)
                ...
            rf->mem_rsrc = vzalloc(rsrc_size) -> Выделить виртуальную непрерывную память и заполнить ее нулями
            rf->arp_table = (struct irdma_arp_entry *)rf->mem_rsrc
            irdma_set_hw_rsrc(rf) -> в соответствии сбазовый адрескомпенсироватьи Зарезервировать местонастраивать Различная физикаресурс(QP,CQ,MR,PD,AH,MCG,ARP,qp_table, cq_table) базовый адрес
            rf->mr_stagmask = ~(((1 << mrdrvbits) - 1) << (32 - mrdrvbits))
        irdma_create_ccq -> Создайте очередь завершения для контроля операций.
            ccq->shadow_area.size = sizeof(struct irdma_cq_shadow_area)
            ccq->mem_cq.va = dma_alloc_coherent
            info.num_elem = IW_CCQ_SIZE -> 2048
            irdma_sc_ccq_init(dev->ccq, &info)
                cq->cq_type = IRDMA_CQ_TYPE_CQP
                IRDMA_RING_INIT(cq->cq_uk.cq_ring, info->num_elem)
                cq->cq_uk.polarity = true -> Бит полярности/реверсивный/действительный бит
            irdma_sc_ccq_create(dev->ccq, 0, true, true)
                irdma_sc_cq_create(ccq, scratch, check_overflow, post_sq) -> Создать очередь завершения
                     irdma_sc_add_cq_ctx(ceq, cq) -> для ceq добавить в cq ctx отслеживать
                        ceq->reg_cq[ceq->reg_cq_size++] = cq
                     ...
                irdma_sc_ccq_create_done -> irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CQ, NULL) -> ждать CQP SQ Завершено один раз за наконец
                    while (1)
                        irdma_sc_ccq_get_cqe_info
                            polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, temp)
                            IRDMA_RING_MOVE_HEAD ->  move the head for cq
                            IRDMA_RING_MOVE_TAIL ->  update cq tail in cq shadow memory also
                        udelay(cqp->dev->hw_attrs.max_sleep_count)
                ccq->dev->cqp->process_cqp_sds = irdma_cqp_sds_cmd
        irdma_setup_ceq_0 -> Создать CEQ 0 и его ресурсы прерываний -> для Место有оборудование Заканчиватьгруппа инцидентов Списокраспространятьодининдивидуальный Списокповерхность,создаватьceq 0и настроить егоmsixвектор прерываниявозвращаться0,еслинастраиватьуспех,нетновозвращатьсяошибка
            num_ceqs = min(rf->msix_count, rf->sc_dev.hmc_fpm_misc.max_ceqs
            rf->ceqlist = kcalloc(num_ceqs, sizeof(*rf->ceqlist), GFP_KERNEL)
            irdma_create_ceq(rf, iwceq, 0, &rf->default_vsi) -> Создать очередь событий завершения
                irdma_sc_ceq_init(&iwceq->sc_ceq, &info)
                irdma_cqp_ceq_cmd(&rf->sc_dev, &iwceq->sc_ceq, IRDMA_OP_CEQ_CREATE)
                or irdma_sc_cceq_create(&iwceq->sc_ceq, 0)
            irdma_cfg_ceq_vector(rf, iwceq, 0, msix_vec) -> для Заканчиватьгруппа инцидентов Списокнастраиватьсерединаперерыв
                if (rf->msix_shared && !ceq_id)
                    tasklet_setup(&rf->dpc_tasklet, irdma_dpc)
                    request_irq(msix_vec->irq, irdma_irq_handler, 0,
                else
                    tasklet_setup(&iwceq->dpc_tasklet, irdma_ceq_dpc)
                        irdma_process_ceq(rf, iwceq)
                            do cq = irdma_sc_process_ceq(dev, sc_ceq)
                                ceq->polarity ^= 1
                                irdma_sc_cq_ack(cq)
                            queue_work(rf->cqp_cmpl_wq, &rf->cqp_cmpl_work)
                            irdma_puda_ce_handler(rf, cq)
                                do {
                                    irdma_puda_poll_cmpl(dev, cq, &compl_error)
                                        if (info.q_type == IRDMA_CQE_QTYPE_RQ)
                                            irdma_puda_poll_info(cq, &info)
                                                cqe = IRDMA_GET_CURRENT_CQ_ELEM(&cq->cq_uk)
                                                    (_cq)->cq_base[IRDMA_RING_CURRENT_HEAD((_cq)->cq_ring)].buf
                                                get_64bit_val(cqe, 24, &qword3)
                                                info->qp = (struct irdma_qp_uk *)(unsigned long)comp_ctx
                                                ...
                                            dma_sync_single_for_cpu -> Убедитесь, что данные в буфере DMA синхронизированы с данными в физической памяти. Если вам нужно, чтобы данные Воли считывались из памяти устройства, вам следует использовать функция dma_sync_single_for_cpu(). Если вам нужно записать данные Воли из памяти на приезжающее устройство, вам следует использовать функция dma_sync_single_for_device()
                                            irdma_puda_get_tcpip_info -> get tcpip info from puda buffer
                                                if (buf->vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
                                                    irdma_gen1_puda_get_tcpip_info(info, buf)
                                                        if (ethh->h_proto == htons(0x8100))
                                                            buf->vlan_id = ntohs(((struct vlan_ethhdr *)ethh)->h_vlan_TCI) & VLAN_VID_MASK
                                                            ip6h = (struct ipv6hdr *)buf->iph
                                                buf->ipv4 = info->ipv4
                                                buf->seqnum = ntohl(tcph->seq)
                                                ether_addr_copy(buf->smac, info->smac)
                                            rsrc->receive(rsrc->vsi, buf) -> irdma_ieq_receive
                                                qp = irdma_ieq_get_qp(vsi->dev, buf)
                                                irdma_ieq_handle_exception(ieq, qp, buf)
                                                    irdma_ieq_check_first_buf(buf, fps)
                                                    irdma_send_ieq_ack(qp)
                                            irdma_ilq_putback_rcvbuf
                                            or irdma_puda_replenish_rq
                                                irdma_puda_get_bufpool
                                                    irdma_puda_get_listbuf
                                                irdma_puda_post_recvbuf
                                        else
                                            rsrc->xmit_complete(rsrc->vsi, buf -> irdma_ieq_tx_compl
                                                irdma_puda_ret_bufpool
                                                    list_add(&buf->list, &rsrc->bufpool)
                                            irdma_puda_send_buf
                                                irdma_puda_send
                                                    wqe = irdma_puda_get_next_send_wqe(&qp->qp_uk, &wqe_idx)
                                                    irdma_uk_qp_post_wr(&qp->qp_uk)
                                                        writel(qp->qp_id, qp->wqe_alloc_db)
                                    irdma_sc_ccq_arm(cq)
                                        writel(ccq->cq_uk.cq_id, ccq->dev->cq_arm_db)
                                }
                        irdma_ena_intr(&rf->sc_dev, iwceq->msix_idx) -> dev->irq_ops->irdma_en_irq(dev, msix_id) -> icrdma_ena_irq -> Включить прерывания
                            writel(val, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + idx)
                    request_irq(msix_vec->irq, irdma_ceq_handler, 0,
                        tasklet_schedule(&iwceq->dpc_tasklet)
                cpumask_clear(&msix_vec->mask)
                cpumask_set_cpu(msix_vec->cpu_affinity, &msix_vec->mask)
                irq_update_affinity_hint(msix_vec->irq, &msix_vec->mask)
                rf->sc_dev.irq_ops->irdma_cfg_ceq(&rf->sc_dev, ceq_id, msix_vec->idx, true) -> icrdma_cfg_ceq
                    writel(reg_val, dev->hw_regs[IRDMA_GLINT_CEQCTL] + ceq_id)
            irdma_ena_intr(&rf->sc_dev, msix_vec->idx)
        INIT_WORK(&rf->cqp_cmpl_work, cqp_compl_worker) -> irdma_cqp_ce_handler
            wake_up(&cqp_request->waitq)
            or cqp_request->callback_fcn(cqp_request)
        irdma_sc_ccq_arm
    ice_get_qos_params
    irdma_fill_qos_info
        l2params->vsi_prio_type = qos_info->vport_priority_type
        l2params->tc_info[i].rel_bw = qos_info->tc_info[i].rel_bw
        memcpy(l2params->dscp_map, qos_info->dscp_map, sizeof(l2params->dscp_map))
    irdma_rt_init_hw -> организация аппаратной среды выполнения, ILQ, IEQ, CEQs and PBLEs
        irdma_sc_vsi_init
        irdma_setup_cm_core
        irdma_vsi_stats_init
        do {
            if (!iwdev->roce_mode) -> Режим без RoCE
            irdma_initialize_ilq -> create iwarp local queue for cm
            irdma_initialize_ieq
                irdma_puda_create_rsrc
                    irdma_puda_qp_create
                        irdma_cqp_qp_create_cmd
                            cqp_info->cqp_cmd = IRDMA_OP_QP_CREATE
            irdma_setup_ceqs -> Управление устройствами ceq и его ресурсы прерываний, @rf: RDMA PCI функция @vsi:этот CEQ из VSI структура для Место有оборудование Заканчиватьгруппа инцидентов Списокраспространять Списокповерхность создавать ceq и настроить его msix вектор прерывания если ceq успех
                irdma_create_ceq
                irdma_cfg_ceq_vector
                irdma_ena_intr
            irdma_hmc_init_pble -> Initialize pble resources during module load
                pble_rsrc->fpm_base_addr = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].base
                INIT_LIST_HEAD(&pble_rsrc->pinfo.clist)
                add_pble_prm(pble_rsrc)
            irdma_setup_aeq
                irdma_create_aeq
                irdma_cfg_aeq_vector
                irdma_ena_intr
            irdma_alloc_set_mac -> set up a mac address table entry
                irdma_alloc_local_mac_entry
                    cqp_info->cqp_cmd = IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY
                irdma_add_local_mac_entry
                    cqp_info->cqp_cmd = IRDMA_OP_ADD_LOCAL_MAC_ENTRY
            irdma_add_ip -> add ip addresses
                irdma_add_ipv4_addr
                    ip_addr = ntohl(ifa->ifa_address)
                    irdma_manage_arp_cache(iwdev->rf, dev->dev_addr, &ip_addr, true, IRDMA_ARP_ADD) -> manage hw arp cache
                        arp_index = irdma_arp_table(rf, ip_addr, ipv4, mac_addr, action)
                        cqp_request = irdma_alloc_and_get_cqp_request(&rf->cqp, false)
                        cqp_info->cqp_cmd = IRDMA_OP_ADD_ARP_CACHE_ENTRY
                irdma_add_ipv6_addr -> ВоляIPv6адресдобавить вприжать аппаратное обеспечение ARPповерхностьсередина
                    idev = __in6_dev_get(ip_dev)
                    irdma_copy_ip_ntohl(local_ipaddr6, ifp->addr.in6_u.u6_addr32)
                        *dst++ = ntohl(*src++);
                        ...
            iwdev->cleanup_wq = alloc_workqueue("irdma-cleanup-wq",
            irdma_get_used_rsrc -> Определить внутренние ресурсы
                iwdev->rf->used_pds
                ...
            init_waitqueue_head
        }
        irdma_rt_deinit_hw(iwdev) -> clean up the irdma device resources -> Очистка ресурсов устройства на основе конечного автомата
            switch (iwdev->init_state)
    irdma_ib_register_device
    ice_rdma_update_vsi_filter -> update main VSI filters for RDMA -> get ice eth api
        vsi = ice_find_vsi(pf, vsi_id)
        ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable) -> enable/disable RDMA filtering on VSI
            cached_ctx = ice_get_vsi_ctx(hw, vsi_handle)
            ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID)
            ice_update_vsi
                ice_aq_update_vsi -> Лед: расширение VSI Ручка изиспользовать 1/2 Раздел, ВСИ Обрабатывать только обслуживание водителя по индивидуальному номеру, используемому для уникальной идентификации. VSI。 VSI ручка Зависит от Аппаратное обеспечение VSI Поддержка нумерации. При взаимодействии с оборудованием дескриптор VSI преобразуется в номер VSI. существоватьпредставлять на рассмотрение 0f9d5027a749 ("лед: рефакторинг VSI Процесс выделения, удаления и реконструкции"), введено VSI ручка,но толькосуществоватьсоздаватьиудалить VSI часиспользовать。 Этот патч является одним из двух отдельных патчей, которые расширяют VSI ручкасуществоватьводитель, остальное изиспользовать. этотснаружи,существоватьэтотпластырьсередина,Должен быть рефакторингпоколениекодизнекоторый Частично верноиспользовать VSI ручка
                    ice_fill_dflt_direct_cmd_desc
                    cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID)
                    status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, -> send FW Admin Queue command to FW Admin Queue
                        ice_sq_send_cmd_retry
                            ice_sq_send_cmd -> send command to Control Queue (ATQ)
                                desc_on_ring = ICE_CTL_Q_DESC(cq->sq, cq->sq.next_to_use)
                                wr32(hw, cq->sq.tail, cq->sq.next_to_use)
                                ice_flush(hw)
                                udelay(5)
    auxiliary_set_drvdata




static const struct irdma_irq_ops icrdma_irq_ops = {
	.irdma_cfg_aeq = irdma_cfg_aeq,
	.irdma_cfg_ceq = icrdma_cfg_ceq,
	.irdma_dis_irq = icrdma_disable_irq,
	.irdma_en_irq = icrdma_ena_irq,
};
           

Назначьте аппаратный адрес BAR0 и регистр регистрации.

Язык кода:javascript
копировать
register addr,
static int irdma_probe(
    struct ice_pf *pf = iidc_adev->pf
    irdma_fill_device_info(iwdev, pf, vsi)
        rf->hw.hw_addr = pf->hw.hw_addr; <- info.bar0 = rf->hw.hw_addr;
    irdma_ctrl_init_hw
        irdma_setup_init_state
            static int irdma_initialize_dev
                info.bar0 = rf->hw.hw_addr;
                irdma_sc_dev_init
                    dev->hw->hw_addr = info->bar0
                    irdma_sc_init_hw                    
                        icrdma_init_hw
                            dev->hw_regs[i] = (u32 __iomem *)(hw_addr + icrdma_regs[i]) -> Зарегистрироваться
​
irdma_sc_cqp_get_next_send_wqe_idx
    IRDMA_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, *wqe_idx, ret_code)
    wqe = cqp->sq_base[*wqe_idx].elem -> Заполните порядок от базового адреса DMAиз ВА до следующего
    IRDMA_CQP_INIT_WQE(wqe) -> #define IRDMA_CQP_INIT_WQE(wqe) memset(wqe, 0, 64) -> WQEразмердля64Характер Фестиваль
​
​
​
ring, поверхность кольцевой цепи, Вынув из головы один юань, Указатель головы Воли перемещается на одну позицию назад.
#define IRDMA_RING_MOVE_HEAD(_ring, _retcode) \
    { \
        register u32 size; \
        size = (_ring).size;  \
        if (!IRDMA_RING_FULL_ERR(_ring)) { \
            (_ring).head = ((_ring).head + 1) % size; \
            (_retcode) = 0; \
        } else { \
            (_retcode) = -ENOMEM; \
        } \
    }
​
Выделите раздел устройства и совместного использования программного обеспечения и памяти DMA, делатьдляотправляющая команда Списокиз Память, начинатьVAделатьдляотправляющая команда Списокизбазовый адрес
cqp->sq.va = dma_alloc_coherent(dev->hw->device, cqp->sq.size, &cqp->sq.pa, GFP_KERNEL);

Очередь завершения опроса пользовательского режима

Язык кода:txt
копировать
static inline int ibv_poll_cq -> .poll_cq = irdma_upoll_cq, -> опрос CQ Для получения (возможно более индивидуального) завершения. есливозвращаться стоимости < 0, возникает ошибка. есливозвращаться стоимости >= 0,нодлявозвращатьсяиз Заканчиватьчисло。 есливозвращаться стоимости Нет负且严格小Вnum_entries,ноCQПустой
    ret = __irdma_upoll_cq(iwucq, num_entries, entry)
        list_for_each_safe(&iwucq->resize_list, cq_buf, next, list) -> Перейти впередResizeиз CQ поверхность буферной колонны
            while (npolled < num_entries)
                ret = irdma_poll_one(&cq_buf->cq, cur_cqe, entry ? entry + npolled : NULL); -> ret 0 = success
                    int ret = irdma_uk_cq_poll_cmpl(ukcq, cur_cqe)
                        cqe = IRDMA_GET_CURRENT_CQ_ELEM(cq) -> ( (cq)->cq_base[(((cq)->cq_ring).head)].buf ) -> get cqe from cq_ring head
                        get_64bit_val(cqe, 24, &qword3)
                        polarity = (__u8)FIELD_GET(IRDMA_CQ_VALID, qword3)
                        return ENONENT -> провайдеры/irdma: удалить enum irdma_status_code ,- использовать Linux Настройка замены кода ошибки irdma Код состояния изиспользовать. - Удалить перечисление irdma_status_code и Определите его из заголовочного файла. - удалитьнекоторыйфункциясерединамного Оставатьсяиз“ret”Изменятьколичество。 потому что irdma_status_code заменен на для int,потому чтоэтот Нет Нужно дваиндивидуальный Изменятьколичество Приходитьдержатьошибкапоколениекод。 - удалить Нет Нужно это сноваизизбыточностьинициализация
                        udma_from_device_barrier(); -> Обязательно проверьте действительный бит перед чтением CQE содержание -> asm volatile("lfence" ::: "memory")
                        ...
                        info->q_type = (__u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
                        info->qp_handle = (irdma_qp_handle)(uintptr_t)qp;
                        info->comp_status = IRDMA_COMPL_STATUS_SUCCESS;
                        ...
                        get_64bit_val(cqe, 0, &qword0);
                        get_64bit_val(cqe, 16, &qword2);
                        get_64bit_val(cqe, 8, &comp_ctx);
                        if (info->q_type == IRDMA_CQE_QTYPE_RQ)
                            info->wr_id = qp->rq_wrid_array[array_idx]
                            IRDMA_RING_SET_TAIL(qp->rq_ring, array_idx + 1) -> (qp->rq_ring).tail = (array_idx + 1) % (qp->rq_ring).size
                        else { /* q_type is IRDMA_CQE_QTYPE_SQ */
                            if (qp->first_sq_wq)
                                irdma_uk_cq_poll_cmpl -> recu
                    irdma_process_cqe_ext
                    or
                    irdma_process_cqe
                        entry->status = IBV_WC_SUCCESS
                        entry->wc_flags |= IBV_WC_WITH_IMM
                        set_ib_wc_op_sq(cur_cqe, entry); -> службы/irdma: исправить RQ Код операции завершения, RQ CQE середина HW Код операции записи берется из пакета приема. RoCEv2/iWARP код операции протокола вместо того, когда вперед предполагается из SW код операции. Автор: Воля CQE серединаиз Грубый трахделатьтипи Команда Списоктипвозвращатьсяприезжать irdma_process_cqe идобавить в 2 индивидуальныйпомощник set_ib_wc_op_sq set_ib_wc_op_rq Воля IRDMA HW op Тип картографии приезжать IB op Типа приходит ремонтэтот проблема. пожалуйста Уведомление,верно В iWARP,Только одобрение напишите сейчас,потому чтоэтоткогдажитьсуществоватьнемедленноданныечас,Держатьделатькод只能да IB_WC_RECV_RDMA_WITH_IMM
                            case IRDMA_OP_TYPE_RDMA_WRITE
                                entry->opcode = IBV_WC_RDMA_WRITE; -> set wc opcode
                        or
                        set_ib_wc_op_rq(cur_cqe, entry,
        while (npolled < num_entries)
            irdma_poll_one
        irdma_process_resize_list
            list_for_each_safe(&iwucq->resize_list, cq_buf, next, list)
                list_del(&cq_buf->list)
                irdma_free_cq_buf(cq_buf
        irdma_uk_cq_set_resized_cnt
            sw_cq_sel += cq_cnt;
            set_64bit_val(cq->shadow_area, 32, temp_val)

ссылка

Intel E810 datasheet

Intel E810 Реализация RDMA (irdma): https://lore.kernel.org/all/20210520143809.819-7-shiraz.saleem@intel.com/T/

Язык кода:c
копировать
intel e810,
commit: https://lore.kernel.org/all/20210520143809.819-7-shiraz.saleem@intel.com/T/
к Внизпластырьсистема Списокпредставилподходящийиспользовать В X722 iWARP Оборудованиесистемаодин Интел RDMA (irdma) Драйверы и поддержка протокола Ethernet iWARP и RoCEv2 изновый E810 оборудование. irdma модуль заменяет X722 старая версия i40iw модуль,ибыл продлендля i40iw Определение ABI。 Он обратно совместим со старыми версиями. X722 rdma основной поставщик (libi40iw)。 X722 и E810 это поддержка RDMA из PCI сетьоборудование. Долженотец Оборудование RDMA блок пройдениспользоватьнедавнодля 5.11 Ядродобавить визосновной Вспомогательныйосновы автобусаструктура Экспортприезжать“irdma”из Вспомогательныйоборудование Приходитьповерхность Показывать。 отец PCI netdev Драйвер «i40e» и «ice» используют инкапсуляцию личных данных/помощь при регистрации операций. RDMA оборудование,Этиданные/Держатьделатьобязательностьприезжатьсуществовать irdma модульсерединазарегистрироватьсяиз Вспомогательныйводитель。 Долженпластырьсначала коллекцияделатьдля RFC представлять на рассмотрение,нассуществовать Чтосерединапридетсяприезжатьобратная связь,предложенный RDMA Дополнение для водителя netdev PCI водитель [1] собственный PCI Оборудование Проходитьиспользоватьплан。 Изучите шину использования платформы и MFD изрешатьплан,Но был отвергнут сообществом,Консенсусдобавить вновыйиз Автобусная инфраструктура приходитподдерживатьэтотдобрыйиспользовать Модель。 Были представлены дальнейшие доработки серии из и вспомогательной шины [2]. этотчас,Greg KH Попросите наш процесс проверки и доработки вспомогательной шины Volya включить во внутренний список рассылки и получить признание уважаемых участников из Ядро, а также включить Nvidia существовать Внутриизвсе ключевые заинтересованные стороныизконсенсус(использовать В mlx5 ребенок Функцияиспользовать) - Корпус) и водитель Intel Sound. Этот индивидуальный процесс занял некоторое время и затруднил netdev/irdma Серия в доработке/пересмотре. Вспомогательныйавтобусный финалсуществовать5.11середина Будьте объединеныи。 существовать На этот разпредставлять на рассмотрениеиз v1-->v2 и v4-->v5 между,IIDC провел серьезную переработку на основе отзывов,наснадеюсь, что оно появитсясуществовать Больше в соответствии с сообществомизнуждаться。 глазвперед,E810 по умолчаниюдля RoCEv2。 существоватьбудущееизпластырьсередина,Воляпрошёл devlink Обеспечить правильное переключение протокола iWARP поддержка во время выполнения. Долженсистема Списокда针верно 5.13-rc1 Сборка из, проект вперед содержит netdev Патч для более удобного просмотра. этот包括Даженовый“ice”водителькпоставлять RDMA поддерживать,и Воля“i40e”водитель Конвертироватьдляиспользовать Вспомогательныйосновы автобуса设施。 один После подтверждения сообществомэтотпредставлять на рассмотрение,Сразу Можетпредставлять на обработка общего запроса на извлечение. v5-->v6:*Воля aux Имя устройства начинается с <модуль>.intel_rdma_<rdma протокол>.<num> Сжатиедля <модуль>.<rdma протокол>.<num> *ремонт alloc_hw_stats изводитель API, экспортировать только статистику портов sysfs v4-->v5:*Экспорт Место有 IIDC Обратный вызов основной операции и из irdma прямойнастраиватьиспользовать。 irdma зависит от i40e иice。 *Удалить переключатель протокола из devlink Параметры времени выполнения. E810 начальствопо умолчаниюдля RoCEv2。 Воляпрошёл [3] серединаобсуждатьизобщественный работникделатьдобавить ввыключательприезжать IWARP из Параметры времени выполнения *Экспорт iidc_auxiliary_dev серединаизice_pf указатель,Долженуказательсуществовать irdma drv.probe() середина Можетиспользовать,ииспользоватьэто происходит PCI функциякоррелятор Поле。 *использоватьопределение Приходитьнастраивать Вспомогательный Название разработки,и Нетда kasprintf。 *удалить IIDC серединаиз Место有будущее Конфигурация。 удалить IIDC серединаизмногоиндивидуальный Вспомогательныйводительподдерживать。 *добавить восновнойводительиз Вспомогательный Держатьделатьперезвонитьс прямымсуществовать iidc_auxiliary_drv вернослонсерединаиспользовать。 *ремонтiceсерединаизauxdevice idaресурсутечка,и Даженовыйприезжатьi40eсерединабольшинствоновыйизida API。 *удалить IIDC и irdma водительсерединалюбой остатокиз VF остаток. *упрощать IIDC API кдобавить виудалить RDMA qset。 удалить iidc_res_base соединениеиспользовать。 *использоватьпрямойнастраиватьиспользовать Конвертировать irdma серединаиз Место有单одинвыполнитьмежду接 .ops перезвонить *добавить в rsvd толькоиспользовать В irdma ABI серединаизверновместе * Очистка iw_memreg_type enum v3-->v4: * ремонтледпластырьсерединаиз W=1 предупреждать * Исправлено использовать Всоздаватьиспользоватьсемья AH имноготранслироватьиз pyverbs * ремонтсуществовать v2 представлять на рассмотрение v2-->v3 серединапересадкаприезжать FIELD_PREP В этот период возникла проблема быстрого набора регистров и дескрипторов: * rebase rdma for-next。 Адаптируйте изменение ядра «1fb7f8973f51 («RDMA: поддержка более 255 индивидуальных портов rdma»)» * irdma Kconfig обновлен в соответствии со стилем кодирования Linux. * ремонт 0-day Проблемы со сборкой * удалить rdma_resource_limits селектор devlink параметр. в соответствии с Parav изпредположениепредставлять на рассмотрениепластырькиспользовать devlink ресурс. * Ice idc Аббревиатура серединаиз пишется с заглавной буквы. Например 'aux' приезжать 'AUX' v1-->v2: * удалить IIDC Работа канала - открыть, закрыть, одноранговый_регистр иpeer_unregister。 и Что Место有СвязанныйизFSMВсесуществоватьice PCIосновнойводительсередина。 * существоватьпроблема IIDC ops перезвонитьчас,существоватьice PCI основнойводительсерединаиспользовать device_lock。 * Поделиться из IIDC заголовоксерединаудалитьpeer_* формулировка,ииспользовать iidc_core*/iidc_auxiliary* Переименоватьструктураи Работа канала。 * существоватьirdma gen2Вспомогательныйводительсерединаначинатьчасраспространятьib_deviceисуществоватьdrv.probe()Заканчиватьчасзарегистрироватьсяэто。 * существоватьбольшоймногочисловодительсерединаширокоиспользовать ibdev_* Распечататьудалить idev_to_dev、ihw_to_dev Макрос,потому чтодляновый Распечататьплансередина Нет Нужно это снова Эти Макрос。 * Не изменять ABI Версия. irdma для 6。 поддерживать irdma ABI Версия. 5 поверхность Показывать Старая версия i40iw использоватьсемья-Совместимость с провайдером。 * существовать irdma_alloc_ucontext Добавить Проверка границ,кпредотвратить < 4 использоватьсемьякосмоспоставлятьпрограмма Версияиз Привязка не удалась。 * от irdma серединаудалить devlink。 добавить в 2 индивидуальныйновыйиз rdma Связанныйсодержаниеdevlink параметрдобавить вприезжатьice PCI основнойводительсередина。 * существоватьдескриптор Полеизполучать/настраиватьначальствоиспользоватьFIELD_PREP/FIELD_GET/GENMASK,и Нетда自行开发изLS_*/RS_*。 * существовать irdma серединаобязательность 2 индивидуальныйнезависимыйиз Вспомогательныйводитель - одининдивидуальныйиспользовать ВНет. 1 поколение,одининдивидуальныйиспользовать ВНет. 2 поколениеибудущееизоборудование. * другой. irdma серединаизводительремонт [1] https://patchwork.kernel.org/project/linux-rdma/patch/20190215171107.6464-2-shiraz.saleem@intel.com/ [2] https://lore.kernel.org/ linux-rdma/20200520070415.3392210-1-jeffrey.t.kirsher@intel.com/ [3] https://lore.kernel.org/linux-rdma/20210407224631.GI282464@nvidia.com/ Dave Ertman (4):iidc :вестивходитьiidc.hice:инициализацияRDMAподдерживатьice:выполнитьiidcДержатьделатьice:зарегистрироваться ВспомогательныйоборудованиекпоставлятьRDMA Michael J. Ruhl(1):RDMA/irdma:дляCM Mustafa Ismailдобавить вдинамичныйотслеживать(13):RDMA/irdma: зарегистрироваться Вспомогательныйводительивыполнить Специализируйтесьиспользовать Проходитьдорога OP RDMA/irdma:выполнитьоборудованиеинициализацияопределение RDMA/irdma:выполнитьаппаратное обеспечение管理Команда Список OP RDMA/irdma: Добавить HMC Резервное хранилищенастраиватьфункция RDMA/irdma: Добавитьпривилегия UDA Команда Списоквыполнить RDMA/irdma: Добавить QoS определение RDMA/irdma: Добавить диспетчер соединений RDMA/irdma: Добавить PBLE Исследователь RDMA/irdma:выполнитьоборудованиеподдерживатьизглагол API RDMA/irdma: Добавить RoCEv2 UD OP поддерживать RDMA/irdma: Добавитьиспользоватьсемья/Ядрообщая библиотека RDMA/irdma: Добавить杂项 实использоватьпрограммаопределение RDMA/irdma: Добавить ABI определение Shiraz Saleem (4):i40e:для aux Подготовка к переоборудованию автобуса i40e заголовок i40e: Зарегистрируйте дополнительное устройство, чтобы предоставить RDMA RDMA/irdma: Добавить irdma Kconfig/Makefile иудалить i40iw RDMA/irdma:Даженовыйподдерживать ВОЗ документ

Сяобин (ssbandjl)

блог: https://cloud.tencent.com/developer/user/5060293/articles | https://logread.cn | https://blog.csdn.net/ssbandjl | https://www.zhihu.com/people/ssbandjl/posts

столбец ДПУ

https://cloud.tencent.com/developer/column/101987

Технические друзья: добро пожаловатьверноDPU/Умный сетевой адаптер/удалить/сеть,ускорение хранения данных/Интересуются такими технологиями, как изоляция безопасностииз Друзья присоединяйтесьТехнология ДПУКоммуникационная группа

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.