enum {
RDMA_NL_IWCM = 2,
RDMA_NL_RSVD,
RDMA_NL_LS, /* RDMA Local Services */
RDMA_NL_NLDEV, /* RDMA device interface */
RDMA_NL_NUM_CLIENTS
};
RXEВведение:
Водитель проходит Linux Реализация сетевого стека InfiniBand RDMA передача инфекции. Он позволяет системам со стандартными адаптерами Ethernet взаимодействовать с RoCE адаптер или запустить RXE Драйвер взаимодействует с другой системой. связанный InfiniBand и RoCE Документация для www.infinibandta.org и www.openfabrics.org скачать. (См. также суу, это iWARP аналогичные программные драйверы. ) Драйвер разделен на два слоя, один из которых Linux RDMA интерфейс стека и реализация команд ядра или пользовательского пространства. API。 глагол пользовательского пространства API Нужно имя по имени librxe Библиотека поддержки, разработанная Universal глагол. пользовательского пространства API libibverbs нагрузка. Еще один слой и первый 3 слоистый Linux интерфейс сетевого стека. Для настройки и использования soft-RoCE драйвер, используйте «Настроить Soft-RoCE (RXE)» ниже. wiki страница:https://github.com/linux-rdma/rdma-core/blob/master/Documentation/rxe.md
/* Management 0x00000FFF */
#define RDMA_CORE_CAP_IB_MAD 0x00000001
#define RDMA_CORE_CAP_IB_SMI 0x00000002
#define RDMA_CORE_CAP_IB_CM 0x00000004
#define RDMA_CORE_CAP_IW_CM 0x00000008
#define RDMA_CORE_CAP_IB_SA 0x00000010
#define RDMA_CORE_CAP_OPA_MAD 0x00000020
rdma_rxe.ko зависит от ib_core.ko, ib_uverbs.ko и других сетевых модулей. Подробнее см.:
drivers/infiniband/Kconfig
# SPDX-License-Identifier: GPL-2.0-only
config RDMA_RXE
tristate "Software RDMA over Ethernet (RoCE) driver"
depends on INET && PCI && INFINIBAND -> Зависит от модулей, связанных с RDMA
depends on INFINIBAND_VIRT_DMA
Модуль rdma определяется следующим образом:
drivers/infiniband/Kconfig
# SPDX-License-Identifier: GPL-2.0-only
menuconfig INFINIBAND
tristate "InfiniBand support"
depends on HAS_IOMEM && HAS_DMA
depends on NET
depends on INET
depends on m || IPV6 != m
depends on !ALPHA
select IRQ_POLL
select DIMLIB
help
Core support for InfiniBand (IB). Make sure to also select
any protocols you wish to use as well as drivers for your
InfiniBand hardware.
if INFINIBAND
config INFINIBAND_USER_MAD
tristate "InfiniBand userspace MAD support"
depends on INFINIBAND
3.7.5.1 Управление подсетями Управление Подсетями фактически делится на Управление подсетямиустройство (SM) Приложения и Управление подсетямиактерское мастерство (SMA)。 Для каждой подсети требуется только одно Управление. Подсетями сервера он может находиться на любом существующем узле, включая коммутаторы и маршрутизаторы. Управление подсетями использует специальный класс управляющих датаграмм. (MAD), известный как Управление пакет данных подсетей (SMP), который направляется в специальную пару очередей (QP0)。 Как показано на картинке 30 Как показано, каждый порт имеет QP0, каждый узел содержит СМА для: • иметь дело с QP0 получено на Get() и Set() SMP • Воля GetResp() SMP отправить QP0 • Воля Trap() SMP отправить QP0 A Управление подсетямиустройство: • ВоляSMP Из QP0 Отправить на QP0 на любой порт • иметь дело сQP0 Все полученные SMP (по SMA узла) иметь дело с СМП кроме)
3.7.5.2 Общие услуги Общие Агент услуг (GSA*) на самом деле состоит из множества агентов управляемых услуг. показано на картинке 31 показано. Некоторые услуги являются дополнительными. Использование общего сервиса называется общим пакетом управления. (GMP) формат сообщения, который представляет собой управляющую дейтаграмму (MAD), обычно направляемый на общий сервисный интерфейс, называемый (GSI) специальная пара очередей (QP1)。 Как показано на картинке 31 Как показано, каждый порт имеет QP1,QP1 все получено на GMP одним из GSA иметь дело с。 GSA действительно может предоставить свою конкретную категорию услуг GMP перенаправить на другую пару очередей, позволяя каждому GSA Поддерживайте собственный интерфейс связи
Я возьму, например, rdma_rxe.ko: выполнить modinfo view Что использоватьib_coreиib_uverbs
когда Пользовательский режимiproute2/rdmaвыполнение библиотекиrdma link add rxe_ens3 type rxe netdev ens3час
qemu_vm:
/root/project/rdma/iproute2/rdma
gdb --args ./rdma link add rxe_ens3 type rxe netdev ens3
main
filename = basename(argv[0]);
err = rd_init(&rd, filename);
rd_prepare_msg
err = rd_batch(&rd, batch_file, force)
rd_cmd(&rd, argc, argv)
rd_exec_cmd
rd_argv_match
c->func(rd) -> int cmd_link
rd_exec_cmd -> link_add
link_add -> link_add_type -> link_add_netdev
rd_prepare_msg(rd, RDMA_NLDEV_CMD_NEWLINK, &seq, -> to kernel Перейдите в режим ядра через Netlink
mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd->link_name);
...
Динамически загружать модуль rdma_rxe.ko в режиме ядра и загружать его зависимые модули.
kernel: RDMA_NLDEV_CMD_NEWLINK
static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
[RDMA_NLDEV_CMD_GET] = {
.doit = nldev_get_doit,
.dump = nldev_get_dumpit,
},
[RDMA_NLDEV_CMD_GET_CHARDEV] = {
.doit = nldev_get_chardev,
},
[RDMA_NLDEV_CMD_SET] = {
.doit = nldev_set_doit,
.flags = RDMA_NL_ADMIN_PERM,
},
[RDMA_NLDEV_CMD_NEWLINK] = {
.doit = nldev_newlink, -> Согласно команде RDMA_NLDEV_CMD_NEWLINK, отправленной из пользовательского режима, Выполните эту функцию doit
.flags = RDMA_NL_ADMIN_PERM,
},
Загрузка модулей и зависимых модулей: MODULE_ALIAS_RDMA_LINK("rxe");
nldev_newlink
nlmsg_parse_deprecated
dev_get_by_name
link_ops_get
CONFIG_MODULES
request_module("rdma-link-%s", type) <- #define MODULE_ALIAS_RDMA_LINK(type) MODULE_ALIAS("rdma-link-" type) -> MODULE_ALIAS_RDMA_LINK("rxe"); -> динамическая нагрузка
ops->newlink(ibdev_name, ndev)
drivers/infiniband/core/device.c
fs_initcall(ib_core_init); -> RDMA/core:Воля sysfs Просмотр ввода ограничен init_net, который представляет собой подготовительный патч для использования в существующем пространстве имен. rdma Изоляция оборудования. Первый шаг – сделать rdma оборудованиетолькосуществовать init net Виден в пространстве имен. Последующий патч использования Воля compat ib_core_device устройства/sysfs существует дерево, включено несколько сетевых пространств имен rdma Видимость устройства. Поскольку подсистема IB зависит от сети стек, поэтому его необходимо инициализировать после существованияnetdev, а поскольку он поддерживает устройства, его необходимо инициализировать до существования подсистемы устройств; Поэтому Воля initcall Порядок изменен на fs_initcall существует, чтобы он был скомпилирован в образ ядра ib_core следуй правильному init заказ
static int __init ib_core_init(void)
ib_wq = alloc_workqueue("infiniband", 0, 0)
ib_comp_unbound_wq -> IB/ядро: к новому CQ API Добавить несвязанный WQ Тип, вышестоящий коммит ядра Воля новый, указанный ниже CQ API Рабочая очередь изменена для привязки к конкретному ЦП (вместо несвязанного). Это приводит к появлению новых CQ API Все пользователи используют одну и ту же привязку WQ。 В частности, при привязке к WQ из CPU занят иметь дело с (более высокий приоритет) прерывание, MAD иметь дело с будет сильно задерживаться. Это приводит к Безумный ответ «сердцебиения» дело с задержкой, из-за которой порт неправильно классифицируется как «неработающий». решитьэтотвопрос,пожалуйста Кновыйиз CQ API добавить вновыйиз“Не связан”WQ введите, чтобы пользователь мог выбрать привязку WQ или несвязанный WQ。 для MAD,выбиратьновыйиз“Не связан”WQ
class_register(&ib_class) -> int class_register(const struct class *cls)
pr_debug("device class '%s': registering\n", cls->name)
error = sysfs_create_groups(&cp->subsys.kobj, cls->class_groups)
rdma_nl_init -> IB/core:существовать netlink информацияиметь дело Избегайте взаимоблокировок во время c, когда он не загружен rdmacm модуль, и при получении netlink сообщение, чтобы получить char информацию об устройстве, поскольку следующая последовательность вызовов используется для rdma_nl_mutex Выполняет рекурсивную блокировку, вызывая тем самым взаимоблокировку. [..] rdma_nl_rcv() mutex_lock() [..] rdma_nl_rcv_msg() ib_get_client_nl_info() request_module() iw_cm_init() rdma_nl_register() mutex_lock(); <- Тупик, снова получить мьютекс Из-за вышеописанной последовательности вызовов наблюдается следующая трассировка вызовов и взаимоблокировка. Ядро: __mutex_lock+0x35e/0x860 Ядро:? __mutex_lock+0x129/0x860 Ядро:? rdma_nl_register+0x1a/0x90 [ib_core] Ядро: rdma_nl_register+0x1a/0x90 [ib_core] Ядро:? 0xffffffffc029b000 Ядро:iw_cm_init+0x34/0x1000 [iw_cm] Ядро:do_one_initcall+0x67/0x2d4 Ядро:? kmem_cache_alloc_trace+0x1ec/0x2a0 Ядро:do_init_module+0x5a/0x223 Ядро:load_module+0x1998/0x1e10 Ядро:? __symbol_put+0x60/0x60 Ядро:__do_sys_finit_module+0x94/0xe0 Ядро:do_syscall_64+0x5a/0x270 Ядро:entry_SYSCALL_64_after_hwframe+0x49/0xbe Трассировка стека процесса:[<0>] __request_module+0x1c9/0x460 [<0>] ib_get_client_nl _Информация+0x5e/0xb0 [ib_core] [<0>] nldev_get_chardev+0x1ac/0x320 [ib_core] [<0>] rdma_nl_rcv_msg+0xeb/0x1d0 [ib_core] [<0>] rdma_nl_rcv+0xcd/0x120 [ib_core] [<0>] netlink_unicast+0x179 /0x220 [<0>] netlink_sendmsg+0x2f6/0x3f0 [<0>] sock_sendmsg+0x30/0x40 [<0>] ___sys_sendmsg+0x27a/0x290 [<0>] __sys_sendmsg+0x58/0xa0 [<0>] do_syscall_64+0x5a /0x270 [<0>]entry_SYSCALL_64_after_hwframe+0x49/0xbe Чтобы преодолеть этот тупик и позволить множеству netlink Параллелизм сообщений дело с, были реализованы следующие планы. 1. Воля защитить cb_table из блокировки разделены на индексы lock и сделайте его rwlock. Эта блокировка используется для того, чтобы гарантировать, что обратные вызовы не будут выполняться после возврата к отмене регистрации. Поскольку модуль не будет зарегистрирован после выполнения обратного вызова, это позволяет избежать взаимоблокировок. 2. Используйте smp_store_release() для обновления cb_table при регистрации, поэтому блокировка не требуется. Это позволяет избежать мысли, что все rwsem Все они имеют одинаковый тип замка. lockdep вопрос
init_rwsem(&rdma_nl_types[idx].sem)
addr_init -> IB/core: Модуль разрешения адресов ВоляIB интегрирован в ядро, разрешение адресов IB объявлено как модуль (ib_addr.ko), который загружается перед существующим модулем ядра IB (ib_core.ko). Это приводит к тому, что ИБ инициализация ядраизIB netlink не может быть использован в ситуации ib_addr.koиспользоватьиз. Чтобы решить эту проблемувопрос,нас Воля ib_addr.ko Преобразовать в IB Часть модуля основная
alloc_ordered_workqueue("ib_addr", 0)
register_netevent_notifier(&nb) -> netevent_callback
NETEVENT_NEIGH_UPDATE
set_timeout(req, jiffies)
ib_mad_init
INIT_LIST_HEAD(&ib_mad_port_list) <- ib_mad_port_open
list_add_tail(&port_priv->port_list, &ib_mad_port_list)
ib_register_client(&mad_client)
ib_sa_init -> Средний основной слой: Средний слой Core , Основные услуги включают интерфейс управления (MAD), интерфейс менеджера соединений (CM) и Управление. интерфейс участника подсетей (SA). Должен В стек входятиспользуется для пользовательского режима, приложения ядра и компонента. Основная служба существует в ядре и представляет собой глагол CM. èУправление переводит интерфейс в пользовательский режим -> Нет. 5 глава Конфигурация INFINIBAND Управление подсетямиустройство, все InfiniBand сеть должна работать Управление Подсетями устройство может работать исправно. Даже если две машины не соединены напрямую с помощью переключателя, То же самое. Может быть более одногоиз Управление подсетями устройства. существовать В том случае, когда Лорд Управление Когда один из подсетей выходит из строя, другой выступает в роли подчиненного сетевого менеджера. из системы возьмет на себя управление. большинство InfiniBand Коммутаторы содержат встроенное Управление подсетямиустройство。Однако,еслитебе нуженвозобновлятьиз Управление подсетями устройства, или Если вам нужно больше контроля, используйте Red Hat Enterprise Linux поставлятьиз OpenSM Управление подсетямиустройство get_random_bytes(&tid, sizeof tid)
ib_register_client(&sa_client)
mcast_init -> IB/sa: отслеживание запросов на присоединение/выход из многоадресной рассылки, IB SA ккаждыйпорт Добавлено для многоадресной рассылки базового отслеживания./оставлятьпожалуйстапросить,и не выполняет никакого подсчета ссылок:еслитакой жепортиздвапользовательприсоединитьсятакой же Группа,ив Пользователь уходит Должен Группа ,Так SA Воля удаляет порт из группы, даже если один пользователь хочет остаться ее участником. потому чтоэтот,дляподдерживать Приходитьстакой жепортизтакой же Группатранслировать Группаизнесколько пользователей,наснуждатьсяхотетьсуществовать Выполните подсчет ссылок локально。 По этой причине, чтобы ib_sa добавить В подмодуле многоадресной рассылки для выполнения операций присоединения/выключения многоадресной рассылки при подсчете ссылок. Исправлятьib_ipoib(многоадресная рассылкаизуникальный пользователь ядра)киспользоватьновыйинтерфейс
ib_sa_register_client(&sa_client)
ib_register_client(&mcast_client) -> mcast_add_one -> InfiniBand Управление подсетями (SA) Услугу предоставляет Управление подсетямиустройство (SM) Предоставляются предопределенные универсальные сервисные прокси. (GSA)。 существовать InfiniBand Конструктивно связь с устройством должна осуществляться через SA Запросите правильный маршрут, чтобы разрешить маршруты к другим хостам.
rdma_cap_ib_mcast -> rdma_cap_ib_mcast - Проверьте, есть ли порт устройства Infiniband, функция многоадресной рассылки. @device: Чтобы проверить изоборудование @port_num: Чтобы проверить номер экспорта * InfiniBand Многоадресная регистрация лучше, чем обычно IPv4 или IPv6 Регистрация многоадресной рассылки более сложна. Когда каждый адаптер главного канала желает присоединиться к группе многоадресной рассылки, он должен машина с подсетями регистрации. Его следует выполнять только один раз, независимо от того, на сколько пар очередей он подписан в группе. толькосуществовать Дополнительныйприезжать Должен Группаизвсе После отсоединения пар очередей,Должно Долженоставлять Должен Группа。 * Возврат: если порт должен поддерживать SM зарегистрироваться/Отменазарегистрироватьсяки отслеживание Дополнительныйприезжатьмногоадресная рассылка Группаиз Общее количество пар очередейиздополнительные расходы на управление,затем вернись true
ib_set_client_data(device, &mcast_client, dev)
INIT_IB_EVENT_HANDLER(&dev->event_handler, device, mcast_event_handler)
switch (event->event)
mcast_groups_event
rb_first
rb_next
rb_entry
ib_register_event_handler(&dev->event_handler)
alloc_ordered_workqueue("ib_nl_sa_wq", WQ_MEM_RECLAIM)
INIT_DELAYED_WORK(&ib_nl_timed_work, ib_nl_request_timeout) -> ib_nl_request_timeout
queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay)
ib_sa_disable_local_svc
send_handler -> callback
register_blocking_lsm_notifier(&ibdev_lsm_nb) -> LSM: переключитесь на блокировку уведомлений об обновлении политики, атомарные средства обновления политики не очень полезны, поскольку обычно они не могут выполнять обновления политик самостоятельно. потому что, похоже, не имеет строгих требований к атомарности,потому чтоэтотвыключательприезжатьвариант блокировки。 При этом переименуйте функцию соответствующим образом.
blocking_notifier_chain_register
register_pernet_device(&rdma_dev_net_ops)
nldev_init()
rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table) -> rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table)
down_write(&rdma_nl_types[index].sem)
rdma_nl_types[index].cb_table = NULL
roce_gid_mgmt_init -> IB/ядро: добавлено RoCE GID Управление таблицами, RoCE GID На основе RDMA (RoCE) оборудованиепорт СвязанныйизкEthernetсетьоборудованиеначальство Конфигурацияиз IP адрес. В настоящее время каждый поддерживаемый RoCE(ocrdma、mlx4) из Драйверы низкого уровня все управляют собой RoCE порт GID поверхность. потому чтоприроданачальство Нетлюбойспецифичный дляпоставщикизсодержание,потому чтоэтотнасверно Что Входить ХОРОШОобобщать,и улучшить RDMA основной GID Кэширование делает свою работу. чтобы заполнить GID Таблица, слушаем события: (a) netdev up/down/change_addr событие - если netdev строитьсуществоватьнасиз RoCE устройство, нам нужно добавить/удалить его IP。 Это включает в себя добавление этого ndev Связанныйизвсе GID, добавить по умолчанию GID ждать. (b) inet событие - Воляновый ГИД (по данным IP адрес) добавляется в таблицу. для порта RoCE GID таблицу для программирования, поставщик должен реализовать add_gid и del_gid перезвонить. RoCE GID Руководство просит нас существовать GID Далее объявить об ассоциации из net_device。 для управления GID поверхность,этотинформацияданеобходимыйиз。 Например, при удалении net_device час,Что Ассоциация GID Также необходимо удалить. RoCE Требоватьв соответствии с Связанныйсетьоборудованиеиз IPv6 По умолчанию генерируется локальный канал для каждого порта GID。 по сравнению с традиционными IPv6 ссылка местная из GID (поскольку у нас есть IP Генерация адреса GID) Вместо этого, когда устройство выключено, по умолчанию GID Также доступен (для поддержки обратной связи). запираниеиз Вот как это делается:Долженпластырь Исправлять Понятно GID Код таблицы, подходящий для реализации add_gid/del_gid перезвонитьизновый RoCE драйвер и не реализован add_gid/del_gid Обратный звонок когда-то назад RoCE и IB водитель. возобновлятьповерхностьиз Процесс отличается,потому чтоэтотзапирание Требоватьтоже разные。 возобновлять RoCE GID стол, проход mutex_lock(&table->lock) выполнитьдля нескольких авторовиз Защищать. Поскольку запись в таблицу требует от нас поиска записи в таблице (возможно, свободной записи), а затем ее изменения, этот мьютекс защищает find_gid и write_gid убеждатьсядействоватьизатомарность。 GID Каждый элемент в кэше подлежит rwlock Защищать. существовать RoCE , написанный (обычно с netdev Порядок уведомления о результатах) с участием поставщиков add_gid и del_gid обратные вызовы, которые могут спать. Таким образом, к каждой записи добавляется недопустимый флаг. RoCE извозобновлятьдапроходить Очередь работ завершенаиз,потому чтоэтот Разрешить спящий режим。 существоватьIBсередина,возобновлятьдасуществоватьwrite_lock_irq(&device->cache.lock)середина Заканчиватьиз,потому чтоэтотwrite_gidНет Разрешить спящий режимиadd_gid/del_gidне будетвызов。 Когда устройство Волясеть входящий/исходящий GID При кэшировании устройство всегда передается в режим удержания. (dev_hold)。 Должен код использовать один рабочий элемент, чтобы возобновить все RDMA оборудование, следуйте netdev или inet Процесс уведомления. Долженпластырь Воля Кэш от клиента(этотда Неправильныйиз,потому чтодлякэшда IB инфраструктураизчасть)превратился всуществоватьоборудованиезарегистрироваться/удалитьчасявныйинициализация/выпускать, commit: https://github.com/ssbandjl/linux/commit/03db3a2d81e6e84f3ed3cb9e087cae17d762642b, drivers/infiniband/core/cache.c
gid_cache_wq = alloc_ordered_workqueue("gid-cache-wq", 0) -> сериал
register_inetaddr_notifier(&nb_inetaddr) -> зарегистрироватьсясетьадрессобытие -> blocking_notifier_chain_register -> Волянотификатор добавлен в цепочку блокирующих уведомлений @nh: Относится к заголовку цепочки уведомлений о блокировке К и указателю зу. @n:Цепочка уведомленийсерединаизновыйвход Волянотификатор добавлен в цепочку блокирующих уведомлений。 Должен вызываться в контексте процесса. Возврат от успеха 0, возвращается при ошибке %-EEXIST
notifier_chain_register(&nh->head, n, unique_priority)
trace_notifier_register((void *)n->notifier_call)
register_inet6addr_notifier(&nb_inet6addr)
register_netdevice_notifier(&nb_netdevice) -> мы полагаемся на netdevice Процесс уведомления Приходитьсистема счислениясерединавсесуществующийизоборудование. Наконец, подпишитесь на это уведомление, чтобы мы ничего не пропустили. IP Добавить/удалить обратные вызовы
IPv4сетьсобытие
static struct notifier_block nb_inetaddr = {
.notifier_call = inetaddr_event
};
static struct notifier_block nb_inet6addr = {
.notifier_call = inet6addr_event
};
IPv6сетьсобытие
inetaddr_event
addr_event(struct notifier_block *this, unsigned long event, struct sockaddr *sa, struct net_device *ndev)
case NETDEV_UP:
gid_op = GID_ADD
case NETDEV_DOWN:
gid_op = GID_DEL
INIT_WORK(&work->work, update_gid_event_work_handler)
rdma_ip2gid(sa, &work->gid)
queue_work(gid_cache_wq, &work->work) -> портUP/DownчаскуроксобытиеивозобновлятьGID
update_gid_event_work_handler
ib_enum_all_roce_netdevs(is_eth_port_of_netdev_filter, work->gid_attr.ndev, callback_for_addr_gid_device_scan, work) -> callback_for_addr_gid_device_scan
update_gid(parsed->gid_op, device, port, &parsed->gid, &parsed->gid_attr)
uverbs
module_init(ib_uverbs_init) -> [PATCH] IB uverbs:основнойвыполнить,добавить в InfiniBand глагол пользовательского пространствавыполнитьизосновной,включатьсоздаватьхарактероборудованиеузел、отпользовательраспределение пространствапожалуйстапроситьки Волясобытие Уведомления передаются обратно в пространство пользователя -> commit: https://github.com/ssbandjl/linux/commit/bc38a6abdd5a50e007d0fcd9b9b6280132b79e62
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
register_chrdev_region(IB_UVERBS_BASE_DEV, infiniband_verbs
alloc_chrdev_region(&dynamic_uverbs_dev, 0,
class_register(&uverbs_class)
class_create_file(&uverbs_class, &class_attr_abi_version.attr);
ib_register_client(&uverbs_client) -> ib_register_client - зарегистрироваться IB Клиент, @client:Клиент Приходитьзарегистрироваться IB водительизначальствослойпользователь Можеткиспользовать ib_register_client() Приходитьзарегистрироваться IB оборудованиедобавить виудалитьизперезвонить. при добавлении IB оборудованиечас,Волявызову каждого есть регистрация клиента из add метод(в соответствии склиентзарегистрироватьсяиззаказ),икогдаудалитьоборудованиечас,Волявызовкаждыйклиентиз remove метод(в соответствии склиентзарегистрироватьсяиз Напротивзаказ)。 Кроме того, при вызове ib_register_client() час,клиент Воляполучатьприезжатьвсеужезарегистрироватьсяоборудованиеиздобавить в обратном вызове
init_completion(&client->uses_zero)
assign_client_id(client)
xa_for_each_marked
add_client_context(device, client)
client->add(device) -> ib_uverbs_add_one
Выполните ib_uverbs_add_one
ib_uverbs_add_one -> РДМА: разрешено ib_client существоватьвызов add() часнеудача,добавить вклиентчас Нетпозволятьнеудача,новсеклиентсуществовать Чтодобавить врутинасередина У всех разныедобрыйпуть отказа。 этотбудет производитьодиндобрый Очень крайнийиз Состояние:добавить вклиентназад,существоватьдобавить впроцесссерединанеудачаи Не установленонабор client_data。 Затем,основной Код по-прежнему будетиспользовать NULL client_data Позвоните другому, чтобы client_data длясередина Сердцеиздействовать,Например remove()、rename()、get_nl_info() и get_net_dev_by_params() - этотдасбивающий с толкуи Несчастный случайиз。 если add() Если обратный вызов завершился неудачно, не вызывайте больше никаких клиентских операций для устройства, даже не удаляйте. существование появляется в обратном вызове операции удаления NULL client_data извсе Проверка избыточности. возобновлятьвсе add() Обратный вызов для правильного возврата кода ошибки. EOPNOTSUPP используется для ULP Не поддерживается ib_device из Состояние - Например,потому чтодляэтотолькоподходящийиспользуется для IB
ссылка: https://www.cnblogs.com/vlhn/p/8301427.html
device_initialize(&uverbs_dev->dev)
init_completion(&uverbs_dev->comp)
uverbs_dev->xrcd_tree = RB_ROOT
INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list) <- list_add_tail(&file->list, &dev->uverbs_file_list) <- ib_uverbs_open
ib_uverbs_create_uapi
uverbs_alloc_api
uapi_merge_def(uapi, ibdev, uverbs_core_api, false)
uapi_merge_obj_tree
uapi_merge_method
case UAPI_DEF_WRITE:
rc = uapi_create_write(uapi, ibdev, def, cur_obj_key, &cur_method_key);
method_elm->handler = def->func_write -> зарегистрироваться Состояние ядраuverbsинтерфейс
dev_set_name uverbs/xxx
cdev_init device->ops.mmap ? &uverbs_mmap_fops : &uverbs_fops);
cdev_device_add
ib_set_client_data
xa_store(&device->client_data, client->client_id, data,
Интерфейс Uverbs режима ядра определяется следующим образом:
определение Состояние ядрадля Пользовательский режимиспользоватьизverbsЯдроинтерфейс
drivers/infiniband/core/uverbs_uapi.c
static const struct uapi_definition uverbs_core_api[] = {
UAPI_DEF_CHAIN(uverbs_def_obj_counters),
UAPI_DEF_CHAIN(uverbs_def_obj_cq),
UAPI_DEF_CHAIN(uverbs_def_obj_device),
UAPI_DEF_CHAIN(uverbs_def_obj_dm),
UAPI_DEF_CHAIN(uverbs_def_obj_flow_action),
UAPI_DEF_CHAIN(uverbs_def_obj_intf),
UAPI_DEF_CHAIN(uverbs_def_obj_mr),
UAPI_DEF_CHAIN(uverbs_def_write_intf),
{},
};
rdma user/kernel api/abi:
const struct uapi_definition uverbs_def_write_intf[] = {
...
DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_PD,
DECLARE_UVERBS_WRITE(
IB_USER_VERBS_CMD_ALLOC_PD,
ib_uverbs_alloc_pd,
UAPI_DEF_WRITE_UDATA_IO(struct ib_uverbs_alloc_pd,
struct ib_uverbs_alloc_pd_resp),
UAPI_DEF_METHOD_NEEDS_FN(alloc_pd)),
DECLARE_UVERBS_WRITE(
IB_USER_VERBS_CMD_DEALLOC_PD,
ib_uverbs_dealloc_pd,
UAPI_DEF_WRITE_I(struct ib_uverbs_dealloc_pd),
UAPI_DEF_METHOD_NEEDS_FN(dealloc_pd))),
...
}
====>
{
.kind = UAPI_DEF_OBJECT_START,
.object_start = { .object_id = UVERBS_OBJECT_PD },
},
{
.kind = UAPI_DEF_WRITE,
.scope = UAPI_SCOPE_OBJECT,
.write = {
.is_ex = 0,
.command_num = IB_USER_VERBS_CMD_ALLOC_PD
},
.func_write = ib_uverbs_alloc_pd, <- method_elm->handler = def->func_write
.write.has_resp = 1 + (sizeof(struct { int:(-!!(offsetof(struct ib_uverbs_alloc_pd, response) != 0)); })) + (sizeof(struct { int:(-!!(sizeof(((struct ib_uverbs_alloc_pd *)0)->response) != sizeof(u64))); })),
.write.req_size = sizeof(struct ib_uverbs_alloc_pd), .write.resp_size = sizeof(struct ib_uverbs_alloc_pd_resp),
.write.has_udata = 1 + (sizeof(struct { int:(-!!(offsetof(struct ib_uverbs_alloc_pd, driver_data) != sizeof(struct ib_uverbs_alloc_pd))); })) + (sizeof(struct { int:(-!!(offsetof(struct ib_uverbs_alloc_pd_resp, driver_data) != sizeof(struct ib_uverbs_alloc_pd_resp))); })),
},
{
.kind = UAPI_DEF_IS_SUPPORTED_DEV_FN,
.scope = UAPI_SCOPE_METHOD,
.needs_fn_offset = offsetof(struct ib_device_ops, alloc_pd) + (sizeof(struct { int:(-!!(sizeof(((struct ib_device_ops *)0)->alloc_pd) != sizeof(void *))); })), },
{
.kind = UAPI_DEF_WRITE,
.scope = UAPI_SCOPE_OBJECT,
.write = {
.is_ex = 0,
.command_num = IB_USER_VERBS_CMD_DEALLOC_PD
},
.func_write = ib_uverbs_dealloc_pd,
.write.req_size = sizeof(struct ib_uverbs_dealloc_pd),
},
{
.kind = UAPI_DEF_IS_SUPPORTED_DEV_FN,
.scope = UAPI_SCOPE_METHOD,
.needs_fn_offset = offsetof(struct ib_device_ops, dealloc_pd) + (sizeof(struct { int:(-!!(sizeof(((struct ib_device_ops *)0)->dealloc_pd) != sizeof(void *))); })),
}
static struct rdma_link_ops rxe_link_ops = {
.type = "rxe",
.newlink = rxe_newlink,
};
...
rxe_newlink -> добавить пару RDMA_NLDEV_CMD_NEWLINK/DELLINK информацияизподдерживать,Разрешить динамическийдобавить вновыйиз RXE Связь. временночас Устаретьиз Опции модуля
is_vlan_dev -> RDMA/rxe:предотвращатьсуществовать vlan Создано поверх интерфейса rxe,существовать vlan Создано поверх интерфейса rxe оборудование Волясоздаватьбесполезныйизоборудование,Долженоборудованиеимеет пустойиз gids поверхность,и Нетспособныйиспользуется для rdma cm коммуникация。 Это вызвано enum_all_gids_of_dev_cb()/is_eth_port_of_netdev() серединаизлогически обусловленоиз,Долженлогикатолькоучитыватьсоединятьприезжатьуже Конфигурациясетьоборудованиеиз“начальствослойоборудование”изсеть,привести к vlan интерфейсиз gid набор пуст и попробуйте передать это rdma соединять Невозможно разобрать gid,оборудованиесуществовать cm_init_av_for_response неуспешный. очевидно,Адаптировать этоот поведение да, чтобы адаптироваться к каждому портсоздавать RoCE оборудованиеиз HW-RoCE оборудование, поэтому RXE из Поведениедолжени HW-RoCE устройства идентичны и создаются только для каждого реального устройства rxe оборудование. чтобы пройти vlan интерфейс для осуществления связи пользователь должен использовать vlan адресиз gid индекс вместо передачи vlan создавать rxe
rxe_get_dev_from_net
rxe_net_add
ib_alloc_device
rxe_add
rxe_init -> RDMA/RXE: заменить красно-черное дерево на xarray, текущий драйвер rxe использует красно-черное дерево для добавления индекса в пул объектов rxe. Linux xarrays поставлять Одиндобрыйлучшеизметод Приходитьвыполнитьиндексиз Та же функция。 этотпластырь Воляобъект пулаизкрасное черное деревозаменятьдля xarray。 потому что xarray Спинлок уже есть, используйте его вместо пула rwlock。 убеждаться xarray(index) и kref(ref count) серединаизвсе Изменятьвсекатом Способпроисходить
rxe_init_device_param
rxe->attr.vendor_id = RXE_VENDOR_ID
addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid -> RDMA/rxe:Воля sys_image_guid Установить в соответствии HW IB Выравнивание устройства, RXE Драйвер не устанавливается sys_image_guid, а приложения пользовательского пространства видят ноль. Это приведет к pyverbs Тест не пройден со следующей трассировкой, потому что IBTA Требования Характеристики действительны из sys_image_guid。 Traceback (последний вызов): файл "./tests/test_device.py",Нет. 51 ХОРОШО,существовать test_query_device self.verify_device_attr(attr) документ“./tests/test_device.py”,Нет. 74 ХОРОШО,существовать verify_device_attr среднее утверждение attr.sys_image_guid != 0 Исправьте это, пожалуйста, Воля sys_image_guid установить равным node_guid
rxe_init_ports -> RDMA/rxe: удалить pkey поверхность,RoCE Требования спецификации RoCE Устройство поддерживает только стандартные pkey。 Однако, rxe Водитель поддерживает 64 сущности pkey поверхность,итолькоиспользовать Нет.одинвход。 удалить pkey таблицу и использовать значение по умолчанию pkey Длина жесткого соединения 1 изповерхность Входить ХОРОШОжестко закодированный。 Воля pkey_table извсечек заменить на с default_pkey из сравнения
rxe_init_port_param
port->attr.state = IB_PORT_DOWN
...
rxe_init_pools
rxe_pool_init(rxe, &rxe->uc_pool, RXE_TYPE_UC)
pool->rxe = rxe
pool->elem_size = ALIGN(info->size, RXE_POOL_ALIGN)
xa_init_flags(&pool->xa, XA_FLAGS_ALLOC)
rxe->mcg_tree = RB_ROOT
rxe_set_mtu
eth_mtu_int_to_enum
mtu = mtu ? min_t(enum ib_mtu, mtu, IB_MTU_4096) : IB_MTU_256
rxe_register_device(rxe, ibdev_name)
dev->node_type = RDMA_NODE_IB_CA
ib_set_device_ops(dev, &rxe_dev_ops)
ib_device_set_netdev(&rxe->ib_dev, rxe->ndev, 1)
alloc_port_data
add_ndev_hash
hash_add_rcu(ndev_hash, &pdata->ndev_hash_link,
rxe_icrc_init
crypto_alloc_shash
ib_register_device -> зарегистрироватьсяIBоборудование
drivers/infiniband/core/device.c -> ib_register_device - К IB основнойзарегистрироваться IB оборудование @device:хотетьзарегистрироватьсяизоборудование @name:толькоизхарактернитьоборудованиеимя。 этот Можетспособныйвключать“%”,этот Воляпривести к Волятолькоиндексдобавить вприезжатьпередачаизоборудованиеимясередина. @dma_device:обратитесь к Кподдерживать DMA изоборудованиеизуказатель。 если%NULL,но ВоляиспользоватьIB оборудование. существуют. В этом случае вызывающий абонент должен быть DMA Полностью настроен ibdev。 Обычно это означает использование dma_virt_ops。 Низкоуровневое использование драйверов ib_register_device() Воля Чтооборудованиезарегистрироватьсяприезжать IB Ядро. всезарегистрироватьсяизклиент Все Воляполучатьприезжатьдобавить визкаждыйоборудованиеизперезвонить. @device Необходимо использовать ib_alloc_device() Сделайте распределения. есливодительиспользовать ops.dealloc_driver и асинхронно вызвать любой ib_unregister_device() ,ноодин раз Долженвозврат функции,оборудованиеуказатель Можетспособныйвстречаодеяловыпускать
int ib_register_device(struct ib_device *device, const char *name, struct device *dma_device) -> roceиIBзарегистрироватьсяизflow: https://blog.csdn.net/tiantao2012/article/details/77746141
assign_name(device, name) -> DMA/устройства: используйте xarray хранить client_data, сейчас существуют у нас небольшой ID, мы можем использовать xarray Вместо линейного поиска в связанном списке для получения данных о клиенте. этот Воляпоставлятьбыстрее и доступнее Расширятьизклиентданныепроверятьпопытаться найти,иделатьнасспособный够Исправлятьзапираниеплан。 потому чтоxarrayМожеткиспользоватьотметкахранить'going_down',потому чтоэтотполностью устраненstruct Значения ib_client_data и Volyaclient_data хранятся непосредственно в существующемxarray. Однако,этот确实нуждатьсяхотетьодинособенныйиз Итерироватьустройство,потому чтодлянасвсе ещедолжен Итерироватьлюбой NULL client_data ценить. также исключен client_data_lock для поддержки внутренних xarray запирание
dev_set_name
err = kobject_set_name_vargs(&dev->kobj, fmt, vargs)
__ib_device_get_by_name <- static DEFINE_XARRAY_FLAGS(devices, XA_FLAGS_ALLOC);
xa_for_each (&devices, index, device)
setup_device(device) -> ib_register_device() Выполните несколько шагов выделения и инициализации. Воля Чторасколотьдляменьше、легче читатьизфункция,кудобный В审проверятьиподдерживать -> setup_device() выделять памятьинастраиватьнаборнуждатьсяхотетьвызовоборудованиедействоватьизданные,этотдасуществовать ib_alloc_device 期междуеще нет Заканчиватьэтотнекоторыйдействоватьизтолько Оригиналпотому что。 он состоит из ib_dealloc_device() Отменить
ib_device_check_mandatory -> must option
IB_MANDATORY_FUNC
mandatory_table
IB_MANDATORY_FUNC(query_device),
...
setup_port_data -> RDMA/device:Воля ib_device per_port данныеобъединитьиприезжатьодин Кусочекнабор,Нетпричина Зависит отвернокаждыйпортданные Входить ХОРОШО 3 распределение. Воляэтоих Группаобъединитьсуществоватьодинростиделатьвсе Каждыйпортданныеизжизненный цикли struct ib_device соответствовать. назад续пластырь Волянуждатьсяхотеть Дажемногоспецифичный дляпортизданные,сейчассуществоватьиметьодинхорошийместо Можеткпомещатьнаборэто
alloc_port_data
rdma_end_port
rdma_for_each_port
INIT_LIST_HEAD(&pdata->pkey_list)
INIT_HLIST_NODE(&pdata->ndev_hash_link)
rdma_for_each_port
get_port_immutable -> .get_port_immutable = irdma_roce_port_immutable -> получатьпортинформацияизатвердевать
ib_query_port -> Проверьте корректность порта, ли iwarp -> __ib_query_port
return device->ops.query_port(device, port_num, port_attr) -> or xtrdma_qeury_port
static int irdma_query_port(struct ib_device *ibdev, u32 port,
props->max_mtu = IB_MTU_4096
props->lid = 1;
props->lmc = 0;
props->sm_lid = 0;
props->sm_sl = 0;
props->state = IB_PORT_ACTIVE;
ib_get_eth_speed(ibdev, port, &props->active_speed,
rdma_port_get_link_layer -> IB_LINK_LAYER_ETHERNET
ib_device_get_netdev -> RDMA/устройство: Добавить ib_device_set_netdev() как get_netdev иззаменятьплан,Ассоциация netdev действительныйначальствоне должен Должен Очень динамично,потому чтоэтотдлябольшинствоводитель Приходитьобъяснять,Нетпричина Зависит от Входить ХОРОШОэтот Образецизперезвонить. предоставить API Приходитьуведомитьосновнойкодсвязанныйсеть Развивать связи,ииспользоватьосновнойподдерживатьизданныеструктура。 этотделать得основнойкодспособный够Даже加Понятноразвязать ndev связь,отипозволятьодиннекоторыйна основеэтотизновый API。 этоттакжеиспользовать Есть кто-тодобрыйзначениеначальствоиззапирание,Можетмноговодитель Всеиметьсбивающий с толкуиз RCU запирание,или ВОЗНедостаток Неправильныйиззапирание
pdata = &ib_dev->port_data[port]
ib_dev->ops.get_netdev(ib_dev, port) -> mlx5_ib_get_netdev -> IB/mlx5: поддерживается IB оборудованиеизперезвонитькполучать Что netdev,толькоподходящийиспользуется для Eth порт:существовать mlx5_ib_device серединаподдерживатьсетьоборудованиеуказатель,еслисетьоборудованиеи IB оборудование имеет то же самое из PCI отецоборудование,носуществовать NETDEV_REGISTER и NETDEV_UNREGISTER событиечасвозобновлятьэто。 выполнить get_netdev перезвонитьквозвращаться Долженсетьоборудование
mdev = mlx5_ib_get_native_port_mdev(ibdev, port_num, NULL)
mlx5_ib_port_link_layer
mlx5_core_mp_enabled
ndev = mlx5_lag_get_roce_netdev(mdev) -> сеть/mlx5: Получить RoCE нетдев, когда LAG Когда активен, IB Водитель использует это для определения IB обязательностьоборудованиеиз netdev。 если режим не поддерживает активное резервное копирование,затем вернись PF0 из netdev;еслимодельда Активное резервное копирование,затем вернисьхозяиндвигатьсяотмашинаиз PF netdev
ldev = mlx5_lag_dev(dev) -> net/mlx5: изменить модель отставания,Lagиспользуется для Волятакой жеHCAиздваPCIФункция Группаобъединить成单индивидуальныйлогика单元。 этотдаосновной Функция,потому чтоэтотдолжно бытьосновнойводительуправлять。 В настоящее время это не так. когданас Воляотстающая структура программного обеспеченияхранилищесуществоватьнижеоборудование Внутричас,Чтожизненный цикл(создавать/разрушать)Зависит от mlx5e Частичное решение. Изменятьвсевесовая модель,делать延迟инижеуровеньводительизжизненный цикл Связанный,и Нетдаи mlx5e Частично связано
ldev && __mlx5_lag_is_roce(ldev)
mlx5_ib_put_native_port_mdev(ibdev, port_num)
mlx5_core_mp_enabled
mpi = ibdev->port[port_num - 1].mp.mpi
rcu_dereference_protected -> rcu_dereference_protected() - когдавозобновлятьодеяло Предотвращатьчасполучать RCU указатель @p:существоватьразвязать除Цитировать Извпередхотетьчитатьизуказатель @c: возникает условие разыменования Возврат указан RCU Защищатьуказательизценить,ноупущение READ_ONCE() 。 этотсуществоватьвозобновлятьблокировка концевого замкауказательценить Изменятьиз Состояние Вниз很иметьиспользовать。 пожалуйста Уведомление,этот Оригинал语Нетвстреча Предотвращать编译устройствоповторитьэтот Цитироватьили Воля Чтои Чтоон Цитировать Группаобъединить,потому чтоэтотне долженсуществовать Не удобнокогда Замок Защищатьиз Состояние Внизиспользоватьэто。 Должен Функциятолькодлявозобновлятьконециспользовать。 только при условии rcu_read_lock() Защищатьчасиспользоватьэтотфункция Воляпривести кредкийно Нет Очень некрасивоизнеудача
__rcu_dereference_protected
еслинасначинатьпроходитьпредотвращать传транслировать Отменазарегистрироватьсяиз netdev Приходитьускоряться Отменазарегистрироватьсяизскорость
__ethtool_get_link_ksettings -> net: ethtool: добавить вновыйиз ETHTOOL_xLINKSETTINGS API,этотпластырьопределение Понятноновыйиз ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API,Зависит отновыйиз get_link_ksettings/set_link_ksettings Обратный звонок иметь дело с。 этот API поставлятьвернобольшинство Старая версия ethtool_cmd Полеизподдерживать,добавить пару Даже大Связьмодельмаска(большинствомного 4064 Кусочек,переменная длина)изподдерживать,иудалить ethtool_cmd уже Устарелоиз Поле(transceiver/maxrxpkt/maxtxpkt)。 этот API Устаревшая старая версия ETHTOOL_GSET/SSET API,ипоставлятьк Вниз КСвойства пост-совместимости: - приноситьиметь Старая версияводительиз Старая версия ethtool: без изменений, все еще используется get_settings/set_settings перезвонить. - с новым get/set_link_ksettings водительиз Старая версия ethtool:использоватьновыйизводительперезвонить,данныесуществоватьвнутренний Преобразовать в Старая версия ethtool_cmd。 ETHTOOL_GSET Волятольковозвращатьсякаждый Связьмодельмаскаиз Нет.один 32b。 если пользователь попробует Воля ethtool_cmd Устаревшие поля имеют значение «не» 0 (трансивер/maxrxpkt/maxtxpkt), ETHTOOL_SSET Волянеудача。 есливодительнастраиватьнаборвыше Кусочек,нозапишу Ядропредупреждать。 - еще нет Приходитьиз ethtool С устаревшими драйверами: без изменений, все еще используется. get_settings/set_settings перезвонить,внутренний Преобразовать вновыйизданныеструктура。 Не рекомендуетсяиспользоватьиз Поле(transceiver/maxrxpkt/maxtxpkt)Воляигнорируется,А существование считается 0 в пользовательском пространстве. пожалуйста, обрати внимание,“еще нет Приходить”из ethtool инструмент Воля Нетпозволять Изменятьэтотнекоторыйуже Устарелоиз Поле。 - еще нет Приходитьиз ethtool с новымизводитель:прямойвызовновыйизперезвонить. Инструмент «Будущее» смыслда: - Запрос: попробуйте сначала ETHTOOL_GLINKSETTINGS,еслинеудачановосстанавливатьсяприезжать ETHTOOL_GSET - Настройка: сначала запросите и запомните ETHTOOL_GLINKSETTINGS или ETHTOOL_GSET Кому из них это удалось? + если ETHTOOL_GLINKSETTINGS В случае успеха используйте ETHTOOL_SLINKSETTINGS Изменять Конфигурация。 неудачадафинальныйиз(Нетхотетьпытаться ETHTOOL_SSET)。 + в противном случае ETHTOOL_GSET успех, использование ETHTOOL_SSET Изменять Конфигурация。 неудачадафинальныйиз(Нетхотетьпытаться ETHTOOL_SLINKSETTINGS)。 по новому API изинтерактивный пользователь/Ядро首Первыйнуждатьсяхотеть Входить ХОРОШОодинвторой по величинеиз ETHTOOL_GLINKSETTINGS рукопожатие,к就Связьмодель Кусочеккартинаиз Согласен насчет длины.。 если Ядро несогласно с пользователемиз Требовать,это Воля Верните ожидания пользователейиз Кусочеккартинадлинакакотрицательная длина(и cmd Поля 0)。 когда Ядроипользовательсоглашатьсячас,Ядровозвращатьсявсе Полесерединаизэффективныйинформация(即Связьмодельдлина> 0, а cmd — ETHTOOL_GLINKSETTINGS). По пользователям/Ядрограницаизданныеструктураи 32/64 Биты не имеют значения. существоватьвнутренний Преобразовать взаконныйиз Ядро Кусочеккартина。 когда Нет.один“link_settings”водительначинатьвнесейчасчас,внутренний __ethtool_get_settings Программа-помощник ядра Воля постепенно была __ethtool_get_link_ksettings заменять. Местокэтотиндивидуальныйпластырьи Нет Изменятьэто,существоватьнуждатьсяхотеть Изменять Извпередэто Воляодеялоудалить
dev->ethtool_ops->get_link_ksettings(dev, link_ksettings)
cmd->base.duplex = DUPLEX_FULL;
ib_get_width_and_speed -> Получить/вычислить разрядность и скорость сетевой карты RDMA -> RDMA/core:отnetdevполучатьIBширинаискорость,квперед无法проверять询网卡из Количество каналов(lanes ),потому чтоэтоттакой жеизnetdev_speedприобретениеприезжатьзафиксированныйизразрядность и скорость。 вместе с Характеристики сетевой карты более Приходитькрестмного Образец化,этотдобрыйзафиксированныймодельуже经Нет再подходящийиспользовать,потому чтоэтотнуждатьсяхотетьодиндобрыйметод Приходитьв соответствии с Количество каналовполучатьправильныйизширинаискорость。 Этот патч от net_device Поиск netdev рядискорость,и Воля Что Преобразовать в IB разрядность и скорость
props->gid_tbl_len = 32;
props->pkey_tbl_len = IRDMA_PKEY_TBL_SZ -> 1
props->max_msg_sz = iwdev->rf->sc_dev.hw_attrs.max_hw_outbound_msg_size
ib_get_cached_subnet_prefix -> IB/core:проходитьчтение кэшаib_query_portсерединаизsubnet_prefix。 ib_query_port() вызов device->ops.query_port() Приходитьполучатьпортсвойство. проверять询методдаспецифичный дляоборудованиеводительиз。 такой жеизфункциявызовdevice->ops.query_gid()ПриходитьполучатьGIDиизвлекатьsubnet_prefix (gid_prefix)。 GID иsubnet_prefix Кэш хранилища существует. ноеслиоборудованиеда Infiniband оборудование,но Нетвстречаоткэшсерединачитатьэтоих。 к Вниз Изменять利использовать Понятнокэшизsubnet_prefix。 RDBMS тестповерхностьяркий,этот Изменятьделать性способныйиметь Понятнозначительно улучшено
*sn_pfx = device->port_data[port_num].cache.subnet_prefix;
immutable->max_mad_size = IB_MGMT_MAD_SIZE
verify_immutable -> 校验затвердеватьизпортданные
rdma_cap_ib_mad -> rdma_cap_ib_mad - исследоватьоборудованиеизпортданетподдерживать Infiniband Управляйте датаграммами. @device: Чтобы проверить изоборудование @port_num: Чтобы проверить номер экспорта Управление датаграммами (MAD) да InfiniBand спецификацияизнеобходимыйчасть,иквсе InfiniBand оборудованиеподдерживать. OPA интерфейсвозвращатьсяподдерживатьнемного Расширятьиз Версия。 возвращаться:еслипортподдерживатьотправлять/ловитьполучатьMADданные Сумка,затем вернисьtrue
device->port_data[port_num].immutable.core_cap_flags & RDMA_CORE_CAP_IB_MAD
rdma_max_mad_size -> возвращатьсяэтот RDMA портRequiredизMax MAD размер. @device:оборудование @port_num:порт Число Должен MAD Размер включает в себя MAD заголовок и MAD нагрузка. Никакие другие заголовки не включены. возвращатьсяпортRequiredизMax MAD размер. еслипорт Не поддерживается БЕЗУМНЫЙ, а затем вернуться 0
device->port_data[port_num].immutable.max_mad_size
device->ops.query_device(device, &device->attrs, &uhw) -> irdma_query_device
ib_cache_setup_one(device) -> Настройте кеш IB(GID) -> IB/ядро: добавлено RoCE GID Управление таблицами, RoCE GID На основе RDMA (RoCE) оборудованиепорт СвязанныйизкEthernetсетьоборудованиеначальство Конфигурацияиз IP адрес. В настоящее время каждый поддерживаемый RoCE(ocrdma、mlx4) из Драйверы низкого уровня все управляют собой RoCE порт GID поверхность. потому чтоприроданачальство Нетлюбойспецифичный дляпоставщикизсодержание,потому чтоэтотнасверно Что Входить ХОРОШОобобщать,и улучшить RDMA основной GID Кэширование делает свою работу. чтобы заполнить GID Таблица, слушаем события: (a) netdev up/down/change_addr событие - если netdev строитьсуществоватьнасиз RoCE устройство, нам нужно добавить/удалить его IP。 Это включает в себя добавление этого ndev Связанныйизвсе GID, добавить по умолчанию GID ждать. (b) inet событие - Воляновый ГИД (по данным IP адрес) добавляется в таблицу. для порта RoCE GID таблицу для программирования, поставщик должен реализовать add_gid и del_gid перезвонить. RoCE GID Руководство просит нас существовать GID Далее объявить об ассоциации из net_device。 для управления GID поверхность,этотинформацияданеобходимыйиз。 Например, при удалении net_device час,Что Ассоциация GID Также необходимо удалить. RoCE Требоватьв соответствии с Связанныйсетьоборудованиеиз IPv6 По умолчанию генерируется локальный канал для каждого порта GID。 по сравнению с традиционными IPv6 ссылка местная из GID (поскольку у нас есть IP Генерация адреса GID) Вместо этого, когда устройство выключено, по умолчанию GID Также доступен (для поддержки обратной связи). запираниеиз Вот как это делается:Долженпластырь Исправлять Понятно GID Код таблицы, подходящий для реализации add_gid/del_gid перезвонитьизновый RoCE драйвер и не реализован add_gid/del_gid Обратный звонок когда-то назад RoCE и IB водитель. возобновлятьповерхностьиз Процесс отличается,потому чтоэтотзапирание Требоватьтоже разные。 возобновлять RoCE GID стол, проход mutex_lock(&table->lock) выполнитьдля нескольких авторовиз Защищать. Поскольку запись в таблицу требует от нас поиска записи в таблице (возможно, свободной записи), а затем ее изменения, этот мьютекс защищает find_gid и write_gid убеждатьсядействоватьизатомарность。 GID Каждый элемент в кэше подлежит rwlock Защищать. существовать RoCE , написанный (обычно с netdev Порядок уведомления о результатах) с участием поставщиков add_gid и del_gid обратные вызовы, которые могут спать. Таким образом, к каждой записи добавляется недопустимый флаг. RoCE извозобновлятьдапроходить Очередь работ завершенаиз,потому чтоэтот Разрешить спящий режим。 существоватьIBсередина,возобновлятьдасуществоватьwrite_lock_irq(&device->cache.lock)середина Заканчиватьиз,потому чтоэтотwrite_gidНет Разрешить спящий режимиadd_gid/del_gidне будетвызов。 Когда устройство Волясеть входящий/исходящий GID При кэшировании устройство всегда передается в режим удержания. (dev_hold)。 Должен код использовать один рабочий элемент, чтобы возобновить все RDMA оборудование, следуйте netdev или inet Процесс уведомления. Долженпластырь Воля Кэш от клиента(этотда Неправильныйиз,потому чтодлякэшда IB инфраструктураизчасть)превратился всуществоватьоборудованиезарегистрироваться/удалитьчасявныйинициализация/выпускать
gid_table_setup_one
_gid_table_setup_one
struct ib_gid_table *table
rdma_for_each_port (ib_dev, rdma_port)
table = alloc_gid_table(ib_dev->port_data[rdma_port].immutable.gid_tbl_len)
gid_table_reserve_default(ib_dev, rdma_port, table)
roce_gid_type_mask = roce_gid_type_mask_support(ib_dev, port)
num_default_gids = hweight_long(roce_gid_type_mask) -> Вычислить число 1из
table->default_gid_indices |= BIT(i)
ib_dev->port_data[rdma_port].cache.gid = table -> init gid table
rdma_roce_rescan_device -> Тяжелыйновыйсканированиесистемасерединаизвсесетьоборудование,ив соответствии снуждатьсяхотеть Воля Что gid Добавить в связанное RoCE оборудование -> {net, IB}/mlx5: Управление несколькими портами RoCE изпортассоциация,вызов mlx5_ib_add час Конечнохотетьдобавить виз mlx5 основнойоборудованиеданетспособный够Входить ХОРОШОпарапорт RoCE действовать. еслида,пожалуйстаиспользовать num_vhca_ports иaffiliate_nic_vport_criteria Функция Конечноэтодахозяиноборудованиевозвращатьсядаотоборудование. если Долженоборудованиедаотродоборудование,пожалуйстапытатьсяпопытаться найтиприезжатьи Что Ассоциацияхозяиноборудование. Можетк Ассоциацияоборудование Воля Поделиться образом системы GUID。 если не ищешь приезжать,пожалуйста Воля Чтопомещать入Нетассоциацияпорт Списокповерхностьсередина. еслипопытаться найтиприезжатьхозяиноборудование,нопроходитьсуществовать NIC vport начальство Вниз文середина Конфигурацияпортотродсвязь Воляпортобязательностьприезжатьэто。 такой же,когдавызов mlx5_ib_remove час Конечнопорттип. еслиэтодаотпорт,но Воля Чтоихозяиноборудование Отменаассоциация,в противном случае Только Воля Чтоот Нетассоциацияпорт Списокповерхностьсерединаудалить Вот и все。 Даже порт Нет.two не может использоваться дляассоциация,IB оборудование Такжезарегистрироватьсядля многихпортоборудование. когда Нет.двапорт稍назад附родчас,долженщеткановый GID кэш才способныйполучатькэшсередина Нет.двапортизпо умолчанию GID。 Экспортroce_rescan_deviceкпоставлятьсуществоватьобязательностьновыйпортназадщеткановыйкэшизмеханизм。 существоватьмногопорт Конфигурациясередина,все IB Объект (QP, MR, PD и т. д.) Соответствующие команды должны проходить через основной сайт. mlx5_core_dev,Чтоон命令долженотправлятьприезжатьотпорт mlx5_core_mdev,предоставитьинтерфейс Приходитьполучать Нет IB вернокак командаизправильный mdev
ib_enum_roce_netdev pass_all_filter enum_all_gids_of_dev_cb
rdma_for_each_port
ib_cache_update -> IB/основной:толькосуществоватьсоответствующийсобытиеначальствовозобновлять PKEY и GID Кэширование, HCA серединаиз PKEY и GID Таблицы могут содержать сотни записей. читатьэтоихдадорогойиз。 часть Оригиналпотому чтодаиспользуется для Поискэтоихиз API Одновременно возвращается только одна запись. этотснаружи,существоватьнекоторыйвыполнитьначальство,Например СХ-3,VF существоватьэтотаспектдапаравиртуализацияиз,идолженполагаться PF драйвер для выполнения чтения. Это снова требует VF приезжать PF изкоммуникация。 IB Core изCache будет соответствии свсесобытие Входить ХОРОШОщеткановый。 потому чтоэтот,в соответствии сполучатьприезжатьизсобытиесоответственнодля IB_EVENT_PKEY_CHANGE и IB_EVENT_GID_CHANGE фильтровать PKEY и GID кэшизщеткановый
rdma_is_port_valid
ib_query_port(device, port, tprops)
rdma_protocol_roce
config_non_roce_gid_cache(device, port, tprops) -> IB/основной:РефакторингRoCEизGIDИсправлятькод,кододеяло РефакторингдляRoCEприготовься остаться одномуизфункция,Можетк Выполнять ХОРОШОи Цитироватьсчитать Связанныйизболее сложныйиздействовать,такой жечасвсе еще Держатькодизчитабельность。 Это включает в себя (a) Упростить, чтобы не выполнять IB связьслоистыйсетьоборудованиеисследоватьи Исправлять。 (b) Не добавлять NULL сетьоборудованиеиз RoCE GID вход; Вместо этого возвращается ошибка. (c) если GID Добавить уровень провайдера add_gid() неудача,но Нетхотетьсуществоватькэшсерединадобавить в Долженвходи Держать Долженвходотметкадля INVALID。 (d) Упрощение и повторное использование ib_cache_gid_add()/del() рутина,кудобныйэтоих甚至Можеткиспользуется для Исправлятьпо умолчанию GID。 Это позволяет избежать изменения значения по умолчанию GID часизодиннекоторыйкодповторить。 (e) find_gid() Флаг ввода рутинных справочных данных в Волю GID Ограничено действительными и недействительными GID,и Нетдазависит от GID содержаниеизсвойствоиноль。 (f) gid_table_reserve_default() существоватьнастраиватьнабор GID Время за столом установлено в начале GID Свойства по умолчанию. 无нуждатьсясуществовать write_gid()、add_gid()、del_gid() Используется в функциях низкого уровня default_gid знаки, как они существуют GID поверхностьвозобновлять期между永远Нетнуждатьсяхотетьвозобновлять GID входиз DEFAULT свойство. какэтот Рефакторингизрезультат,бронироватьиз GID 0:0:0:0:0:0:0:0 Больше не доступен для поиска, как описано ниже. в соответствии с IB Каноническая версия 1.3 Нет. 4.1.1 Фестиваль Нет. (6) точка, одноадресная передача GID вход 0:0:0:0:0:0:0:0 дабронировать GID, фрагмент которого выглядит следующим образом. "Одноадресная передача GID адрес 0:0:0:0:0:0:0:0 дабронироватьиз - называемое резервирование GID。это Нет得распространять给любойконецконецпорт。это Нет得использовать作глазотметкаадресили Глобальный заголовок маршрутизации (GRH). " GID поверхностькэшсейчассуществоватьтолькохранилищеэффективныйиз GID вход。 существоватьэтотпластырь Извперед,Можеткиспользовать ib_find_cached_gid_by_port() и Чтоондобрыйпохожийизпроверятьпопытаться найтирутинасуществовать GID Поиск сохранен в таблице GID 0:0:0:0:0:0:0:0。 ноль GID больше не доступен для поиска, поскольку он не должен существовать GRH илизапись путивходсередина,нравиться IB Каноническая версия 1.3 Нет. 4.1.1 Фестиваль Нет. (6) точка、Нет. 12.7.10 Фестивальи Нет. 12.7.20 описано в разделе. ib_cache_update() одеялоупрощатьдляисследоватьсвязьслойодин Второсортный,верновсесвязьслойиспользоватьединыйиззапираниеплан,удалить Прочас gid Логика распределения/освобождения таблиц. этотснаружи,(a) Расширять ib_gid_attr кхранилищепортииндекс,кудобный GID проверять询рутина Можеткотсвойствоструктурасерединаполучатьпортииндексинформация。 (b) Расширять ib_gid_attr хранитьоборудование,кудобныйсуществовать Воля Приходитьизкодсередина,когда Заканчивать GID Цитироватьсчитатьчас,оборудованиеиспользуется длявозвращатьсяприезжать GID поверхностьвход
device->ops.query_gid(device, port, i, &gid_attr.gid)
rdma_protocol_iwarp(device, port)
add_modify_gid(table, &gid_attr)
ib_query_pkey -> Get P_Key table entry
device->ops.query_pkey(device, port_num, index, pkey) -> irdma_query_pkey -> #define IRDMA_DEFAULT_PKEY 0xFFFF
ib_security_cache_change -> IB/основной:существовать QP применяется на PKey безопасность,добавить вновыйиз LSM Перехватчики для выделения и освобождения контекста безопасности и проверки доступа PKey из Разрешения. создаватьиразрушать QP При выделении и освобождении контекста безопасности. этотначальство Вниз文используется дляконтрольверно PKey из визита. При запросе модификации QP Приходить Изменятьпорт、PKey индексили Альтернативный путьчас,пожалуйстаисследовать QP данет具иметьверно Долженпортподсетьвпередукрашенныйначальствоиз PKey поверхностьиндекссерединаиз PKey из Разрешения. если QP даобщийиз,пожалуйстаубеждаться QP извсе句柄также具иметьдоступ Разрешения。 хранилище QP толькосуществоватьиспользоватьизпорти PKey индекс. Тяжелыйнаборприезжать После инициализации преобразования,пользователь Можеткнезависимый Исправлятьпорт、PKey Индекс и альтернативный путь. потому чтоэтот,порти PKey настраиватьнабор Изменять Можеткда Первыйвпереднастраиватьнабориновыйнастраиватьнаборизобъединитьи。 длясуществовать PKey поверхностьилиподсетьвпередукрашенный Изменятьчас维持доступконтроль,пожалуйстабронироватькаждыйпортначальствоиспользоватькаждый PKey индексизвсе QP из Списокповерхность. еслипроисходить Изменять,ноиспользовать Долженоборудованиеипортизвсе QP Вседолжен强制Выполнять ХОРОШОновыйкэшнастраиватьнабориздоступ Разрешения。 этотнекоторый Изменять Воляделадобавить вприезжать QP В процессе модификации. если Исправлятьнеудача,нодолжен Держатьистарыйпорти PKey индексизассоциация;если Исправлятьуспех,нодолжен Воля Чтоудалить. долженсуществовать Исправлять Извпередучреждать立иновыйпорти PKey индексизассоциация,если Исправлятьнеудачано Воля Чтоудалить. 1. когда QP одеяло Исправлятьдляидентификацияпортчас,PKey индексили Альтернативный путь Воля Должен QP вставлятьприезжатьподходящийкогдаиз Списокповерхностьсередина. 2. исследоватьдоступновыйнастраиватьнабориз Разрешения. 3. еслишаг 2 Предоставьте доступ, затем попробуйте изменить QP。 4a. еслишаг 2 и 3 успех,ноудалитьлюбой Первыйвпередизассоциация。 4b. есликслишкомнеудача,пожалуйстаудалитьновыйизнастраиватьнаборассоциация。 если PKey поверхностьилиподсетьвпередукрашенныйпроисходить Изменять,нотраверс QP Списокповерхностьиисследоватьэтоихданет具иметь Разрешения。 если Нет,но Воля QP отправлятьприезжатьошибкасостояниеивызвать смертельный исходошибкасобытие。 еслиэтодаобщий QP,пожалуйстаубеждатьсяобщий real_qp извсе QP Также имеет разрешения. если иметь безопасную структуруиз QP доступ запрещен,но Безопасностьструктура Воляодеялоотметкадляэтотдобрый,и QP Воляодеялодобавить вприезжать error_list середина. один раз Воля QP Перейдите к завершению ошибки, и флаг безопасной структуры будет очищен. Правильное ведение списка поможет Воля QP Уничтожение конвертируется в транзакцию. оборудованиеизаппаратное обеспечениеводительвыпускать ib_qp структура,потому чтоэтоткогдаразрушатьтолькосуществовать Входить ХОРОШОчас,ib_qp_security структурасерединаиз ib_qp указатель не определен. когдаразрушатьпроцессначинатьчас,ib_qp_security Структура отмечена как положительное существование для разрушения. Это предотвращает QP указательвозьми любойдействовать. QP После успешного уничтожения он все еще может находиться в списке существующих. error_list начальство,ждать Долженпотокиметь дело Это перед чисткой конструкции. еслиразрушатьнеудача,но QP порти PKey настраиватьнабор Воля Тяжелыйновыйвставлятьприезжатьподходящийкогдаиз Списокповерхностьсередина,Знак разрушения Воля убран,и обеспечить контроль доступа,В случае возникновения каких-либо изменений в кэше в процессе существования. Чтобы сохранить изменения безопасности изолированными,использоватьновыйдокумент Приходитьдержатьи Безопасность Связанныйиз Функция
list_for_each_entry (pkey, &device->port_data[port_num].pkey_list,
check_pkey_qps(pkey, device, port_num, subnet_prefix)
ib_get_cached_pkey
enforce_qp_pkey_security
security_ib_pkey_access -> Check if access to an IB pkey is allowed
return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey) -> selinux_ib_pkey_access
sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid)
avc_has_perm(sec->sid, sid,
qp_to_error(pp->sec)
.qp_state = IB_QPS_ERR
.event = IB_EVENT_QP_FATAL
ib_modify_qp(sec->qp,
sec->qp->event_handler(&event,
list_del(&pp->to_error_list)
complete(&pp->sec->error_complete)
device->groups[0] = &ib_dev_attr_group; -> RDMA/core:проходитьобычно Группамеханизмсоздаватьоборудование hw_counters,и Нетдавызов device_add_groups() Воля Группадобавить вприезжатьпроходить device_add() управлятьизсуществующий Группачисло Группасередина. этотнуждатьсяхотетьсуществовать device_add() ранее установленный hw_counters,кудобныйэтоотужеразделенныйизпорт sysfs разделить на поток -> Нет.один Группаиспользуется дляоборудованиесвойство,Нет.два Группаиспользуется дляводительпоставлятьизсвойство(Необязательный)。 Нет.три Группада hw_stats этодаодинк NULL окончаниеизчисло Группа
device->groups[1] = device->ops.device_group;
ib_setup_device_attrs
data = alloc_hw_stats_device(ibdev)
ibdev->ops.get_hw_stats
sysfs_attr_init(&attr->attr.attr)
attr->attr.show = hw_stat_device_show
attr->show = show_hw_stats
attr->show = show_stats_lifespan;
attr->attr.store = hw_stat_device_store;
attr->store = set_stats_lifespan;
ib_device_register_rdmacg
rdma_counter_init
dev_set_uevent_suppress
ib_setup_port_attrs
enable_device_and_get
add_client_context
client->add(device) -> .add = ib_uverbs_add_one,
add_compat_devs(device) -> RDMA/core:существоватьnetпространство именсерединавыполнитьcompat device/sysfsДерево,Выборib_coreиз слоя совместимости sysfsвход,кудобный Нетinit_net netпространство иментакже Можеткволосысейчасrdmaоборудование. Каждый не init_net сеть Пространства именсуществоватьвсоздавать Понятно ib_core_device。 этот Образециз ib_core_device sysfs дерево напоминает init_net пространство именсерединапопытаться найтиприезжатьиз rdma оборудование. Это позволяет пройти sysfs входсуществоватьмногоиндивидуальный Нет init_net Найдено в пространстве имен сети rdma оборудование,иверно rdma-core Пользовательское пространство полезно
add_one_compat_dev
dev_set_uevent_suppress
kobject_uevent(&device->dev.kobj, KOBJ_ADD)
ib_device_put
проходитьсканированиеоборудованиеизперезвонитьперечислятьоборудованиевсеизGIDs(в соответствии сIP вычисляет GID,и кэшируйте GID)
static void enum_all_gids_of_dev_cb(struct ib_device *ib_dev, u32 port, struct net_device *rdma_ndev,void *cookie)
for_each_net(net) -> Два уровня цикла for
for_each_netdev(net, ndev)
когда Нетв Вобязательностьмодельчас,фильтридобавить вхозяинсетьоборудованиеизпо умолчанию GID,или ВОЗкогдав Вобязательностьмодельчас,добавить вобязательностьхозяиноборудованиеизпо умолчанию GID
is_ndev_for_default_gid_filter
add_default_gids(ib_dev, port, rdma_ndev, ndev) -> ib_cache_gid_set_default_gid
mask = GID_ATTR_FIND_MASK_GID_TYPE | -> IB/core: исправлены изменения mac адресчасудалитьпо умолчанию GID извопрос,существовать [1] Извперед,когдасетьоборудованиеиз MAC адрес Изменятьчас,по умолчанию GID отвечать Долженодеялоудалитьидобавить враз Приходить,этотбудет нажиматьк Вниззаказ Влияниеузели/илипорт GUID。 netdevice_event() -> NETDEV_CHANGEADDR default_del_cmd() del_netdev_default_ips() bond_delete_netdev_default_gids() ib_cache_gid_set_default_gid() ib_cache_gid_del() add_cmd() [..] нода,существовать Нетобязательностьсценасередина Нетвстречавызов ib_cache_gid_del(), потому что event_ndev и rdma_ndev такой же. потому чтоэтот,ремонтэтотситуация,когдасобытие ndev и rdma_dev такой жечаспренебрегатьисследоватьначальствослойоборудование; Похоже на: bond_set_netdev_default_gids()。 этотремонт ib_cache_gid_del() одеялоправильныйвызов; нода ib_cache_gid_del() попытаться найти Нетприезжатьхотетьудалитьизпо умолчанию GID, потому что find_gid() данный default_gid = false и установить GID_ATTR_FIND_MASK_DEFAULT。 Но тогда это было ib_cache_gid_set_default_gid() крышка,как add_cmd() изчасть。 потому чтоэтот,mac адрес Изменятьв целомподходящийиспользуется дляпо умолчанию GID。 Серия рефакторингов [1],Можетк Обнаружениеприезжатьэтотдобрый Неправильныйиз Поведение。 потому чтоэтот,удалитьпо умолчаниюGIDчас,пожалуйстанастраиватьнаборdefault_gidинастраиватьнаборMASKлоготип. когдаудалитьна основеIPизGIDчас,Прозрачныйdefault_gidинастраиватьнаборMASKлоготип. [1] https://patchwork.kernel.org/patch/10319151/
for (gid_type = 0; gid_type < IB_GID_TYPE_SIZE; ++gid_type) -> Перебрать 3 типа GID
if (1UL << gid_type & ~gid_type_mask)
make_default_gid(ndev, &gid)
gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL)
addrconf_ifid_eui48(&gid->raw[8], dev) -> функцияipv6_generate_eui64финальныйвызовaddrconf_ifid_eui48генерироватьадрес.ВоляоборудованиеизMACадресdev_addrизвпередтрииндивидуальный Характер ФестивалькопироватьприезжатьIPv6адресизвторая половина(s6_addr+8)Начало;существоватьловить Вниз Приходитьиз Нет.4и Нет.5индивидуальный Характер Фестивальвдобавить в0xFFи0xFEценить;копироватьMACадресизназадтрииндивидуальный Характер Фестивальприезжатьловить Вниз ПриходитьизIPv6адресиз Нет.6индивидуальный Характер Фестиваль Начало
__ib_cache_gid_add(ib_dev, port, &gid, &gid_attr, mask, true)
rdma_is_zero_gid(gid) -> IB/ядро: сократить использование zgid из места,и Нетда开помещатькодирование memcmp() Приходитьисследовать Данныйиз GID да Нет是ноль,идаиспользовать Вспомогательныйфункция Приходить Выполнять ХОРОШОэтотдействовать,ииспользовать memset заменять memcpy(z,&zgid) из Примеры
find_gid(table, gid, attr, default_gid, mask, &empty) -> find gid from cache
add_modify_gid(table, attr)
entry = alloc_gid_entry(attr)
add_roce_gid(entry)
rdma_cap_roce_gid_table
attr->device->ops.add_gid(attr, &entry->context) -> mlx5_ib_add_gid
store_gid_entry(table, entry)
table->data_vec[entry->attr.index] = entry; -> store gid
dispatch_gid_change_event(ib_dev, port)
event.event = IB_EVENT_GID_CHANGE
ib_dispatch_event_clients(&event) -> IB/основной:позволять IB основной Кэш распределениявозобновлятьсобытие глазвперед,когда Низкий уровеньводительуведомить Pkey、GID ипорт Изменятьсобытиечас,этоихвстречав соответствии сзарегистрироватьсяиззаказуведомить给ужезарегистрироватьсяизиметь дело программа. IB основнойи Чтоон УЛП (например, IPoIB) пара GID、LID、Pkey Изменятьсобытиезаинтересованный。 потому что ULP завершить полностью GID Запросы делаются IB основнойпоставлять Служить,и IB основной Волякэшвозобновлятьоткладыватьприезжатьоперативная группа Список,потому чтоэтот Чтоонклиентсуществоватьиметь дело с Собственныйизсобытиечас Можетспособныйвстреча看приезжать Проходитьчасизкэшданные。 Например,подизвызов Деревопоказывать Понятно ipoib нравитьсячтосуществоватьвозобновлять WQ серединаизкэшизтакой жечасвызов rdma_query_gid()。 mlx5_ib_handle_event() ib_dispatch_event() ib_cache_event()queue_work() -> кэшвозобновлятьскоростьпомедленнее [..] ipoib_event()queue_work() [..] Работа иметь дело программа ipoib_ib_dev_flush_light() __ipoib_ib_dev_flush() ipoib_dev_addr_changed_valid() rdma_query_gid() <- вернуть старый GID ,кэшеще нетвозобновлять。 Волявсесобытие分派移至оперативная группа Список,кудобный始конецсуществоватьуведомитьлюбойклиент Извперед Заканчиватькэшвозобновлять
list_for_each_entry(handler, &event->device->event_handler_list, list)
handler->handler(handler, event)
is_eth_port_of_netdev_filter
real_dev = rdma_vlan_dev_real_dev(cookie) -> IB/core:удалитьот void приезжать net_device изуказательконверсия,этотпластырьизбегать Понятноот void приезжать net_device из Нетдолженхотетьиздобрыйформа Конвертировать -> IB/основной:для IBoE добавить в VLAN поддержка IBoE добавить в 802.1q VLAN поддерживать. VLAN отметкав соответствии ск Вниз Способкодированиесуществоватьотсвязьместныйадреспроизводнаяиз GID середина: когда GID Включать VLAN Когда, ГИД[11] GID[12] Включать VLAN ID。 данные Сумкаиз 3 Поле приоритета пользователя и SL из 3 Кусочектакой же. для rdma_cm Приложение, Условия использования Полеиспользуется дляпрохода двигаться направо 5 биты для генерации SL поле, тем самым эффективно занимая TOS Полеиз 3 MS Кусочек -> commit: https://github.com/ssbandjl/linux/commit/af7bd463761c6abd8ca8d831f9cc0ac19f3b7d4b
is_vlan_dev(dev) ? vlan_dev_real_dev(dev) : NULL
net_device *ret = vlan_dev_priv(dev)->real_dev -> while (is_vlan_dev(ret)) -> Возьмите рекурсивноприезжатьvlanоборудованиеверноотвечатьизреальностьоборудование
rdma_is_upper_dev_rcu -> IB/core:Воля rdma_is_upper_dev_rcu перейти к головедокумент,Чтобы проверить маршрутизацию,наснуждатьсяхотетьодиндобрый Простойизметод Приходитьисследоватьсетьоборудованиеданетрод Внасиз RDMA оборудование. Воляэтот Вспомогательныйфункцияперейти к головедокументкделатьисследовать Даже容易
netdev_has_upper_dev_all_rcu -> Check if device is linked to an upper device
netdev_walk_all_upper_dev_rcu(dev, ____netdev_has_upper_dev,
is_eth_active_slave_of_bonding_rcu -> IB/ядро: добавленоRoCEповерхностьобязательность(bond)поддерживать,иметь дело собязательностьи ЧтооноборудованиенуждатьсяхотетьнасвсесетьоборудованиеизGID,этотнекоторыйсетьоборудованиедаRoCEпорт Связанныйсетьоборудованиеизначальствослойоборудование. активное резервное копирование Конфигурацияприносить Приходить Понятно Дажемногоиспытание,потому чтодляпо умолчанию GID может толькосуществовать Активностьоборудованиеначальствонастраиватьнабор(этотдадолженхотетьиз,в противном случаетакой жеиз MAC Можеткиспользуется длямногоиндивидуальныйотоборудование, поэтомумногоиндивидуальныйотоборудование Воля具иметьтакой жеиз GID)。 управлятьэтотнекоторый Конфигурациядапроходитьмонитор Приходить Заканчиватьиз: (a) NETDEV_CHANGEUPPER событие (1) если Связь Понятно Связанныйизсетьоборудование,ноудалитьвсе Нет Активностьизотоборудованиепо умолчанию GID идобавить вначальствослойоборудование GID。 (2) если Связанныйсетьоборудование Не связано,ноудалитьвсеначальствослойGID,идобавить впо умолчаниюGID。 (b) NETDEV_BONDING_FAILOVER: (1) от Нет Активностьотстоятьудалитьобязательность GID (2) удалить Нет Активностьотстоятьизпо умолчанию GID (3) Воляобязательность GID добавить вприезжать Активностьотстоять -> struct bonding
netif_is_bond_master(upper)
bond_option_active_slave_get_rcu
rcu_dereference_rtnl(bond->curr_active_slave)
bond_uses_primary(bond)
_add_netdev_ips(ib_dev, port, ndev)
enum_netdev_ipv4_ips(ib_dev, port, ndev) -> Enum IPv4оборудованиеизIPадрес
__in_dev_get_rcu
list_add_tail(&entry->list, &sin_list)
update_gid_ip(GID_ADD, ib_dev, port, ndev, (struct sockaddr *)&sin_iter->ip);
rdma_ip2gid(addr, &gid) -> IPадресприезжатьGIDиз Конвертироватьалгоритм -> IB/core:verbs/cm структурасерединаизкEthernet L2 свойство,этотпластырьдобавить вверно verbs/cm/cma структурасерединаизкEthernet L2 свойствоизподдерживать. существоватьиметь дело с L2 кEthernetчас,насотвечать Долженкииспользовать IB L2(и L4 PKEY)свойстводобрыйпохожийиз Способиспользовать smac、dmac、vlan ID и приоритет. потому чтоэтот,этотнекоторыйсвойствоодеялодобавить вприезжатьк Внизструктурасередина: * ib_ah_attr - добавить в dmac * ib_qp_attr - добавить в smac и vlan_id,(sl бронировать vlan приоритет) * ib_wc - добавить в smac、vlan_id * ib_sa_path_rec - добавить в smac、dmac、vlan_id * cm_av - добавить в smac и vlan_id длязапись путиструктура,существует Воля Особое внимание уделяется тому, чтобы избежать появления новых полей при упаковке в проволочном формате.,потому чтоэтотнас Нетвстреча破坏 IB CM и SA проводной протокол. существоватьхозяиндвигаться侧,CM заполнен. Его внутренняя структура происходит от ULP поставлятьизпуть。 насдобавить в ETH L2 Недвижимость и Воля их заложили. CM дескриптор адреса (структура cm_av)середина. существоватьодеялодвигаться侧,CM От и REQ информация Ассоциация WC заполнить его внутреннюю структуру. насдобавить вот WC получать ETH L2 свойствоизсодержание。 когдааппаратное обеспечениеводительсуществовать WC серединапоставлятьнеобходимыйиз ETH L2 свойства, они установлены IB_WC_WITH_SMAC и IB_WC_WITH_VLAN логотип. IB основнойкодисследоватьэтотнекоторыйотметка志да Стоит ли сохранятьсуществовать,если Нет,ноот ib_init_ah_from_wc() Вспомогательныйфункция Входить ХОРОШОадресанализировать。 ib_modify_qp_is_ok такжеодеяловозобновлятькучитыватьсвязьслой。 некоторые параметрыдлякEthernetсвязьслойданеобходимыйиз,идляIBПриходитьобъяснятьноне имеющий отношения。 Исправлятьпоставщикводителькподдерживатьновыйизфункциязнак
case AF_INET: -> ipv4
ipv6_addr_set_v4mapped(((struct sockaddr_in *)addr)->sin_addr.s_addr, (struct in6_addr *)gid)
ipv6_addr_set(v4mapped, 0, 0, htonl(0x0000FFFF), addr)
__ipv6_addr_set_half(&addr->s6_addr32[0], w1, w2)
__ipv6_addr_set_half(&addr->s6_addr32[2], w3, w4)
case AF_INET6:
*(struct in6_addr *)&gid->raw = ((struct sockaddr_in6 *)addr)->sin6_addr
update_gid(gid_op, ib_dev, port, &gid, &gid_attr)
unsigned long gid_type_mask = roce_gid_type_mask_support(ib_dev, port) -> IB/core:Воляgid_typeдобавить вприезжатьgidсвойствосередина,дляподдерживатьмногодобрыйGIDдобрыйформа,наснуждатьсяхотетьхранилищекаждыйGIDизgid_type。 Это также связано с RoCE v2 Приложение «RoCEv2 порт GID поверхностьвходотвечать具иметьповерхность Показывать L3 адресдобрыйформаиз“GID Тип «свойства» остается неизменным. когдавпередподдерживатьиз GID да IB_GID_TYPE_IB,этоттакжеда RoCE v1 GID тип. это означает gid_type отвечатьдобавить вприезжать roce_gid_table в метаданных
ib_cache_gid_add(ib_dev, port, gid, gid_attr) -> .is_supported = &mlx5_rdma_supported,
__ib_cache_gid_add
or ib_cache_gid_del(ib_dev, port, gid, gid_attr) -> _ib_cache_gid_del
find_gid
del_gid(ib_dev, port, table, ix) -> del_gid
mlx5r_del_gid_macsec_operations -> del flow
dispatch_gid_change_event(ib_dev, port)
enum_netdev_ipv6_ips(ib_dev, port, ndev)
in6_dev = in6_dev_get(ndev)
list_add_tail(&entry->list, &sin6_list)
rdma_ip2gid((struct sockaddr *)&sin6_iter->sin6, &gid)
update_gid(GID_ADD, ib_dev, port, &gid, &gid_attr)
ucma_copy_iboe_route struct rdma_route -> RDMA/cma: поддержка многопутевой записи netlink канал, поддерживает прохождение RDMA netlink Каналы получают входящие и исходящие сообщения от сервисов пользовательского пространства. IB Записи пути (и GMP PathRecord)。 этот3индивидуальныйPRсерединаизLIDМожеткэтот Образециспользовать: 1. GMP PR: используется как стандартный локальный/дистанционный идентификатор LID; 2、исходящийPRизDLID:использовать作исходящийпотокколичествоиз“dlid”Поле; 3.входящийPRизDLID:использовать作响отвечатьнаправлениеисходящийпотокколичествоиз“dlid”Поле。 этот Образец做изглазиздаподдерживатьсподходящийотвечатьдорога Зависит от。 использоватькогдавпередиз IB дорога Зависит отразвязать决план,когдаданные Сумкаволосывнечас,каждыйглазотметка Всевстречаодеялораспространятьодинзафиксированныйиз DLID,это означает Воляиспользоватьзафиксированныйиздорога Зависит отустройство。 входящий/исходящийзапись путисерединаиз LID Можетиспользуется для识别позволятьи Другойодинподсеть实体Входить ХОРОШОкоммуникацияиздорога Зависит отустройство Группа。 проходитьэтоих,Приходитьсподсетьмеждусоединятьизданные Сумка Можеткпроходить Должен Группасерединаизлюбойдорога Зависит отустройствоприезжатьдостигатьглазотметка。 как Jason Подтвержденный,когдаотправлять netlink По запросу ядро использует LS_RESOLVE_PATH_USE_ALL чтобы служба знала, что ядро поддерживает несколько PR
IB:адрес Конвертироватьк Воля IP картографированиеприезжать IB адрес (GID),добавить вадрес Конвертировать Служить,использовать IPoIB Воля IP адрескартографированиеприезжать InfiniBand GID адрес
/**
* struct rdma_dev_addr - Contains resolved RDMA hardware addresses
* @src_dev_addr: Source MAC address.
* @dst_dev_addr: Destination MAC address.
* @broadcast: Broadcast address of the device.
* @dev_type: The interface hardware type of the device.
* @bound_dev_if: An optional device interface index.
* @transport: The transport type used.
* @net: Network namespace containing the bound_dev_if net_dev.
* @sgid_attr: GID attribute to use for identified SGID
*/
struct rdma_dev_addr {
unsigned char src_dev_addr[MAX_ADDR_LEN]; -> Исходный MAC(SMAC)
unsigned char dst_dev_addr[MAX_ADDR_LEN]; -> глазизMAC(DMAC)
unsigned char broadcast[MAX_ADDR_LEN];
unsigned short dev_type;
int bound_dev_if;
enum rdma_transport_type transport;
struct net *net;
const struct ib_gid_attr *sgid_attr;
enum rdma_network_type network;
int hoplimit;
};
addr_resolve
rdma_set_src_addr_rcu
...
rdma_translate_ip -> Translate a local IP address to an RDMA hardware
dev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if) -> IB/addr:Волясетьпространство именкакпараметрпередача,дляib_addrмодульдобавить всетьпространство именподдерживать. дляэтот,всеадресанализироватьи匹配Всеотвечать Должениспользоватьподходящийкогдаизпространство имени Нетда init_net завершить. этотдапроходитьк Вниз Способвыполнитьиз: 1. Воляявныйсетьпространство именпараметрдобавить вприезжатьнуждатьсяхотетьпространство имениз Экспортфункция。 2. Воляпространство имендержатьсуществовать rdma_addr_client структурасередина. 3. вызовсеть Функциячасиспользовать。 длябронироватьвызовмодульиз Поведение,&init_net существовать Чтоонмодульизвызовсерединакакпараметрпередача。 вместе ссуществовать Дажемногоуровеньначальстводобавить впространство именподдерживать,этотсодержаниеужеодеяло Исправлять -> Deprecated for new users, call netdev_get_by_index() instead -> netdev_get_by_index() - проходить ifindex проверятьпопытаться найтиоборудование, @net:подходящийиспользоватьизсетьпространство имен @ifindex:оборудованиеиндекс @tracker:получать Цитироватьизотслеживатьвернослон @gfp:отслеживатьустройствоизфлаг выделения Поиск интерфейса по индексу. еслиеще нетпопытаться найтиприезжатьоборудованиеилиобратитесь к Коборудованиеизуказатель,затем вернись NULL。 возвращатьсяизоборудованиеужедобавить в Цитировать,иуказательда Безопасностьиз,прямойприезжатьпользовательвызов netdev_put() указать, что они закончили его использовать
dev_get_by_index_rcu(net, ifindex)
hlist_for_each_entry_rcu(dev, head, index_hlist)
rdma_copy_src_l2_addr(dev_addr, dev)
memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN)
dev = rdma_find_ndev_for_src_ip_rcu(dev_addr->net, addr)
switch (src_in->sa_family)
case AF_INET:
__ip_dev_find
ifa = inet_lookup_ifaddr_rcu(net, addr)
u32 hash = inet_addr_hash(net, addr)
net_eq(dev_net(ifa->ifa_dev->dev), net)
local = fib_get_table(net, RT_TABLE_LOCAL)
fib_table_lookup
trace_fib_table_lookup
case AF_INET6:
ipv6_chk_addr -> ipv6_chk_addr_and_flags -> VRF оборудованиеи ip правила в совокупности обеспечивают существование Linux сетькучасерединасоздавать虚拟дорога Зависит отидомен пересылки(Также известен как ВРФ, в частности VRF-lite) из возможностей. одиндобрыйвариант использованиядамногожилецвопрос,вкаждыйжилец Всеиметь Собственныйуникальныйиздорога Зависит отповерхность,и至少нуждатьсяхотеть Неттакой жеизпо умолчаниюшлюз。 проходить Волярозеткаобязательностьприезжать VRF оборудование,Процессы могут быть «осведомлены о VRF». Затем,проходитьрозеткаизданные Сумкаиспользоватьи VRF оборудование Ассоциациядорога Зависит отповерхность. VRF оборудованиевыполнитьизодин Тяжелыйхотетьособенностьдаэтотолько Влияние Нет. 3 слойикначальствослой,потому чтоэтот L2 инструменты (например, LLDP) не затрагиваются (т.е. им не требуется существование каждого VRF вбегаю). Должендизайнвозвращатьсяпозволятьиспользоватьболее высокий приоритетиз IP регулированиено(на основе Стратегияиздорога Зависит от,PBR),к优Первый Вв соответствии снуждатьсяхотетьгидидентификацияпотокколичествоиз VRF оборудованиерегулированиено。 этотснаружи,VRF оборудованиепозволять VRF Вложен в пространство имен существования. Например,сетьпространство именпоставлятьоборудованиеслойсетьинтерфейсизразделение,пространство имен Внутриинтерфейсначальствоиз VLAN поставлять L2 отдельно, а затем VRF оборудованиепоставлять L3 разлука. дизайн VRF оборудованиедапроходить Ассоциациядорога Зависит отповерхностьсоздаватьиз。 Тогда сетевой интерфейс подчиняется VRF оборудование:-> net/ipv6:Изменятьадресисследоватьк始конец采использоватьоборудованиепараметр,ipv6_chk_addr_and_flags OK адресда Нет далокальногоадреса,ки(Необязательный)данетдаидентификацияоборудованиеначальствоизадрес. Например, по ip6_route_info_create вызовэто Приходить Конечно Данныйизшлюзадресданетдаместныйадрес. адресисследоватькогдавперед Нетучитывать L3 домен,потому чтоэтотесли Внизодин Прыжокобратитесь к КНет.два VRF серединаизадрес,но Нетпозволятьсуществоватьодин VRF серединадобавить вдорога Зависит от。 Например, $ ip route add 2001:db8:1::/64 vrf r2 via 2001:db8:102::23 ошибка:шлюзадресневерный。 в 2001:db8:102::23 да vrf r1 серединаинтерфейсначальствоизадрес. ipv6_chk_addr_and_flags нуждатьсяхотетьпозволятьвызов ВОЗ始конец传入приноситьиметь单独параметризоборудование,котказался Воляадреспределдляидентификацияоборудование. Долженоборудованиеиспользуется для Конечнозаинтересованныйиз L3 домен. дляэтот,добавить водинпараметрк Прыжок Проходитьоборудованиеисследоватьивозобновлятьвызов ВОЗк始конецсуществовать Можетспособныйиз Состояние Внизпередачаоборудование,ииспользоватьновыйпараметр Приходитьповерхность Показыватьдоменсерединаизлюбойадрес. использовать NULL dev параметрвозобновлять ipv6_chk_addr из少числопользователь。 этотпластырьиметь дело сверноэтотнекоторыйвызов ВОЗиз Изменять,и无нуждатьсядобавить вдоменисследовать。 ip6_validate_gw Нужно иметь дело с 2 ситуация - одиндобрыйдаоборудованиекак Внизодин Прыжокспецификацияизчастьданный,Другойодиндобрыйдаоборудованиеодеялоанализировать。 Есть по крайней мере 1 добрый VRF Состояние,Воляисследоватьоткладыватьприезжатьтолькосуществоватьдорога Зависит отпроверятьпопытаться найтиразвязать决Изназад,оборудованиевстречанеудачаивнесейчас Нетпрямойвидизошибка“RTNETLINK Отвечать:Нетприезжатьхозяинмашинаиздорога Зависит от”,и Нетда Первый выбориз“ошибка:шлюз Нетспособныйдаместныйадрес” ”。 “Нетприезжатьхозяинмашинаиздорога Зависит от”ошибкадапотому чтооткатприезжать完整проверятьпопытаться найтиипривести киз。 исследовать两Второсортныйкизбегатьэтотошибка
inet6_addr_hash
l3mdev_master_dev_rcu
ipv6_addr_equal
iproute2: https://github.com/ssbandjl/iproute2.git, https://github.com/ssbandjl/MLNX_OFED_SRC-5.9-0.5.6.0/tree/main/SOURCES/mlnx-iproute2-6.0.0
Таблица символов Linux/таблица символов загруженного модуля/драйвера: https://sysprogs.com/VisualKernel/documentation/kernelsymbols/
Загрузка модулей Linux/процесс загрузки модуля: https://www.cnblogs.com/sky-heaven/p/13280255.html, https://www.cnblogs.com/aspirs/p/15522142.html
блог: 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/интеллектуальными сетевыми картами/разгрузкой/сетями, ускорением хранения данных/изоляцией безопасности и другими технологиями, могут присоединиться к группе обмена технологиями DPU.