首页 > 解决方案 > Mellanox libvma:如何接收与用户空间时间相当的数据包时间戳?

问题描述

使用默认的 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);

没有办法通过 a struct msghdr(也没有recvmsg-function)。第 38 页的手册 ( https://www.mellanox.com/related-docs/prod_acceleration_software/VMA_8_6_10_User_Manual.pdf ) 只告诉我需要运行 PTP 守护程序。

有谁知道我是否以及如何使用 libvma 接收与gettimeofday用户空间相当的时间戳?

标签: clinuxsocketsnetworking

解决方案


看起来,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);

推荐阅读