DPDK-REORDER LIBRARY 排序库

0x01 缘由

     排序,不要与tcp流重组排序混淆,而且下文踢桃序列号和tcp序列号不是同一个。此库为非线程安全的。

0x02 介绍

     1.引言

     Reorder Library 提供一种机制依据序列号对mbuf进行排序。

     2.操作

     Reorder Library实质上是一个mbuf有序buffer。使用者将乱序的mbuf插入到有序的buffer中,然后从中有序的取出。
     在给定时间内,这个重排buffer包含序列号在序列窗口内的mbufs。序列窗口由最小序列数和重排序buffer配置的持有条目数决定。例如,给一个有200条目的重排序buffer和350的最小序列,这个序列窗口最小值和最大值分别为350,550。
     当插入mbufs时,Reorder Library依赖插入在mbuf中序列号来区分先后的有效性:
     vaild: 序列号在窗口内。
     late: 序列号在窗口外,小于最小序列号。
     early:序列号在窗口外,大于最大序列号。
     重排buffer直接返回late mbufs,然后尝试容纳early mbufs。

     3.实现细节

     Reorder Library 实现一对缓冲区,称为Oder buffer 和Ready buffer。
     调用一个插入方法,vaild mbufs是直接插入到Oder buffer,而late mbufs是直接返回一个错误信息。
     对于early mbufs这种情况下,重新排序buffer将尝试移动窗口(递增最小序列号),以使mbuf变为有效的。为此,在Oder buffer中mbufs被移到Ready buffer中。任何mbufs没有及时到达的将被忽略,因此将变为late mbufs。这意味着只要Ready buffer中有多余的空间,窗口就会移动来容纳early mbufs,否则就会在重排窗口之外。
     例如,假设有一个200条目和最小序列为350的重排buffer,然后我们需要差异个序号为565的early mbuf。这说明我们至少需要移动窗口15个位置去容纳这个mbuf。这个重排buffer尝试移动mbufs在Order buffer中15个槽到Ready buffer中,只要Ready buffer中有足够的空间。在这个点的Order buffer的任何空隙将调过,当后面到来的包将被当做late包。将数据包移动Ready buffer过程持续到最小值知道一个空隙,如在Order buffer 遇到丢包。
     当处理mbufs过程时,这个重排buffer将先把Ready buffer中的mbuf返回,然后Order buffer中的直到遇到丢包。

0x03 应用

     案例:包分发器
     使用DPDK实现一个包分发器的应用,利用到Reorder Library库按包接收的顺序去转发数据包。
     一个基本的包分发器由一个分发器和多个worker线程组成。这个worker线程无法保证包有序的,因此一个重排序缓存能够尽可能的讲包排序处理。
     在这种场景下,在将mbufs派送到works前,包分发器分配一个序列号到mbuf。当works完成包处理时,这个包分发器插入这个mbufs到重排序buffer,然后最后转发到处理mbufs。

0x04 DPDK example

[root@dev packet_ordering]# ls
build  main.c  Makefile
[root@dev packet_ordering]# make clean
[root@dev packet_ordering]# make
  CC main.o
  LD packet_ordering
  INSTALL-APP packet_ordering
  INSTALL-MAP packet_ordering.map

       /* Create rings for inter core communication */
        rx_to_workers = rte_ring_create("rx_to_workers", RING_SIZE, rte_socket_id(),
                        RING_F_SP_ENQ);
        if (rx_to_workers == NULL)
                rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));

        workers_to_tx = rte_ring_create("workers_to_tx", RING_SIZE, rte_socket_id(),
                        RING_F_SC_DEQ);
        if (workers_to_tx == NULL)
                rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));

        if (!disable_reorder) {
                send_args.buffer = rte_reorder_create("PKT_RO", rte_socket_id(),
                                REORDER_BUFFER_SIZE);
                if (send_args.buffer == NULL)
                        rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));
        }

        last_lcore_id   = get_last_lcore_id();
        master_lcore_id = rte_get_master_lcore();

        worker_args.ring_in  = rx_to_workers;
        worker_args.ring_out = workers_to_tx;

        /* Start worker_thread() on all the available slave cores but the last 1 */
        for (lcore_id = 0; lcore_id <= get_previous_lcore_id(last_lcore_id); lcore_id++)
                if (rte_lcore_is_enabled(lcore_id) && lcore_id != master_lcore_id)
                        rte_eal_remote_launch(worker_thread, (void *)&worker_args,
                                        lcore_id);

        if (disable_reorder) {
                /* Start tx_thread() on the last slave core */
                rte_eal_remote_launch((lcore_function_t *)tx_thread, workers_to_tx,
                                last_lcore_id);
        } else {
                send_args.ring_in = workers_to_tx;
                /* Start send_thread() on the last slave core */
                rte_eal_remote_launch((lcore_function_t *)send_thread,
                                (void *)&send_args, last_lcore_id);
        }

        /* Start rx_thread() on the master core */
        rx_thread(rx_to_workers);



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值