mirror of
https://github.com/0xAX/linux-insides.git
synced 2024-11-15 20:48:57 +00:00
Merge pull request #395 from zhangyangjing/master
Update interrupts-9.md
This commit is contained in:
commit
8709507ce5
@ -4,18 +4,7 @@ Interrupts and Interrupt Handling. Part 9.
|
||||
Introduction to deferred interrupts (Softirq, Tasklets and Workqueues)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
It is the ninth part of the [linux-insides](https://www.gitbook.com/book/0xax/linux-insides/details) book and in the previous [Previous part](http://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-8.html) we saw implementation of the `init_IRQ` from that defined in the [arch/x86/kernel/irqinit.c](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/irqinit.c) source code file. So, we will continue to dive into the initialization stuff which is related to the external hardware interrupts in this part.
|
||||
|
||||
After the `init_IRQ` function we can see the call of the `softirq_init` function in the [init/main.c](https://github.com/torvalds/linux/blob/master/init/main.c). This function defined in the [kernel/softirq.c](https://github.com/torvalds/linux/blob/master/kernel/softirq.c) source code file and as we can understand from its name, this function makes initialization of the `softirq` or in other words initialization of the `deferred interrupts`. What is it deferreed intrrupt? We already saw a little bit about it in the ninth [part](http://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-9.html) of the chapter that describes initialization process of the Linux kernel. There are three types of `deferred interrupts` in the Linux kernel:
|
||||
|
||||
* `softirqs`;
|
||||
* `tasklets`;
|
||||
* `workqueues`;
|
||||
|
||||
And we will see description of all of these types in this part. As I said, we saw only a little bit about this theme, so, now is time to dive deep into details about this theme.
|
||||
|
||||
Deferred interrupts
|
||||
----------------------------------------------------------------------------------
|
||||
It is the nine part of the Interrupts and Interrupt Handling in the Linux kernel [chapter](http://0xax.gitbooks.io/linux-insides/content/interrupts/index.html) and in the previous [Previous part](http://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-8.html) we saw implementation of the `init_IRQ` from that defined in the [arch/x86/kernel/irqinit.c](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/irqinit.c) source code file. So, we will continue to dive into the initialization stuff which is related to the external hardware interrupts in this part.
|
||||
|
||||
Interrupts may have different important characteristics and there are two among them:
|
||||
|
||||
@ -27,9 +16,20 @@ As you can understand, it is almost impossible to make so that both characterist
|
||||
* Top half;
|
||||
* Bottom half;
|
||||
|
||||
Once the Linux kernel was one of the ways the organization postprocessing, and which was called: `the bottom half` of the processor, but now it is already not actual. Now this term has remained as a common noun referring to all the different ways of organizing deferred processing of an interrupt. With the advent of parallelisms in the Linux kernel, all new schemes of implementation of the bottom half handlers are built on the performance of the processor specific kernel thread that called `ksoftirqd` (will be discussed below). The `softirq` mechanism represents handling of interrupts that are `almost` as important as the handling of the hardware interrupts. The deferred processing of an interrupt suggests that some of the actions for an interrupt may be postponed to a later execution when the system will be less loaded. As you can suggests, an interrupt handler can do large amount of work that is impermissible as it executes in the context where interrupts are disabled. That's why processing of an interrupt can be splitted on two different parts. In the first part, the main handler of an interrupt does only minimal and the most important job. After this it schedules the second part and finishes its work. When the system is less busy and context of the processor allows to handle interrupts, the second part starts its work and finishes to process remaing part of a deferred interrupt. That is main explanation of the deferred interrupt handling.
|
||||
Once the Linux kernel was one of the ways the organization postprocessing, and which was called: `the bottom half` of the processor, but now it is already not actual. Now this term has remained as a common noun referring to all the different ways of organizing deferred processing of an interrupt.The deferred processing of an interrupt suggests that some of the actions for an interrupt may be postponed to a later execution when the system will be less loaded. As you can suggests, an interrupt handler can do large amount of work that is impermissible as it executes in the context where interrupts are disabled. That's why processing of an interrupt can be splitted on two different parts. In the first part, the main handler of an interrupt does only minimal and the most important job. After this it schedules the second part and finishes its work. When the system is less busy and context of the processor allows to handle interrupts, the second part starts its work and finishes to process remaing part of a deferred interrupt.
|
||||
|
||||
As I already wrote above, handling of deferred interrupts (or `softirq` in other words) and accordingly `tasklets` is performed by a set of the special kernel threads (one thread per processor). Each processor has its own thread that is called `ksoftirqd/n` where the `n` is the number of the processor. We can see it in the output of the `systemd-cgls` util:
|
||||
There are three types of `deferred interrupts` in the Linux kernel:
|
||||
|
||||
* `softirqs`;
|
||||
* `tasklets`;
|
||||
* `workqueues`;
|
||||
|
||||
And we will see description of all of these types in this part. As I said, we saw only a little bit about this theme, so, now is time to dive deep into details about this theme.
|
||||
|
||||
Softirqs
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
With the advent of parallelisms in the Linux kernel, all new schemes of implementation of the bottom half handlers are built on the performance of the processor specific kernel thread that called `ksoftirqd` (will be discussed below). Each processor has its own thread that is called `ksoftirqd/n` where the `n` is the number of the processor. We can see it in the output of the `systemd-cgls` util:
|
||||
|
||||
```
|
||||
$ systemd-cgls -k | grep ksoft
|
||||
@ -49,7 +49,7 @@ The `spawn_ksoftirqd` function starts this these threads. As we can see this fun
|
||||
early_initcall(spawn_ksoftirqd);
|
||||
```
|
||||
|
||||
Deferred interrupts are determined statically at compile-time of the Linux kernel and the `open_softirq` function takes care of `softirq` initialization. The `open_softirq` function defined in the [kernel/softirq.c](https://github.com/torvalds/linux/blob/master/kernel/softirq.c):
|
||||
Softirqs are determined statically at compile-time of the Linux kernel and the `open_softirq` function takes care of `softirq` initialization. The `open_softirq` function defined in the [kernel/softirq.c](https://github.com/torvalds/linux/blob/master/kernel/softirq.c):
|
||||
|
||||
|
||||
```C
|
||||
@ -61,7 +61,7 @@ void open_softirq(int nr, void (*action)(struct softirq_action *))
|
||||
|
||||
and as we can see this function uses two parameters:
|
||||
|
||||
* the index of the `softirq_vec` array;
|
||||
* the index of the `softirq_vec` array;
|
||||
* a pointer to the softirq function to be executed;
|
||||
|
||||
First of all let's look on the `softirq_vec` array:
|
||||
|
Loading…
Reference in New Issue
Block a user