引用
HARD_TX_LOCK(dev, txq, smp_processor_id()) -- txq->_xmit_lock;
会 lock dev_hard_start_xmit() flow,即表示NIC driver的 ndo_start_xmit()在实现上必须是原子的,不能有阻塞。
LLD
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)
2. Classful Queuing Disciplines (qdiscs)
内核目前multiple queue qdisc, 包括:
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.
采用register_qdisc()接口来注册一些算法到全局链表qdisc_base中。
在各NIC driver注册时调用。里面会再调用 dev_init_scheduler(dev) 进行初始化为noop_qdisc。
noop_qdisc算法什么也不做,enqueue函数为丢弃数据包。
当用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可以使用以下命令对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
即可看出目前ubuntu默认用的是 fq_codel qdisc。