软中断和收包流程

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值