mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-26 19:51:35 +01:00
move schedule() doc to README
This commit is contained in:
35
README.adoc
35
README.adoc
@@ -4032,6 +4032,41 @@ Possible very likely outcome:
|
|||||||
|
|
||||||
The threads almost always interleaved nicely, thus confirming that they are actually running in parallel.
|
The threads almost always interleaved nicely, thus confirming that they are actually running in parallel.
|
||||||
|
|
||||||
|
===== schedule
|
||||||
|
|
||||||
|
Let's block the entire kernel! Yay:
|
||||||
|
|
||||||
|
.....
|
||||||
|
./run -F 'dmesg -n 1;insmod /schedule.ko schedule=0'
|
||||||
|
.....
|
||||||
|
|
||||||
|
Outcome: the system hangs, the only way out is to kill the VM.
|
||||||
|
|
||||||
|
Source: link:kernel_module/schedule.c[]
|
||||||
|
|
||||||
|
kthreads only allow interrupting if you call `schedule()`, and the `schedule=0` <<kernel-module-parameters,kernel module parameter>> turns it off.
|
||||||
|
|
||||||
|
Sleep functions like `usleep_range` also end up calling schedule.
|
||||||
|
|
||||||
|
If we allow `schedule()` to be called, then the system becomes responsive:
|
||||||
|
|
||||||
|
.....
|
||||||
|
./run -F 'dmesg -n 1;insmod /schedule.ko schedule=1'
|
||||||
|
.....
|
||||||
|
|
||||||
|
|
||||||
|
and we can observe the counting with:
|
||||||
|
|
||||||
|
....
|
||||||
|
dmesg -w
|
||||||
|
....
|
||||||
|
|
||||||
|
The system also responds if we <<number-of-cores,add another core>>:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run -c 2 -F 'dmesg -n 1;insmod /schedule.ko schedule=0'
|
||||||
|
....
|
||||||
|
|
||||||
=== IRQ
|
=== IRQ
|
||||||
|
|
||||||
==== irq.ko
|
==== irq.ko
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
https://github.com/cirosantilli/linux-kernel-module-cheat#directory-structure
|
https://github.com/cirosantilli/linux-kernel-module-cheat#directory-structure
|
||||||
|
|
||||||
. Asynchronous
|
. Asynchronous
|
||||||
.. link:irq.c[]
|
|
||||||
.. link:schedule.c[]
|
|
||||||
.. link:sleep.c[]
|
.. link:sleep.c[]
|
||||||
.. link:timer.c[]
|
.. link:timer.c[]
|
||||||
.. link:work_from_work.c[]
|
.. link:work_from_work.c[]
|
||||||
|
|||||||
@@ -1,34 +1,12 @@
|
|||||||
/*
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#schedule */
|
||||||
Let's block the entire kernel! Yay!
|
|
||||||
|
|
||||||
kthreads only allow interrupting if you call schedule.
|
|
||||||
|
|
||||||
If you don't, they just run forever, and you have to kill the VM.
|
|
||||||
|
|
||||||
Sleep functions like usleep_range also end up calling schedule.
|
|
||||||
|
|
||||||
Test with:
|
|
||||||
|
|
||||||
dmesg -n 1
|
|
||||||
insmod /schedule.ko yn=[01]
|
|
||||||
dmesg | tail
|
|
||||||
|
|
||||||
Then:
|
|
||||||
|
|
||||||
- yn=0:
|
|
||||||
- `qemu -smp 1`: everything blocks!
|
|
||||||
- `qemu -smp 2`: you can still use the board, but is it noticeably slow
|
|
||||||
- yn=1: all good
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <uapi/linux/stat.h> /* S_IRUSR | S_IWUSR */
|
#include <uapi/linux/stat.h> /* S_IRUSR | S_IWUSR */
|
||||||
|
|
||||||
static int yn = 1;
|
static int do_schedule = 1;
|
||||||
module_param(yn, int, S_IRUSR | S_IWUSR);
|
module_param_named(schedule, do_schedule, int, S_IRUSR | S_IWUSR);
|
||||||
MODULE_PARM_DESC(yn, "A short integer");
|
|
||||||
|
|
||||||
static struct task_struct *kthread;
|
static struct task_struct *kthread;
|
||||||
|
|
||||||
@@ -38,7 +16,7 @@ static int work_func(void *data)
|
|||||||
while (!kthread_should_stop()) {
|
while (!kthread_should_stop()) {
|
||||||
pr_info("%u\n", i);
|
pr_info("%u\n", i);
|
||||||
i++;
|
i++;
|
||||||
if (yn)
|
if (do_schedule)
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user