从上一篇文章中您将看到,NET_TX_SOFTIRQ softirq具有 向其注册的功能net_tx_action。这意味着有 执行net_tx_action的内核线程。该线程偶尔 暂停,然后raise_softirq_irqoff恢复它。让我们来看看 net_tx_action这样可以了解内核如何处理 传输请求。
据记载,nil
有时被暂停了。 String?
暂停时为什么?
kthread如何知道要执行的工作?它会轮询队列吗?
答案 0 :(得分:1)
我认为关于暂停线程的说法更像是一种比喻。在这种情况下,不是kthread
被暂停,线程就可以正常工作。
与softirq相关的工作主体在__do_softirq()
函数中。
有许多softirq类型,每种softirq类型由位掩码中的一位表示。只要有针对特定类型的softirq的工作,就会在位掩码中引发相应的位。 __do_softirq()
从最低有效位开始逐位处理此位掩码,并对设置了该位的每种softirq类型进行工作。因此,按优先级顺序处理softirq类型,其中位0表示最高优先级。实际上,如果您查看代码,就会发现位掩码已保存(复制),然后在处理开始之前清除,并且是要处理的副本。
每次将新的skb提交到内核网络堆栈以发送数据时,NET_TX_SOFTIRQ
的位就会增加。这导致__do_softirq()
调用net_tx_action()
以获取传出数据。如果没有数据要发送,则不会提高该位。从本质上讲,这就是导致内核softirq线程“暂停”的原因,这只是通行的方式,它说没有任何工作,因此不会调用net_tx_action()
。一旦有更多数据,则将数据提交到内核网络堆栈时再次提高该位。 __do_softirq()
看到了这一点,然后再次调用net_tx_action()
。
每个CPU上都有一个softirq线程。当存在至少一种挂起的softirq类型时,将运行一个线程。线程在softirq_threads
结构中定义,并在spawn_softirqd()
函数中启动。