linux-kernelsoftirq

Pausing a kthread in Linux


here https://blog.packagecloud.io/eng/2017/02/06/monitoring-tuning-linux-networking-stack-sending-data/#queuing-disciplines it is written:

As you’ll see from the previous post, the NET_TX_SOFTIRQ softirq has the function net_tx_action registered to it. This means that there is a kernel thread executing net_tx_action. That thread is occasionally paused and raise_softirq_irqoff resumes it. Let’s take a look at what net_tx_action does so we can understand how the kernel processes transmit requests.

It is written that kthread is occasionally paused. When a kthread is paused and why?

How kthread knows about work to execute? Does it poll a queue?


Solution

  • I think what's said about pausing a thread there is more like a figure of speech. In this case it's not kthread that is paused, the thread works just fine.

    The body of work related to softirq is in __do_softirq() function.

    There's a number of softirq types, and each softirq type is represented by a bit in a bitmask. Whenever there's work for a specific type of softirq, the corresponding bit is raised in the bitmask. __do_softirq() processes this bitmask bit by bit starting with the least significant bit, and does the work for each softirq type that has the bit set. Thus softirq types are processed in the order of priority, with the bit 0 representing the highest priority. In fact, if you look at the code you'll see that the bitmask is saved (copied) and then cleared before the processing starts, and it's the copy that is processed.

    The bit for NET_TX_SOFTIRQ is raised each time a new skb is submitted to the kernel networking stack to send data out. That causes __do_softirq() to call net_tx_action() for outgoing data. If there's no data to send out, then the bit is not raised. Essentially, that's what causes the kernel softirq thread to "pause" which is just a layman way to say that there's no work for it, so net_tx_action() is not called. As soon as there's more data, the bit is raised again as data is submitted to the kernel networking stack. __do_softirq() sees that and calls net_tx_action() again.

    There's a softirq thread on each CPU. A thread is run when there's at least one pending softirq type. The threads are defined in softirq_threads structure and started in spawn_softirqd() function.