网卡驱动 之 数据链路层(TX)

引用

  • 链路层输出 - qdisc
  • 链路层的输出
  • 多队列网卡简介以及Linux通过网卡发送数据包源码解读
  • Linux多队列网卡
  • Linux TCP队列相关参数的总结
  • Queueing in the Linux Network Stack
  • Linux XPS实现
  • linux kernel 网络协议栈之xps特性详解
  • What is the mq qdisc in tc Traffic Control?
  • Linux 高级流控 - IBM
  • 网卡中断及多队列
  • Cgroup - Linux 的网络资源隔离
  • Linux 网络堆栈的排队机制
  • 理解fq_codel之概述
  • Linux内核--网络栈实现分析(一)--网络栈初始化
  • HOWTO for multiqueue network device support
  • Multiqueue networking
  • Multi-queue network interfaces with SMP on Linux
  • MQPRIO - Multiqueue Priority Qdisc (Offloaded Hardware QOS)
  • Monitoring and Tuning the Linux Networking Stack: Sending Data
  • Monitoring and Tuning the Linux Networking Stack: Receiving Data
  • Documentation: networking: cpsw: add MQPRIO & CBS offload examples
  • tc - show / manipulate traffic control settings
  • Linux Traffic Control

一. OverArch

网卡驱动 之 数据链路层(TX)_第1张图片

HARD_TX_LOCK(dev, txq, smp_processor_id()) -- txq->_xmit_lock;

会 lock dev_hard_start_xmit() flow,即表示NIC driver的 ndo_start_xmit()在实现上必须是原子的,不能有阻塞。

LLD

网卡驱动 之 数据链路层(TX)_第2张图片

  •  

二.qdisc

网卡驱动 之 数据链路层(TX)_第3张图片

  • Qdisc: how to queue the packets
  • Class: tied with qdiscs to form a hierarchy
  • Filter: how to classify or filter the packets
  • Action: how to deal with the matched packets

网卡驱动 之 数据链路层(TX)_第4张图片

2.1 按照single queue和multiple queue分类

single queue:表示NIC 只有一个tx queue,一般由硬件决定。

multiple queue: 表示NIC 由多个tx queue。

在alloc_etherdev_mq()等申请net device时,就决定了tx queue的数量。

当然,还可用 netif_set_real_num_tx_queues()来报告真实的queue。

 * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
 * greater than real_num_tx_queues stale skbs on the qdisc must be flushed.

内核目前Single queue qdisc, 包括:

1. Classless Queuing Disciplines (qdiscs)

  • choke, codel, [p|b]fifo, fq, fq_codel, fq_pie, gred, hhf, ingress, mqprio, multiq, netem, pfifo_fast, pie, red, rr, sfb, sfq, tbf

2. Classful Queuing Disciplines (qdiscs)

  • ATM, CBQ, DRR, DSMARK, ETS, HFSC, HTB, PRIO, QFQ

网卡驱动 之 数据链路层(TX)_第5张图片

内核目前multiple queue qdisc, 包括:

  • mq qdisc (/net/sched/sch_mq.c)
  • mqprio qdisc (/net/sched/sch_mqprio.c)
  • multiq qdisc (/net/sched/sch_multiq.c)

The mq qdisc is a dummy qdisc which sets up an array of pfifo_fast queues as a Traffic Control tc class under the root mq qdisc. One pfifo_fast queue is created for each hardware queue.

  •  

2. 2 init flow

  • subsys_initcall(pktsched_init);   - net/sched/sch_api.h

采用register_qdisc()接口来注册一些算法到全局链表qdisc_base中。

  • int register_netdevice(struct net_device *dev) - /net/core/dev.c

在各NIC driver注册时调用。里面会再调用 dev_init_scheduler(dev) 进行初始化为noop_qdisc

noop_qdisc算法什么也不做,enqueue函数为丢弃数据包。

  • int dev_open(struct net_device *dev, struct netlink_ext_ack *extack) - /net/core/dev.c

当用ifconfig xxx up网卡后,会调用dev_open(),最终分配默认的qdisc算法给tx queue。

single tx queue: pfifo_fast

multiple tx queue: mq

默认的qdisc 由 CONFIG_DEFAULT_NET_SCH指定 -- sch_default_qdisc()

可通过 cat /proc/sys/net/core/default_qdisc 查看或更改。

三. TC简介

tc可以使用以下命令对QDisc、类和过滤器进行操作:

add,在一个节点里加入一个QDisc、类或者过滤器。添加时,需要传递一个祖先作为参数,传递参数时既可以使用ID也可以直接传递设备的根。如果要建立一个QDisc或者过滤器,可以使用句柄(handle)来命名;如果要建立一个类,可以使用类识别符(classid)来命名。

remove,删除有某个句柄(handle)指定的QDisc,根QDisc(root)也可以删除。被删除QDisc上的所有子类以及附属于各个类的过滤器都会被自动删除。

change,以替代的方式修改某些条目。除了句柄(handle)和祖先不能修改以外,change命令的语法和add命令相同。换句话说,change命令不能一定节点的位置。

replace,对一个现有节点进行近于原子操作的删除/添加。如果节点不存在,这个命令就会建立节点。

link,只适用于DQisc,替代一个现有的节点。

tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]

tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]

tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id

tc [-s | -d ] qdisc show [ dev DEV ]

tc [-s | -d ] class show dev DEV tc filter show dev DEV

网卡驱动 之 数据链路层(TX)_第6张图片

即可看出目前ubuntu默认用的是 fq_codel qdisc。

 

 

你可能感兴趣的:(linux系统开发,协议)