vpp hqos分析

news2024/11/26 12:24:38

vpp支持两套qos实现,一套是基于policer实现的qos,另外一套是基于dpdk的qos套件实现的hqos。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! ! 

基本流程图

 

如上图所示,worker线程从nic中读取报文进行处理,调用dpdk设备发送函数时,如果配置了hqos,那么设置hqos相关参数,将其送入swq队列(swq队列与worker线程是1:1的关系),worker线程处理结束,hqos线程(根据配置决定个数)轮询从swq中读取报文进行qos处理,qos使用的是dpdk qos套件。

HQOS配置解析

dpdk配置

dpdk {
  socket-mem 16384,16384

  dev 0000:02:00.0 {
    num-rx-queues 2
    hqos #使能网卡hqos
  }
  dev 0000:06:00.0 {
    num-rx-queues 2
    hqos #使能网卡hqos
  }

  num-mbufs 1000000
}

cpu配置

cpu {
  main-core 0
  corelist-workers  1, 2, 3, 4
  corelist-hqos-threads  5, 6  #启动两个hqos线程,分别使用cpu5和6
}

通过上面两步配置即可开启hqos配置,会使用默认的hqos配置。

dpdk qos相关参数配置

  • port configuration
port {
  rate 1250000000           /* Assuming 10GbE port */
  frame_overhead 24         /* Overhead fields per Ethernet frame:
                             * 7B (Preamble) +
                             * 1B (Start of Frame Delimiter (SFD)) + 
                             * 4B (Frame Check Sequence (FCS)) +
                             * 12B (Inter Frame Gap (IFG))
                             */
  mtu 1522                  /* Assuming Ethernet/IPv4 pkt (FCS not included) */
  n_subports_per_port 1     /* Number of subports per output interface */
  n_pipes_per_subport 4096  /* Number of pipes (users/subscribers) */
  queue_sizes 64 64 64 64   /* Packet queue size for each traffic class.
                             * All queues within the same pipe traffic class
                             * have the same size. Queues from different
                             * pipes serving the same traffic class have
                             * the same size. */
}
  • subport configuration
subport 0 {
  tb_rate 1250000000        /* Subport level token bucket rate (bytes per second) */
  tb_size 1000000           /* Subport level token bucket size (bytes) */
  tc0_rate 1250000000       /* Subport level token bucket rate for traffic class 0 (bytes per second) */
  tc1_rate 1250000000       /* Subport level token bucket rate for traffic class 1 (bytes per second) */
  tc2_rate 1250000000       /* Subport level token bucket rate for traffic class 2 (bytes per second) */
  tc3_rate 1250000000       /* Subport level token bucket rate for traffic class 3 (bytes per second) */
  tc_period 10              /* Time interval for refilling the token bucket associated with traffic class (Milliseconds) */
  pipe 0 4095 profile 0     /* pipe 0到4095使用profile0 pipes (users/subscribers) configured with pipe profile 0 */
}
  • pipe configuration
pipe_profile 0 {
  tb_rate 305175          /* Pipe level token bucket rate (bytes per second) */
  tb_size 1000000         /* Pipe level token bucket size (bytes) */
  tc0_rate 305175         /* Pipe level token bucket rate for traffic class 0 (bytes per second) */
  tc1_rate 305175         /* Pipe level token bucket rate for traffic class 1 (bytes per second) */
  tc2_rate 305175         /* Pipe level token bucket rate for traffic class 2 (bytes per second) */
  tc3_rate 305175         /* Pipe level token bucket rate for traffic class 3 (bytes per second) */
  tc_period 40            /* Time interval for refilling the token bucket associated with traffic class at pipe level (Milliseconds) */
  tc3_oversubscription_weight 1 /* Weight traffic class 3 oversubscription */
  tc0_wrr_weights 1 1 1 1     /* Pipe queues WRR weights for traffic class 0 */
  tc1_wrr_weights 1 1 1 1     /* Pipe queues WRR weights for traffic class 1 */
  tc2_wrr_weights 1 1 1 1     /* Pipe queues WRR weights for traffic class 2 */
  tc3_wrr_weights 1 1 1 1     /* Pipe queues WRR weights for traffic class 3 */
}
  • red 拥塞控制
red {
  tc0_wred_min 48 40 32     /* Minimum threshold for traffic class 0 queue (min_th) in number of packets */
  tc0_wred_max 64 64 64     /* Maximum threshold for traffic class 0 queue (max_th) in number of packets */
  tc0_wred_inv_prob 10 10 10    /* Inverse of packet marking probability for traffic class 0 queue (maxp = 1 / maxp_inv) */
  tc0_wred_weight 9 9 9     /* Traffic Class 0 queue weight */
  tc1_wred_min 48 40 32     /* Minimum threshold for traffic class 1 queue (min_th) in number of packets */
  tc1_wred_max 64 64 64     /* Maximum threshold for traffic class 1 queue (max_th) in number of packets */
  tc1_wred_inv_prob 10 10 10    /* Inverse of packet marking probability for traffic class 1 queue (maxp = 1 / maxp_inv) */
  tc1_wred_weight 9 9 9     /* Traffic Class 1 queue weight */
  tc2_wred_min 48 40 32     /* Minimum threshold for traffic class 2 queue (min_th) in number of packets */
  tc2_wred_max 64 64 64     /* Maximum threshold for traffic class 2 queue (max_th) in number of packets */
  tc2_wred_inv_prob 10 10 10    /* Inverse of packet marking probability for traffic class 2 queue (maxp = 1 / maxp_inv) */
  tc2_wred_weight 9 9 9     /* Traffic Class 2 queue weight */
  tc3_wred_min 48 40 32     /* Minimum threshold for traffic class 3 queue (min_th) in number of packets */
  tc3_wred_max 64 64 64     /* Maximum threshold for traffic class 3 queue (max_th) in number of packets */
  tc3_wred_inv_prob 10 10 10    /* Inverse of packet marking probability for traffic class 3 queue (maxp = 1 / maxp_inv) */
  tc3_wred_weight 9 9 9     /* Traffic Class 3 queue weight */
}

port,subport,pipe,tc,queue这些配置某些参数也可以使用命令行或者api进行配置。

CLI配置qos

  • 可以使用如下命令配置subport参数
set dpdk interface hqos subport <if-name> subport <n> [rate <n>] [bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]
  • 配置pipe参数
set dpdk interface hqos pipe <if-name> subport <n> pipe <n> profile <n>
  • 指定接口的hqos处理线程
set dpdk interface hqos placement <if-name> thread <n>
  • 设置报文的具体域用于报文分类,其中id为hqos_field编号
set dpdk interface hqos pktfield <if-name> id <n> offset <n> mask <n>
  • 设置tc和tcq映射表,根据dscp映射到具体的tc和tcq
set dpdk interface hqos tctbl <if-name> entry <n> tc <n> queue <n>
  • 查看hqos配置命令
vpp# show dpdk interface hqos TenGigabitEthernet2/0/0
 Thread:
   Input SWQ size = 4096 packets
   Enqueue burst size = 256 packets
   Dequeue burst size = 220 packets
   Packet field 0: slab position =    0, slab bitmask = 0x0000000000000000
   Packet field 1: slab position =   40, slab bitmask = 0x0000000fff000000
   Packet field 2: slab position =    8, slab bitmask = 0x00000000000000fc
   Packet field 2 translation table:
   [ 0 .. 15]:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
   [16 .. 31]:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
   [32 .. 47]:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
   [48 .. 63]:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 Port:
   Rate = 1250000000 bytes/second
   MTU = 1514 bytes
   Frame overhead = 24 bytes
   Number of subports = 1
   Number of pipes per subport = 4096
   Packet queue size: TC0 = 64, TC1 = 64, TC2 = 64, TC3 = 64 packets
   Number of pipe profiles = 1
   Pipe profile 0:
   Rate = 305175 bytes/second
   Token bucket size = 1000000 bytes
   Traffic class rate: TC0 = 305175, TC1 = 305175, TC2 = 305175, TC3 = 305175 bytes/second
   TC period = 40 milliseconds
   TC0 WRR weights: Q0 = 1, Q1 = 1, Q2 = 1, Q3 = 1
   TC1 WRR weights: Q0 = 1, Q1 = 1, Q2 = 1, Q3 = 1
   TC2 WRR weights: Q0 = 1, Q1 = 1, Q2 = 1, Q3 = 1
   TC3 WRR weights: Q0 = 1, Q1 = 1, Q2 = 1, Q3 = 1
  • 查看设备所属的hqos线程
vpp# show dpdk interface hqos placement
  Thread 5 (vpp_hqos-threads_0 at lcore 5):
      TenGigabitEthernet2/0/0 queue 0
  Thread 6 (vpp_hqos-threads_1 at lcore 6):
       TenGigabitEthernet4/0/1 queue 0

DPDK QOS套件

该部分内容请参考:

http://doc.dpdk.org/guides/pr...

HQOS源码分析

数据结构

dpdk_device_t

HQOS是基于每个dpdk设备的,所以dpdk设备描述控制块存在与hqos相关的成员。

typedef struct
{
    ......
    /* HQoS related 工作线程与hqos线程之间有一个映射关系,因为两者线程不一样多 */
    dpdk_device_hqos_per_worker_thread_t *hqos_wt;//工作线程队列,工作线程往hqos_wt.swq中写报文,swq指向hqos_ht.swq
    dpdk_device_hqos_per_hqos_thread_t *hqos_ht;//hqos线程队列,hqos线程从hqos_ht.swq中读报文
    ......
} dpdk_device_t;

dpdk_device_hqos_per_worker_thread_t

typedef struct
{
    /* Required for vec_validate_aligned */
    CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);

    struct rte_ring *swq;//指向该设备的该线程将报文写入的目标环形队列。
    //这些参数用来对报文进行分类,设置dpdk qos的subport,pipe,tc,queue等参数
    u64 hqos_field0_slabmask;
    u32 hqos_field0_slabpos;
    u32 hqos_field0_slabshr;
    u64 hqos_field1_slabmask;
    u32 hqos_field1_slabpos;
    u32 hqos_field1_slabshr;
    u64 hqos_field2_slabmask;
    u32 hqos_field2_slabpos;
    u32 hqos_field2_slabshr;
    u32 hqos_tc_table[64];
} dpdk_device_hqos_per_worker_thread_t;

上面是每工作线程与hqos相关的私有数据,dpdk设备维护一个这样的数组,每一个工作线程一个成员。该结构中的成员主要用来对报文进行分类,从上面可以看出,报文分类太简单,无法满足较细的分类需求。可以结合分类器做进一步改进。

dpdk_device_hqos_per_hqos_thread_t

typedef struct
{
    /* Required for vec_validate_aligned */
    CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
    struct rte_ring **swq;//worker thread和hqos thread线程报文中转环形队列数组,其大小等于worker线程的个数
    struct rte_mbuf **pkts_enq;//入队,用于从swq中提取报文放入到pkts_enq中,然后将pkts_enq中的报文压入qos
    struct rte_mbuf **pkts_deq;//出队,从qos中提取报文,然后从网口发送出去。
    struct rte_sched_port *hqos;//设备的dpdk qos配置参数
    u32 hqos_burst_enq;//设备一次入队报文的个数限制
    u32 hqos_burst_deq;//设备一次出队报文的个数限制
    u32 pkts_enq_len;//当前入队报文中的个数
    u32 swq_pos;//hqos迭代器当前处理的软件队列的位置
    u32 flush_count;//当前报文不足批量写入个数空转次数,达到一定次数后,立即写入,不再等待。
} dpdk_device_hqos_per_hqos_thread_t;

上面是每hqos线程与hqos相关的私有数据,一个dpdk设备只能属于一个hqos线程。该结构主要维护与worker线程的桥接队列以及该port的hqos参数。

dpdk_main_t

typedef struct
{
    ......
    //dpdk设备hqos cpu索引数组,根据hqos索引获取其管理的dpdk设备数组,构建了hqos线程与dpdk设备的关系,是一对多的关系
    dpdk_device_and_queue_t **devices_by_hqos_cpu;
    ......
} dpdk_main_t;

hqos类线程注册

/* *INDENT-OFF* 注册dpdk类线程*/
VLIB_REGISTER_THREAD (hqos_thread_reg, static) =
{
    .name = "hqos-threads",
    .short_name = "hqos-threads",
    .function = dpdk_hqos_thread_fn,//执行函数
};

前面提到的配置corelist-hqos-threads 5,6 。VPP在解析到该配置后,会使用hqos-threads去线程类型链表中去查找是否存在这样的线程,找到后会启动对应个数的该类线程,线程的主函数为dpdk_hqos_thread_fn

函数实现

dpdk_hqos_thread_fn

//dpdk线程执行函数
void
dpdk_hqos_thread_fn (void *arg)
{
    vlib_worker_thread_t *w = (vlib_worker_thread_t *) arg;
    vlib_worker_thread_init (w);//hqos线程初始化
    dpdk_hqos_thread (w);
}

void
dpdk_hqos_thread (vlib_worker_thread_t * w)
{
    vlib_main_t *vm;
    vlib_thread_main_t *tm = vlib_get_thread_main ();
    dpdk_main_t *dm = &dpdk_main;

    vm = vlib_get_main ();

    ASSERT (vm->thread_index == vlib_get_thread_index ());

    clib_time_init (&vm->clib_time);
    clib_mem_set_heap (w->thread_mheap);

    /* Wait until the dpdk init sequence is complete */
    while (tm->worker_thread_release == 0)
        vlib_worker_thread_barrier_check ();
    //根据cpu索引
    if (vec_len (dm->devices_by_hqos_cpu[vm->thread_index]) == 0)
        return
            clib_error
            ("current I/O TX thread does not have any devices assigned to it");

    if (DPDK_HQOS_DBG_BYPASS)
        dpdk_hqos_thread_internal_hqos_dbg_bypass (vm);//调试函数,用于调试
    else
        dpdk_hqos_thread_internal (vm);//核心处理函数
}

dpdk_hqos_thread_internal

static_always_inline void
dpdk_hqos_thread_internal (vlib_main_t * vm)
{
    dpdk_main_t *dm = &dpdk_main;
    u32 thread_index = vm->thread_index;
    u32 dev_pos;

    dev_pos = 0;//起始设备编号
    while (1)//循环遍历每一个设备
    {
        vlib_worker_thread_barrier_check ();//查看主线程是否通知了sync
        //根据cpu id获取该cpu的设备数组
        u32 n_devs = vec_len (dm->devices_by_hqos_cpu[thread_index]);
        if (PREDICT_FALSE (n_devs == 0))
        {
            dev_pos = 0;
            continue;
        }
        //一圈遍历完成,开始新的一圈。
        if (dev_pos >= n_devs)
            dev_pos = 0;
        //获取当前需要遍历的设备的上下文
        dpdk_device_and_queue_t *dq =
            vec_elt_at_index (dm->devices_by_hqos_cpu[thread_index], dev_pos);
        //获取dpdk设备描述控制块
        dpdk_device_t *xd = vec_elt_at_index (dm->devices, dq->device);

原文链接:https://segmentfault.com/a/1190000019644679 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DPU网络开发SDK——DPDK(一)

随着软件定义网络SDN的不断发展&#xff0c;网络数据转发面的需求越来越多样化&#xff0c;这体现在更快的数据包处理速率&#xff0c;更高的网络吞吐带宽&#xff0c;更灵活的自定义网络协议。传统的硬件设备无法满足网络协议的自定义&#xff0c;而基于Linux内核网络协议栈的…

故障电弧探测器的必要性及组网方案 安科瑞 时丽花

摘要】&#xff1a;电气设备是建筑中不可缺少的一部分&#xff0c;具有较为重要的作用和意义&#xff0c;在应用过程中不仅能够提升建筑本身实用性能&#xff0c;而且可为消费者提供更加优良的生活环境。但设备一旦在运行过程中出现故障&#xff0c;不仅会影响居民正常生活&…

艾美捷细胞失巢凋亡检测试剂盒测定原理化验方案

对细胞外基质&#xff08;ECM&#xff09;的粘附对于许多粘附细胞的生存和繁殖至关重要细胞。细胞与ECM的粘附丧失或不当粘附导致的细胞凋亡定义为“anoikis”。Anoikis&#xff0c;来自希腊语无家可归的意思&#xff0c;与生理学有关组织更新和细胞稳态的过程。 癌症发展和生长…

做测试8年,33岁前只想追求大厂高薪,今年只求稳定收入

疫情3年&#xff0c;每一个行业的危机&#xff0c;每一个企业的倒下&#xff0c;背后都是无数人的降薪、降职和失业。这也暴露了人生的残酷真相&#xff1a;人活一辈子&#xff0c;总有“丰年”和“荒年” 优秀的测试既过得了丰年&#xff0c;也受得住荒年 一个测试宝妈&…

冒烟测试的7个好处,你是否经常用到它?

以下为作者观点&#xff1a; 冒烟测试(smoke testing)是在开发的早期阶段评估基本的软件组件&#xff0c;以检查它们是否 “着火”&#xff08;有问题&#xff09;&#xff0c;本文旨在介绍冒烟测试及其在程序开发过程中的作用。 什么是冒烟测试&#xff1f; 冒烟测试是在开…

Linux文件权限

Linux文件权限 文件权限介绍 Linux文件权限有三种&#xff1a; 权限对应字符可读(read)r可写(write)w可执行(execute)x 文件权限身份也有三种&#xff1a; 权限身份对应字符文件所有者(user)u文件所有者所在组(group)g其他(other)&#xff0c;即除了文件所有者和其所在组的…

简明误差卡尔曼滤波器(ESKF)及其推导过程

文章目录1. 简明ESKF简介ESKF基本过程及优点ESKF参数含义连续时间上的 ESKF状态方程误差状态方程推导误差状态的旋转项误差状态的速度项完整误差变量的运动学方程离散时间上的ESKF运动学方程ESKF的运动过程ESKF的更新过程ESKF的误差状态后续处理小结1. 简明ESKF 简介 本文主要…

电商新趋势:Starday拿下黑色星期五的制胜法宝是物流速度

国内电商“双十一”购物狂欢季活动已经闭幕&#xff0c;“双十二”又将袭来&#xff0c;但更多人却将眼光放在蓬勃发展的跨境电商行业中。当下跨境电商卖家们正在各大跨境电商服务平台的带领下全力备战&#xff0c;在“黑色星期五”期间推出各类大促活动&#xff0c;奋力冲刺20…

灌区量测水监测系统解决方案 灌区量测水系统解决方案 农业水价综合改革解决方案

平升电子灌区量测水监测系统解决方案/灌区量测水系统解决方案/农业水价综合改革解决方案&#xff0c;对灌区的渠道水位、流量、水雨情、土壤墒情、气象等信息进行监测&#xff0c;同时对泵站、闸门进行远程控制&#xff0c;对重点区域进行视频监控&#xff0c;实现了信息的采集…

网络面试知识

客户端与服务端的网络通信 bind函数 把一个本地协议地址和套接口绑定&#xff0c;比如把本机的2222端口绑定到套接口。注意&#xff1a;为什么在上图中客户端不需要调用bind函数&#xff1f;这是因为如果没有调用bind函数绑定一个端口的话&#xff0c;当调用connect函数时&…

Kotlin高仿微信-第18篇-单聊-删除单条信息

Kotlin高仿微信-项目实践58篇详细讲解了各个功能点&#xff0c;包括&#xff1a;注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。 Kotlin高仿…

FRED应用:激光二极管的模拟

简介 当提及模拟激光二极管时&#xff0c;FRED软件具有极大的灵活性。在这篇应用笔记中&#xff0c;将会描述简单到详细的激光光源模型。最基本的模型是高斯TEM0,0模。更高级的模型包括在束腰上偏移和发散中的像散光束。激光也可以使用其M2因子表示。最后&#xff0c;可以创…

【TeamViewer丨远程控制软件】上海道宁助您远程访问和即时远程支持,提高远程工作团队的生产力

TeamViewer是 全面的远程访问、远程控制 及远程支持解决方案 几乎适用于所有桌面和移动平台 包括Windows、macOS、Android及iOS 开发商介绍 TeamViewer诞生于2005年&#xff0c;办公地点遍布全球12个国家或地区&#xff0c;以基于云的技术为核心&#xff0c;致力于在全球…

Jina AI正式将DocArray捐赠给Linux基金会

DocArray 是一个用于处理、传输和存储多模态数据的 Python 工具包。DocArray 提供便捷的多模态数据处理功能&#xff0c;具备基于 Protobuf 提供高性能的网络传输性能&#xff0c;同时也为多种向量存储方案提供统一的 API 接口。现在 Jina AI 正式将 DocArray 项目捐赠给 Linux…

JAVA助农电商商城平台毕业设计,JAVA助农销售网站系统设计与实现,毕设作品参考

功能清单 【后台管理功能模块】 系统设置&#xff1a;设置关于我们、联系我们、加入我们、法律声明的信息。 广告管理&#xff1a;设置网站首页轮播图和链接地址。 留言管理&#xff1a;显示用户通过前台留言的列表&#xff0c;支持删除。 会员中心&#xff1a;显示所有注册用户…

鲲鹏devkit性能分析工具介绍(四)

鲲鹏devkit性能分析工具介绍&#xff08;四&#xff09; 前面我们已经介绍了鲲鹏devkit性能分析工具的全景分析、热点函数分析、进程/线程分析、微架构分析、和访存分析&#xff0c;由此可见进行性能调优绝对不能够仅仅去进行一方面的考察而是需要全方面的数据分析进行一定的舍…

外汇天眼:经济衰退无阻加息,欧美货币政策齐收紧

美联储和欧洲央行官员在近两日发表讲话&#xff0c;先后释放进一步加息信号&#xff0c;美股、欧股事后均收跌&#xff0c;市场预计美元、欧元近期将下跌。 通胀仍高于目标&#xff0c;两大央行将进一步加息 除了非农报告等关键通胀数据&#xff0c;本周央行动态同样备受市场关…

软件测试 -- 进阶 5 软件测试用例

及之而后知&#xff0c;履之而后艰&#xff0c;乌有不行而能知者乎&#xff1f;。-- 魏源 释译&#xff1a;实际接触之后才知道真相&#xff0c;新自做了之后才知道困难&#xff0c;哪有不实践就能够知道的呢&#xff1f; 需求 -> 分析 -> 设计 -> 策略&#xff0…

大数据中Hadoop、Hive、Spark的关系

文章总括图 数据存储 单机数据库时代 所有数据在单机都能存的下&#xff0c;数据处理的任务都是IO密集型&#xff0c;更谈不上分布式系统 一个典型的2U服务器可以插6块硬盘&#xff0c;每块硬盘4T&#xff0c;共24T原始容量&#xff0c;再加上一些数据包的可用冗余&#xf…

A Self-Attentive model for Knowledge Tracing论文笔记和代码解析

原文链接和代码链接A Self-Attentive model for Knowledge Tracing | Papers With Code motivation&#xff1a;传统方法面临着处理稀疏数据时不能很好地泛化的问题。 本文提出了一种基于自注意力机制的知识追踪模型 Self Attentive Knowledge Tracing (SAKT)。其本质是用 Tra…