软中断和收包流程

来源:互联网 发布:淘宝助理5.7教程 编辑:程序博客网 时间:2024/06/05 22:45

 

open_softirq建立类型与handler的对应关系。

void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
{
    softirq_vec[nr].data = data;
    softirq_vec[nr].action = action;
}

netif_rx将收到的包放到softnet_data的input_pkt_queue中,之后调用netif_rx_schedule(&queue->backlog_dev)将设备加入poll_list队列。netif_rx_schedule中调用设置软中断对应标志位。

do_irq中断处理结束处,调用irq_exit(),其中判断当cpu没有处理中断,并且存在要执行的bh时(检查之前设置的标记),调用invoke_softirq。invoke_softirq就是do_softirq。do_softirq检查存在挂起的软中断,则调用__do_softirq。其中调用open_softirq中注册的action函数处理,在处理过程中可以有新的软中断被设置,这些软中断也会被处理,直到处理完或者超过规定的次数,如果超过了次数而还有未处理的软中断,则会启动ksoftirqd进程处理剩余的软中断。

接收数据的软中断处理函数为net_rx_action(),回调用poll_list队列中注册的poll函数,对于收包来说是process_backlog(在net_dev_init中注册)。

queue->backlog_dev.poll = process_backlog;

process_backlog从queue->input_pkt_queue中取出skb并调用netif_receive_skb(skb)。

存在两个链表
static struct list_head ptype_base[16]; /* 16 way hashed list */
static struct list_head ptype_all;  /* Taps */

协议调用dev_add_pack时会将packet_type加入相应队列。在netif_receive_skb中会遍历这两个队列,调用deliver_skb。deliver_skb()调用packet_type中指定的函数通知相应协议处理skb。对于ip4,这个函数就是ip_rcv。

 

对于NAPI,不使用softnet_data中的input_pkt_queue,而是使用设备维护的私有队列。netrx_if也是针对非NAPI。NAPI方式中poll_list是设备链表,poll函数由各设备提供。对于非NAPI,poll_list中只有一个设备,就是softnet_data中的backlog_dev,也被称为伪设备,它的poll函数是process_backlog。l

原创粉丝点击