您的位置:首页 > 理论基础 > 计算机网络

《深入理解Linux网络技术内幕》阅读笔记(十一)

2015-10-02 22:36 543 查看
准备接收:



准备传输:



每个cpu都有一个output_queue队列,里面包含有数据要传输的设备。每个设备有自己的qdisc队列(若设备的队列规则存在时),里面包含该设备需要发送的sk_buff队列(若在dev_queue_xmit传输失败,则在软中断里面重新发送)。

dev->qdisc指向一个队列的实例,里面包含了队列本身以及操作队列的方法(enqueue、dequeue、requeue)。这些方法的集合组成了一种队列规则(skb将以某种规则入队、以某种规则出队,并不一定是简单的先进先出),这样的规则可用于流量控制。

有些设备没有队列,如回环设备:每当传输一个帧时,就会立刻被传递出去,但是因为没有队列可以让帧重新排入,如果有地方出错,帧就会被丢弃,没有第二次机会(TCP有重传机制,所以还是不会丢,但是UDP就丢了)。















下列情况之一,校验和必须在软件内计算:

1.硬件不支持校验和计算。

2.适配卡只能针对底层是IP的TCP/UDP封包使用硬件校验和计算,但是,正在传输的封包不使用IP,或者使用其他底层是IP的L4协议。



我们知道当来自设备驱动程序的程序在中断环境下运行时,就必须尽快执行。释放一个缓冲区会消耗时间,所以会受到拖延,因而可以要求net_tx_action软IRQ予以负责。设备驱动程序不使用dev_kfree_skb,而是使用dev_kfree_skb_irq。dev_kfree_skb收回sk_buff到缓冲区,但是dev_kfree_skb_irq只会把被释放的缓冲区的指针添加到与CPU相关联的softnet_data结构的completion_queue列表中,然后让net_tx_action稍后去做实际的工作。

603 /* Use this variant in places where it could be invoked
604  * either from interrupt or non-interrupt context.
605  */
606 static inline void dev_kfree_skb_any(struct sk_buff *skb)
607 {
608         if (in_irq())
609                 dev_kfree_skb_irq(skb);
610         else
611                 dev_kfree_skb(skb);
612 }


589 static inline void dev_kfree_skb_irq(struct sk_buff *skb)
590 {
591         if (atomic_dec_and_test(&skb->users)) {
592                 int cpu =smp_processor_id();
593                 unsigned long flags;
594
595                 local_irq_save(flags);
596                 skb->next = softnet_data[cpu].completion_queue;
597                 softnet_data[cpu].completion_queue = skb;
598                 cpu_raise_softirq(cpu, NET_TX_SOFTIRQ);
599                 local_irq_restore(flags);
600         }
601 }


看门狗定时器:

这是由每个设备定时器所启动的。此定时器会定时到期,以确保该设备一切没问题(设备的输出队列已关闭),然后自行重新启动。当侦测到问题,以及上次帧传输后已经过太多时间时,定时器的处理函数会启用设备驱动程序所注册的函数,以复位NIC。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: