Шаблон драйвера диспетчера подключений rdma
Я использую реализацию OFD 3.18r2 драйверов Infiniband для моего приложения. В частности, я использую функции-оболочки диспетчера подключений rdma. Чтобы лучше понять, что происходит под капотом, я привык смотреть на исходный код. Делая это, я наткнулся на что-то похожее на шаблон, но я не могу этого понять. Давайте сделаем пример. Функции диспетчера подключений rdma находятся в cma.c. Посмотрим, например, на вызов rdma_listen (это характерно почти для всех функций, определенных в библиотеке, которые начинаются с "rdma_"):
int rdma_listen(struct rdma_cm_id *id, int backlog)
{
struct ucma_abi_listen cmd;
struct cma_id_private *id_priv;
int ret;
CMA_INIT_CMD(&cmd, sizeof cmd, LISTEN);
id_priv = container_of(id, struct cma_id_private, id);
cmd.id = id_priv->handle;
cmd.backlog = backlog;
ret = write(id->channel->fd, &cmd, sizeof cmd);
if (ret != sizeof cmd)
return (ret >= 0) ? ERR(ENODATA) : -1;
if (af_ib_support)
return ucma_query_addr(id);
else
return ucma_query_route(id);
}
Здесь вы можете увидеть шаблон, который я упоминал ранее:
ret = write(id->channel->fd, &cmd, sizeof cmd);
Первый аргумент вызова write - это дескриптор файла, связанный с / dev / infiniband / rdma_cm, но я не могу понять использование аргументов cmd. Я копаюсь в источнике только для того, чтобы обнаружить, что cmd является структурой, которая используется для определения ABI вызовов функции rdma cm. Я действительно не понимаю, является ли это общим шаблоном для выполнения вызовов драйвера устройства и как он работает, где настоящий код, связанный с аргументом cmd. Не могли бы вы мне помочь?
1 ответ
Используя write()
Системный вызов для выполнения команд является распространенным методом для выполнения команд в подсистеме RDMA. Он используется, среди прочего, модулем rdma_ucm и модулем ib_uverbs. Код ядра, связанный с rdma_ucm, можно найти в файле drivers / infiniband / core / ucma.c. В частности, write()
Системный вызов для этого устройства реализован в ucma_write()
функция.
Я не думаю, что есть много документации по этому методу вызова в драйвер. user_verbs.txt
документ в документации ядра гласит:
Commands are sent to the kernel via write()s on these device files.
The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
The structs for commands that require a response from the kernel
contain a 64-bit field used to pass a pointer to an output buffer.
Status is returned to userspace as the return value of the write()
system call.
Я думаю, что это может быть небольшое злоупотребление write()
системный вызов, который реализует нечто более похожее на ioctl()
,
Изменить: Обратите внимание, что я добавил ссылку на модуль ядра вышестоящего, но структура источника OFED похожа. Изменить: Добавлены некоторые указатели документации.