深入理解Linux网络技术内幕学习笔记第九章:中断和网络驱动程序

设备与内核(可理解为内核中的驱动程序)交换数据的两种方式:

轮询:

中断:

当接收一个帧时,设备产生一个硬件中断通知内核,然后驱动程序将该帧拷贝到内核可以访问的输入队列,之后,内核将该帧传给相关协议(如IP)专用的处理函数。

中断处理函数分为上半部(top handler)和下半部(bottom handler),上半部时需要立即处理的一些事,而下半部不是特别紧迫。这么做是由于中断是非可抢占的,且在中断期间关闭了中断请求,但不是整个中断期间都是如此。因此,为了尽可能地提高性能,将中断处理过程分为上下两部分,上部分不可抢占,关闭中断,下半部分则不需要如此。

内核2.2的下半部函数:

下半部函数被划分为一大群类型:

enum{

    ...

    NET_BH;//网络相关

    ...

}

每种类型都通过init_bh而关联一个下半部处理函数。每当中断处理函数想触发下半部执行时,调用mark_bn标记一下。内核检查到这个标记后,就会执行函数do_bottom_half来执行下半部函数。

内核2.4之后的下半部函数引入了软IRQ,可以看作是多线程版的下半部函数。

新的软IRQ有6种类型:

enum{

    HI_SOFTIRQ;//用于实现高优先级的微任务

    HT_SOFTIRQ;//旧版本的下半部类型都以HT_SOFTIRQ重新实现

    NET_TX_SOFTIRQ;//网络代码使用

    NET_RX_SOFTIRQ;//网络代码使用

    SCSI_SOFTIRQ;

    TASKLET_SOFTIRQ;//用于实现低优先级的微任务

}

每种软IRQ都维护一个softnet_data结构数组,而每个cpu都有一个softnet_data数据来存储当前软IRQ的信息。调用open_softirq来注册软irq函数。为了执行软IRQ,需要_ _raise_softirq_irqoff函数来标记一下。

内核2.2的多数下半部函数都已经转化为软IRQ或微任务,微任务是函数,可以延迟中断或其他任务。微任务建立在软IRQ之上,通常由中断处理函数发出。

下面介绍一下softnet_data结构:

每个cpu都有队列,用于处理接收的帧。该队列的数据结构就是softnet_data。

struct softnet_data{

    int throttle;//bool值,表示cpu是否窒息,通常可以理解为队列是否已满

    int cng_level;//拥塞等级

    int avg_blog;//平均队列长度。以上三个参数有拥塞管理算法使用

    struct sk_buff_head    input_pkt_queue;//该队列用来保存进来的帧(被驱动处理前)

    struct list_head    poll_list;//双向链表

    struct net_device    *output_queue;//设备列表,其中的列表有数据要传输

    struct sk_buff    *completion_queue;//缓冲区列表,其中的数据已经传输,可以释放掉

    sruct net_device    backlog_dev;//表示该设备已在相关联的cpu上为net_rx_action调度以准备执行。

}

吐槽一下:本章关于中断里的下半部函数,软IRQ,微任务的诸多细节我都没有记录(偷懒了,反正我又不搞驱动开发)。要是完整记录感觉恨不得把整章都抄下来,还是太菜了,理解不够,不会提炼。总之,中断处理分为上个两个部分,上半部分是必须即使处理的(如将帧拷贝到sk_buff等),且处理过程中无法被中断,cpu无法被抢占,而下半部分则没有这些要求,为了进一步的改进下半部处理过程,又出现了软IRQ和微任务。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值