Mellanox libvma: Как получить временную метку пакета, сопоставимую с временем пользователя? - PullRequest
0 голосов
/ 17 марта 2020

При использовании сокетов по умолчанию Linux прием временных меток работал для меня так:

char ctrl[CMSG_SPACE(sizeof(struct timeval))];

struct msghdr msg;
struct iovec iov;
msg.msg_control = (char*)ctrl;
msg.msg_controllen = sizeof(ctrl);
msg.msg_name = &cfg->ifaddr;
msg.msg_namelen = sizeof(cfg->ifaddr);

msg.msg_iov = &iov;
msg.msg_iovlen = 1;
iov.iov_base = buffer;
iov.iov_len = BUFFER_SIZE;

struct timeval time_user, time_kernel;
struct cmsghdr *cmsg = (struct cmsghdr*)&ctrl;

const int64_t read_bytes = recvmsg(igmp_socket_fd, &msg, 0);
if(read_bytes == -1) {
    return;
}

gettimeofday(&time_user, NULL);

if(cmsg->cmsg_level == SOL_SOCKET) {
    memcpy(&time_kernel, CMSG_DATA(cmsg), sizeof(struct timeval));
    const double timediff = (time_user.tv_sec - time_kernel.tv_sec) * 1000000 + (time_user.tv_usec - time_kernel.tv_usec);
}

Но с

vma_api->recvfrom_zcopy(socket_fd, buffer, BUFFER_SIZE, &flags, &sa, &sock_len);

нет способа передать struct msghdr (также нет функции recvmsg). Руководство (https://www.mellanox.com/related-docs/prod_acceleration_software/VMA_8_6_10_User_Manual.pdf) на странице 38 только говорит мне, что мне нужен работающий PTP-демон.

Кто-нибудь знает, можно ли и как получить временную метку с помощью libvma, которая сопоставима? gettimeofday в пользовательском пространстве?

1 Ответ

0 голосов
/ 19 марта 2020

Похоже, recvmsg перезаписывается libvma (в случае, если он предварительно загружен LD_PRELOAD), поэтому мой пример кода в посте выше также может быть использован. Кроме того, vma_cyclic_buffer_read предоставляет аппаратную метку времени (которая обычно синхронизируется с временем в пользовательском пространстве с помощью параметра VMA_HW_TS_CONVERSION=3) для первого пакета буфера (к сожалению, не для каждого пакета):

struct vma_completion_cb_t vma_completion;
memset(&vma_completion, 0, sizeof(struct vma_completion_cb_t));
vma_completion.comp_mask = VMA_CB_MASK_TIMESTAMP; /* important */

const int ret = vma_api->vma_cyclic_buffer_read(ring_fd, &vma_completion, 100, 5000, flags);
/* ... */
struct timeval usr_timeval;
gettimeofday(&usr_timeval, NULL);

const uint16_t timediff_us = calc_us_timeval_spec_diff(&usr_timeval, &vma_completion.hw_timestamp);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...