You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DPDK程序配置:仅保留UDP/TCP报文头入队(ConnectX-6 DX网卡)

解决方案:DPDK中仅保留报文头存储的实现方案

一、硬件层面:利用网卡截断功能直接接收报文头

你的Mellanox ConnectX-6 DX网卡支持硬件数据包截断,配合rte_flow可以直接让网卡只传输指定长度的报文头(比如前64字节,足以覆盖以太网+IP+TCP/UDP头部),数据部分直接在网卡端丢弃,从根源上减少内存占用和主机处理开销。

实现步骤:
在创建rte_flow过滤UDP/TCP的规则时,添加RTE_FLOW_ACTION_TYPE_TRUNCATE动作,指定截断长度:

struct rte_flow_action_truncate truncate_cfg = {
    .length = 64, // 根据实际头部长度调整,确保覆盖L2-L4头部
};
struct rte_flow_action actions[] = {
    { .type = RTE_FLOW_ACTION_TYPE_TRUNCATE, .conf = &truncate_cfg },
    { .type = RTE_FLOW_ACTION_TYPE_ACCEPT },
};
// 后续搭配UDP/TCP的匹配规则完成flow创建

二、软件层面:处理mbuf时裁剪或分离数据部分

如果硬件截断不满足需求,可在软件层面对接收后的mbuf做处理:

1. 直接裁剪mbuf保留头部

用rte_pktmbuf_trim()调整mbuf的长度,只保留所需头部,多余的数据部分会被标记为无效,释放mbuf时完整归还内存池:

uint32_t needed_header_len = 64;
struct rte_mbuf *rx_mbufs[BURST_SIZE];
uint16_t nb_rx = rte_eth_rx_burst(port_id, queue_id, rx_mbufs, BURST_SIZE);

for (int i = 0; i < nb_rx; i++) {
    struct rte_mbuf *mbuf = rx_mbufs[i];
    if (rte_pktmbuf_pkt_len(mbuf) > needed_header_len) {
        int ret = rte_pktmbuf_trim(mbuf, rte_pktmbuf_pkt_len(mbuf) - needed_header_len);
        if (ret < 0) {
            rte_pktmbuf_free(mbuf);
            continue;
        }
    }
    // 将裁剪后的mbuf存入队列
    enqueue_to_custom_queue(mbuf);
}

2. 用Indirect Mbuf分离元数据与头部

如果需要保留原始mbuf的元数据(如端口号、RSS哈希值)但只存头部,可创建间接mbuf复制头部后释放原始mbuf:

uint32_t needed_header_len = 64;
struct rte_mempool *indirect_mempool = /* 提前初始化的间接mbuf内存池 */;

for (int i = 0; i < nb_rx; i++) {
    struct rte_mbuf *orig_mbuf = rx_mbufs[i];
    struct rte_mbuf *header_mbuf = rte_pktmbuf_indirect_alloc(indirect_mempool);
    if (!header_mbuf) {
        rte_pktmbuf_free(orig_mbuf);
        continue;
    }
    // 复制头部数据到间接mbuf
    rte_memcpy(rte_pktmbuf_mtod(header_mbuf, void*), 
               rte_pktmbuf_mtod(orig_mbuf, void*), 
               needed_header_len);
    // 设置间接mbuf的长度字段
    header_mbuf->pkt_len = needed_header_len;
    header_mbuf->data_len = needed_header_len;
    
    rte_pktmbuf_free(orig_mbuf);
    enqueue_to_custom_queue(header_mbuf);
}

三、结合RX Callback优化流程

基于你使用的收发包回调示例,可把裁剪逻辑放到RX回调中,实现接收时自动处理:

static uint16_t rx_header_only_callback(uint16_t port_id, uint16_t queue_id, 
                                        struct rte_mbuf **mbufs, uint16_t nb_bufs, 
                                        void *user_param) {
    uint32_t header_len = *(uint32_t*)user_param;
    uint16_t valid_cnt = 0;
    
    for (int i = 0; i < nb_bufs; i++) {
        struct rte_mbuf *mbuf = mbufs[i];
        if (rte_pktmbuf_pkt_len(mbuf) > header_len) {
            if (rte_pktmbuf_trim(mbuf, rte_pktmbuf_pkt_len(mbuf) - header_len) < 0) {
                rte_pktmbuf_free(mbuf);
                mbufs[i] = NULL;
                continue;
            }
        }
        mbufs[valid_cnt++] = mbuf;
    }
    return valid_cnt;
}

// 初始化时注册回调
uint32_t target_header_len = 64;
rte_eth_rx_callback_register(port_id, queue_id, rx_header_only_callback, &target_header_len);

四、关键注意事项

  • ConnectX-6 DX完全支持rte_flow的TRUNCATE动作,需确保DPDK版本≥20.11(建议用LTS版本),mlx5驱动正常加载。
  • 若用硬件截断,可配置更小的mbuf数据缓冲区(比如128字节),进一步节省内存。
  • 性能优先级:硬件截断 > 软件裁剪 > 间接mbuf(间接mbuf存在内存拷贝,适合需保留元数据的场景)

内容的提问来源于stack exchange,提问作者Daniel Gilkarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:43:20