在数据包发送一节提到了流控TC的实现,现在进一步研究。
数据包发送是通过dev_queue_xmit实现的,
if (q->enqueue) {
rc = __dev_xmit_skb(skb, q, dev, txq);
goto out;
}
如果有enqueue则说明进行流控,否则直接发送。
参考函数__dev_xmit_skb,我们可以看到对skb进行了enqueue操作,并__qdisc_run开始触发软中断。
struct Qdisc_ops定义了QoS相关的操作,最主要的是enqueue和dequeue。
当一个网卡注册时,调用int register_netdevice(struct net_device *dev),负责初始化网卡TC的是
void dev_init_scheduler(struct net_device*dev)
{
dev->qdisc= &noop_qdisc;
netdev_for_each_tx_queue(dev,dev_init_scheduler_queue, &noop_qdisc);
if(dev_ingress_queue(dev))
dev_init_scheduler_queue(dev,dev_ingress_queue(dev), &noop_qdisc);
setup_timer(&dev->watchdog_timer,dev_watchdog, (unsigned long)dev);
}
dev的qdisc被