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

来源:互联网 发布:lsd可以在淘宝上买到 编辑:程序博客网 时间:2024/05/21 23:58

准备接收:
这里写图片描述
准备传输:
这里写图片描述
每个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 invoked604  * 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         else611                 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。

0 0