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

来源:互联网 发布:mysql for mac 编辑:程序博客网 时间:2024/05/01 11:56

这里写图片描述
这里写图片描述
这里写图片描述
当特定事件发生时,设备驱动程序会代表内核指示设备产生硬件中断。处理函数会把该帧排入队列某处,然后通知内核。该技术是低流量负载下的最佳选择。遗憾的是,在高流量负载下就无法良好运作:每接收一个帧就强制产生中断,很快就会让cpu为处理中断事件浪费所有的时间。
负责接收帧的代码分成两部分,首先,驱动程序把该帧拷贝到内核可访问的输入队列,然后,内核再予以处理。在高流量负载下,中断代码会持续抢占正在处理的代码。到某一时间点,输入队列会满,而新的帧无法入队(由于没有空间),而旧的帧又无法被处理(由于一直被抢占)。结果系统就奔溃了。
驱动程序可以只关闭某个设备的中断事件,该设备的输入队列中有一些帧,然后把轮询驱动程序的队列的任务交给一个内核处理函数,不再是把所有中断事件都关闭,之后令驱动程序为内核把帧排入队列以便于处理。(NAPI)
定时器驱动的中断事件:
驱动程序指示设备设备定期产生一个中断事件,不再是让设备以异步方式通知驱动程序有关帧的接收。然后,处理函数会检查自从上次中断事件以来是否有任何帧到达,然后一次处理所有帧。最好是驱动程序有话要说时才定期产生中断事件。
preempt_count被分成三个组件,每个字节都是一个计数器,各自针对一种需要非抢占功能的情况:硬件中断,软件中断,以及一般非抢占情况。如下图:
这里写图片描述
当调用schedule函数并通知该函数它已经被调用而抢占了当前任务之前,上图中的preempt_count最高字节的第二最低位会被设置。
cpu_is_offline:支持可热拔插cpu的时候 判断cpu是否已经被拔出了。(内核保存一个 cpu_online_mask,用于指出当前哪些cpu是活动的。)

98 #define cpu_online(cpu)         cpumask_test_cpu((cpu), cpu_online_mask)763 #define cpu_is_offline(cpu)     unlikely(!cpu_online(cpu))

每个cpu都有一个ksoftirqd线程。cpu_chain链让各子系统知道一个cpu何时起来运行或者何时死掉。
CPU_UP_PREPARE:当cpu运行起来但还没有就绪时,就会产生。
CPU_ONLINE:当cpu就绪时,就会产生。
CPU_UP_CANCELLED:
CPU_DEAD:只有当内核编译为支持可热拔插cpu时,这两条信息才会产生。当先前的CPU_UP_PREPARE通知信息所触发的任务之一失败时,就会使用CPU_UP_CANCELLED通知消息。因此,cpu就无法上线了。当cpu死掉时,就会用到CPU_DEAD。
CPU_UP_PREPARE会建立线程,并将此与关联的cpu绑定,但是没有唤醒该线程。CPU_ONLINE唤醒该线程。当CPU死掉时,其相关联的ksoftirqd实例也会被杀掉。
这里写图片描述

0 0
原创粉丝点击