From f294553e43bc69ebcc43bb63356e437607da8f4f Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Wed, 15 Apr 2020 06:31:54 +0200 Subject: [PATCH 1/7] Fix typo in Interrupts-1 s/..allows the interrupted program to be resume/ ..allows the interrupted program to resume/ --- Interrupts/linux-interrupts-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Interrupts/linux-interrupts-1.md b/Interrupts/linux-interrupts-1.md index eeab497..1df63e8 100644 --- a/Interrupts/linux-interrupts-1.md +++ b/Interrupts/linux-interrupts-1.md @@ -52,7 +52,7 @@ As mentioned earlier, an interrupt can occur at any time for a reason which the * `Traps` * `Aborts` -A `fault` is an exception reported before the execution of a "faulty" instruction (which can then be corrected). If correct, it allows the interrupted program to be resume. +A `fault` is an exception reported before the execution of a "faulty" instruction (which can then be corrected). If correct, it allows the interrupted program to resume. Next a `trap` is an exception which is reported immediately following the execution of the `trap` instruction. Traps also allow the interrupted program to be continued just as a `fault` does. From 781a2d12f1da49df58edcb8d68fbda8a50a7c628 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Wed, 15 Apr 2020 06:40:41 +0200 Subject: [PATCH 2/7] Missing commas Commas after the words: Finally, Also at the beginning of sentences and before a which within a sentence. --- Interrupts/linux-interrupts-1.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Interrupts/linux-interrupts-1.md b/Interrupts/linux-interrupts-1.md index 1df63e8..a370213 100644 --- a/Interrupts/linux-interrupts-1.md +++ b/Interrupts/linux-interrupts-1.md @@ -54,11 +54,11 @@ As mentioned earlier, an interrupt can occur at any time for a reason which the A `fault` is an exception reported before the execution of a "faulty" instruction (which can then be corrected). If correct, it allows the interrupted program to resume. -Next a `trap` is an exception which is reported immediately following the execution of the `trap` instruction. Traps also allow the interrupted program to be continued just as a `fault` does. +Next a `trap` is an exception, which is reported immediately following the execution of the `trap` instruction. Traps also allow the interrupted program to be continued just as a `fault` does. -Finally an `abort` is an exception that does not always report the exact instruction which caused the exception and does not allow the interrupted program to be resumed. +Finally, an `abort` is an exception that does not always report the exact instruction which caused the exception and does not allow the interrupted program to be resumed. -Also we already know from the previous [part](https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-3.html) that interrupts can be classified as `maskable` and `non-maskable`. Maskable interrupts are interrupts which can be blocked with the two following instructions for `x86_64` - `sti` and `cli`. We can find them in the Linux kernel source code: +Also, we already know from the previous [part](https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-3.html) that interrupts can be classified as `maskable` and `non-maskable`. Maskable interrupts are interrupts which can be blocked with the two following instructions for `x86_64` - `sti` and `cli`. We can find them in the Linux kernel source code: ```C static inline void native_irq_disable(void) @@ -466,7 +466,7 @@ When an interrupt or an exception occurs, the new `ss` selector is forced to `NU +---------------+ ``` -If the `IST` field in the interrupt gate is not `0`, we read the `IST` pointer into `rsp`. If the interrupt vector number has an error code associated with it, we then push the error code onto the stack. If the interrupt vector number has no error code, we go ahead and push the dummy error code on to the stack. We need to do this to ensure stack consistency. Next, we load the segment-selector field from the gate descriptor into the CS register and must verify that the target code-segment is a 64-bit mode code segment by the checking bit `21` i.e. the `L` bit in the `Global Descriptor Table`. Finally we load the offset field from the gate descriptor into `rip` which will be the entry-point of the interrupt handler. After this the interrupt handler begins to execute and when the interrupt handler finishes its execution, it must return control to the interrupted process with the `iret` instruction. The `iret` instruction unconditionally pops the stack pointer (`ss:rsp`) to restore the stack of the interrupted process and does not depend on the `cpl` change. +If the `IST` field in the interrupt gate is not `0`, we read the `IST` pointer into `rsp`. If the interrupt vector number has an error code associated with it, we then push the error code onto the stack. If the interrupt vector number has no error code, we go ahead and push the dummy error code on to the stack. We need to do this to ensure stack consistency. Next, we load the segment-selector field from the gate descriptor into the CS register and must verify that the target code-segment is a 64-bit mode code segment by the checking bit `21` i.e. the `L` bit in the `Global Descriptor Table`. Finally, we load the offset field from the gate descriptor into `rip` which will be the entry-point of the interrupt handler. After this the interrupt handler begins to execute and when the interrupt handler finishes its execution, it must return control to the interrupted process with the `iret` instruction. The `iret` instruction unconditionally pops the stack pointer (`ss:rsp`) to restore the stack of the interrupted process and does not depend on the `cpl` change. That's all. From a40a3d1be361782fe8c57a2c21d5712d4b6d38a3 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Wed, 15 Apr 2020 07:27:23 +0200 Subject: [PATCH 3/7] Fix typo at the description of IDT entries s/special mechanism in the x86_64, will see it later;/ special mechanism in the x86_64, which is described below;/ --- Interrupts/linux-interrupts-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Interrupts/linux-interrupts-1.md b/Interrupts/linux-interrupts-1.md index a370213..6bbdbb6 100644 --- a/Interrupts/linux-interrupts-1.md +++ b/Interrupts/linux-interrupts-1.md @@ -214,7 +214,7 @@ As we can see, `IDT` entry on the diagram consists of the following fields: * `0-15` bits - offset from the segment selector which is used by the processor as the base address of the entry point of the interrupt handler; * `16-31` bits - base address of the segment select which contains the entry point of the interrupt handler; -* `IST` - a new special mechanism in the `x86_64`, will see it later; +* `IST` - a new special mechanism in the `x86_64`, which is described below; * `DPL` - Descriptor Privilege Level; * `P` - Segment Present flag; * `48-63` bits - the second part of the handler base address; From 74a281cccc465a4c09375f426c120b0ce287e215 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Fri, 17 Apr 2020 07:05:09 +0200 Subject: [PATCH 4/7] SyncPrim/linux-sync-1 improve wording Improve wording of multiple sentences in the introduction. Correct grammar mistakes. No semantic changes. --- SyncPrim/linux-sync-1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SyncPrim/linux-sync-1.md b/SyncPrim/linux-sync-1.md index 9dfeb7d..e96790d 100644 --- a/SyncPrim/linux-sync-1.md +++ b/SyncPrim/linux-sync-1.md @@ -4,9 +4,9 @@ Synchronization primitives in the Linux kernel. Part 1. Introduction -------------------------------------------------------------------------------- -This part opens a new chapter in the [linux-insides](https://0xax.gitbooks.io/linux-insides/content/) book. Timers and time management related stuff was described in the previous [chapter](https://0xax.gitbooks.io/linux-insides/content/Timers/index.html). Now time to go next. As you may understand from the part's title, this chapter will describe [synchronization](https://en.wikipedia.org/wiki/Synchronization_%28computer_science%29) primitives in the Linux kernel. +This part opens a new chapter in the [linux-insides](https://0xax.gitbooks.io/linux-insides/content/) book. Timers and time management related stuff was described in the previous [chapter](https://0xax.gitbooks.io/linux-insides/content/Timers/index.html). Now it's time to move on to the next topic. As you probably recognized from the title, this chapter will describe the [synchronization](https://en.wikipedia.org/wiki/Synchronization_%28computer_science%29) primitives in the Linux kernel. -As always, before we will consider something synchronization related, we will try to know what `synchronization primitive` is in general. Actually, synchronization primitive is a software mechanism which provides the ability to two or more [parallel](https://en.wikipedia.org/wiki/Parallel_computing) processes or threads to not execute simultaneously on the same segment of a code. For example, let's look on the following piece of code: +As always, we will try to know what a `synchronization primitive` in general is before we deal with any synchronization-related issues. Actually, a synchronization primitive is a software mechanism, that ensures that two or more [parallel](https://en.wikipedia.org/wiki/Parallel_computing) processes or threads are not running simultaneously on the same code segment. For example, let's look at the following piece of code: ```C mutex_lock(&clocksource_mutex); From caa200e708a5d09d9969a11bc85711dbc02041c6 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Sat, 18 Apr 2020 06:21:18 +0200 Subject: [PATCH 5/7] Interrupts/linux-interrupts-2.md: Improve wording s/more about its implementation you can read/you can read more about its implementation/ s/For now we come to/For now, we have reached/ s/Of course you already can know that we will/You probably already know, that we will/ --- Interrupts/linux-interrupts-2.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Interrupts/linux-interrupts-2.md b/Interrupts/linux-interrupts-2.md index c2e994b..72bb4ba 100644 --- a/Interrupts/linux-interrupts-2.md +++ b/Interrupts/linux-interrupts-2.md @@ -1,4 +1,4 @@ -Interrupts and Interrupt Handling. Part 2. +Ineerrupts and Interrupt Handling. Part 2. ================================================================================ Start to dive into interrupt and exceptions handling in the Linux kernel @@ -9,7 +9,7 @@ We saw some theory about interrupts and exception handling in the previous [part If you've read the previous parts, you can remember that the earliest place in the Linux kernel `x86_64` architecture-specific source code which is related to the interrupt is located in the [arch/x86/boot/pm.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pm.c) source code file and represents the first setup of the [Interrupt Descriptor Table](http://en.wikipedia.org/wiki/Interrupt_descriptor_table). It occurs right before the transition into the [protected mode](http://en.wikipedia.org/wiki/Protected_mode) in the `go_to_protected_mode` function by the call of the `setup_idt`: ```C -void go_to_protected_mode(void) +vd more about its implementation in the part about Early interrupt and exception handling)/oid go_to_protected_mode(void) { ... setup_idt(); @@ -224,7 +224,7 @@ ENTRY(early_idt_handler_array) ENDPROC(early_idt_handler_common) ``` -It fills `early_idt_handler_array` with the `.rept NUM_EXCEPTION_VECTORS` and contains entry of the `early_make_pgtable` interrupt handler (more about its implementation you can read in the part about [Early interrupt and exception handling](https://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-2.html)). For now we come to the end of the `x86_64` architecture-specific code and the next part is the generic kernel code. Of course you already can know that we will return to the architecture-specific code in the `setup_arch` function and other places, but this is the end of the `x86_64` early code. +It fills `early_idt_handler_array` with the `.rept NUM_EXCEPTION_VECTORS` and contains entry of the `early_make_pgtable` interrupt handler (you can read more about its implementation in the part about [Early interrupt and exception handling](https://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-2.html)). For now, we have reached the end of the x86_64 architecture-specific code and the next part is the generic kernel code. You probably already know, that we will return to the architecture-specific code in the `setup_arch` function and other places, but this is the end of the `x86_64` early code. Setting stack canary for the interrupt stack ------------------------------------------------------------------------------- From 991f171c6d567aa61f3ef7613b82e237094038ac Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Sat, 18 Apr 2020 07:10:32 +0200 Subject: [PATCH 6/7] Initialization/linux-initialization-8.md: Fix grammatical errors & improve wording s/as if a single task/as if they were a single task/ s/The least unit which scheduler operates is an individual task or thread. But a process is not only one type of entities of which the scheduller may operate./ The smallest unit that the scheduler works with is an individual task or thread. However, a process is not the only type of entity that the scheduler can operate with./ s/these options provides support/these options provide support/ s/The first one option provides support for group scheduling with `completely fair scheduler` policies and the second with `real-time` policies respectively./ The first option provides support for group scheduling with the `completely fair scheduler` policies and the second with the `real-time` policies respectively./ s/It means that it supports/That means it supports/ --- Initialization/linux-initialization-8.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Initialization/linux-initialization-8.md b/Initialization/linux-initialization-8.md index 057491b..f3e989f 100644 --- a/Initialization/linux-initialization-8.md +++ b/Initialization/linux-initialization-8.md @@ -318,11 +318,11 @@ The `Completely Fair Scheduler` supports following `normal` or in other words `n The `SCHED_NORMAL` is used for the most normal applications, the amount of cpu each process consumes is mostly determined by the [nice](http://en.wikipedia.org/wiki/Nice_%28Unix%29) value, the `SCHED_BATCH` used for the 100% non-interactive tasks and the `SCHED_IDLE` runs tasks only when the processor has no task to run besides this task. -The `real-time` policies are also supported for the time-critical applications: `SCHED_FIFO` and `SCHED_RR`. If you've read something about the Linux kernel scheduler, you can know that it is modular. It means that it supports different algorithms to schedule different types of processes. Usually this modularity is called `scheduler classes`. These modules encapsulate scheduling policy details and are handled by the scheduler core without knowing too much about them. +The `real-time` policies are also supported for the time-critical applications: `SCHED_FIFO` and `SCHED_RR`. If you've read something about the Linux kernel scheduler, you can know that it is modular. That means it supports different algorithms to schedule different types of processes. Usually this modularity is called `scheduler classes`. These modules encapsulate scheduling policy details and are handled by the scheduler core without knowing too much about them. -Now let's get back to the our code and look on the two configuration options: `CONFIG_FAIR_GROUP_SCHED` and `CONFIG_RT_GROUP_SCHED`. The least unit which scheduler operates is an individual task or thread. But a process is not only one type of entities of which the scheduler may operate. Both of these options provides support for group scheduling. The first one option provides support for group scheduling with `completely fair scheduler` policies and the second with `real-time` policies respectively. +Now let's get back to the our code and look on the two configuration options: `CONFIG_FAIR_GROUP_SCHED` and `CONFIG_RT_GROUP_SCHED`. The smallest unit that the scheduler works with is an individual task or thread. However, a process is not the only type of entity that the scheduler can operate with. Both of these options provide support for group scheduling. The first option provides support for group scheduling with the `completely fair scheduler` policies and the second with the `real-time` policies respectively. -In simple words, group scheduling is a feature that allows us to schedule a set of tasks as if a single task. For example, if you create a group with two tasks on the group, then this group is just like one normal task, from the kernel perspective. After a group is scheduled, the scheduler will pick a task from this group and it will be scheduled inside the group. So, such mechanism allows us to build hierarchies and manage their resources. Although a minimal unit of scheduling is a process, the Linux kernel scheduler does not use `task_struct` structure under the hood. There is special `sched_entity` structure that is used by the Linux kernel scheduler as scheduling unit. +In simple words, group scheduling is a feature that allows us to schedule a set of tasks as if they were a single task. For example, if you create a group with two tasks on the group, then this group is just like one normal task, from the kernel perspective. After a group is scheduled, the scheduler will pick a task from this group and it will be scheduled inside the group. So, such mechanism allows us to build hierarchies and manage their resources. Although a minimal unit of scheduling is a process, the Linux kernel scheduler does not use `task_struct` structure under the hood. There is special `sched_entity` structure that is used by the Linux kernel scheduler as scheduling unit. So, the current goal is to calculate a space to allocate for a `sched_entity(ies)` of the root task group and we do it two times with: From 8976544271043cdf2d7939ca9210d53e194a6cd5 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Sat, 18 Apr 2020 11:51:40 +0200 Subject: [PATCH 7/7] remove accidental corruptions --- Interrupts/linux-interrupts-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Interrupts/linux-interrupts-2.md b/Interrupts/linux-interrupts-2.md index 72bb4ba..3c7d61d 100644 --- a/Interrupts/linux-interrupts-2.md +++ b/Interrupts/linux-interrupts-2.md @@ -1,4 +1,4 @@ -Ineerrupts and Interrupt Handling. Part 2. +Interrupts and Interrupt Handling. Part 2. ================================================================================ Start to dive into interrupt and exceptions handling in the Linux kernel @@ -9,7 +9,7 @@ We saw some theory about interrupts and exception handling in the previous [part If you've read the previous parts, you can remember that the earliest place in the Linux kernel `x86_64` architecture-specific source code which is related to the interrupt is located in the [arch/x86/boot/pm.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pm.c) source code file and represents the first setup of the [Interrupt Descriptor Table](http://en.wikipedia.org/wiki/Interrupt_descriptor_table). It occurs right before the transition into the [protected mode](http://en.wikipedia.org/wiki/Protected_mode) in the `go_to_protected_mode` function by the call of the `setup_idt`: ```C -vd more about its implementation in the part about Early interrupt and exception handling)/oid go_to_protected_mode(void) +void go_to_protected_mode(void) { ... setup_idt();