总结
<h2>触发发包、收包中断类型</h2>
<p>NET_TX_SOFTIRQ 对应的响应函数为 <code>net_tx_action</code>,主要工作有:
1、遍历 <code>sd-&gt;completion_queue</code> 并释放上面的 skb
2、遍历 <code>sd-&gt;output_queue</code> 并调用 qdisc 出包。具体调用链为:<code>qdisc_run(q)</code> -> <code>qdisc_restart(q)</code> -> <code>sch_direct_xmit</code> -> <code>dev_hard_start_xmit</code>
3、触发的地方如下:</p>
<pre><code class="language-c">// net/core/dev.c
__netif_reschedule // 触发软中断 NET_TX_SOFTIRQ
__netif_schedule // qdisc
too much ...
net_tx_action // 出包时,有条件调度 qdisc
net_dev_init
end
dev_kfree_skb_irq
too much ...
dev_cpu_callback
net_dev_init // 初始化的时候调用一次,可忽略
end
net_dev_init // 注册对应的中断处理函数,可忽略
end
</code></pre>
<p>NET_RX_SOFTIRQ 对应的响应函数为 <code>net_rx_action</code>,主要工作有:
1、遍历 <code>sd-&gt;poll_list</code> 上的 napi 对象,并调用其 poll 函数
2、触发的地方如下:</p>
<pre><code class="language-c">____napi_schedule // 将 napi 加入到 sd-&gt;poll_list 中,并触发软中断 NET_RX_SOFTIRQ
rps_trigger_softirq // 调用 ____napi_schedule(sd, &amp;sd-&gt;backlog);
net_dev_init // 调用 sd-&gt;csd.func = rps_trigger_softirq;
end
enqueue_to_backlog // 调用 ____napi_schedule(sd, &amp;sd-&gt;backlog);
netif_rx // 本机通信会用到?
too much ...
netif_receive_skb // 开启 rps 情况下有可能执行
too much ...
__napi_schedule // 调用 ____napi_schedule(&amp;__get_cpu_var(softnet_data), n);
too much ...
dev_cpu_callback
net_dev_init // 初始化的时候调用一次,可忽略
end
rps_ipi_queued // rps 相关
enqueue_to_backlog
... // 同上
net_rx_action
net_dev_init
end
net_dev_init // 注册对应的中断处理函数,可忽略
end
</code></pre>