Why is cpu_idle called as the last function of the start_kernel routine?
up vote
3
down vote
favorite
I'm reading the start_kernel
function in /init/main.c
.
The last function called in start_kernel
is rest_init
, and at the end of rest_init
, cpu_idle
is called.
Why is it called as the last function of the start_kernel
routine, and what does it do?
kernel linux-kernel cpu c
add a comment |
up vote
3
down vote
favorite
I'm reading the start_kernel
function in /init/main.c
.
The last function called in start_kernel
is rest_init
, and at the end of rest_init
, cpu_idle
is called.
Why is it called as the last function of the start_kernel
routine, and what does it do?
kernel linux-kernel cpu c
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I'm reading the start_kernel
function in /init/main.c
.
The last function called in start_kernel
is rest_init
, and at the end of rest_init
, cpu_idle
is called.
Why is it called as the last function of the start_kernel
routine, and what does it do?
kernel linux-kernel cpu c
I'm reading the start_kernel
function in /init/main.c
.
The last function called in start_kernel
is rest_init
, and at the end of rest_init
, cpu_idle
is called.
Why is it called as the last function of the start_kernel
routine, and what does it do?
kernel linux-kernel cpu c
kernel linux-kernel cpu c
edited Feb 24 at 2:08
aliceinpalth
800116
800116
asked Feb 23 at 22:04
Anthony
161
161
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
5
down vote
To answer your first question,
What does
cpu_idle
do?
In general (without regards to the context of the question), when the CPU is in an idle state, it means that the kernel currently has no work for the CPU to perform, and thus the CPU is idly awaiting more work from the kernel.
You can think of how the kernel works as a manager, giving work to the CPU (according to a schedule). When no work is available for the CPU to take on, the CPU will be put into an idle state and await an interupt. You can read more about CPU interupts here.
With regards to the context of your question, you can read the exact implementation of what cpu_idle
does:
cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
cpu_relax();
schedule();
}
}
In summary, cpu_idle
puts the CPU into a state where it is idle. This is achieved through using while
loops to handle scheduling of processes when needed; else, the CPU is made idle with cpu_relax
.
Why is it called as the last function of the
start_kernel
routine?
The reason this function is executed as the last instruction in the start_kernel
routine is because the CPU has executed all necessary work to start the kernel - no further instructions will be executed, thus the CPU will become idle, awaiting the next task or interupt. To indicate this, the CPU should be put into an idle state, as it is no longer required for initialization of the kernel.
add a comment |
up vote
2
down vote
A central processing unit always has to be executing something. If there's nothing to do, it simply loops in an infinite loop, which an interrupt (such as the system heartbeat interrupt) will break it out of.
In older multi-process/multi-threaded operating systems, if the dispatcher (the low-level scheduler that picks and switches to the next thread to run off the runnable threads queue) finds no thread ready to run it would simply enter such an infinite loop.
This is a problem for multi-processor operating systems, though, as the infinite loop is executed in the context of whatever thread the dispatcher was leaving. This could end up with the same thread "running" on two processors at once, which causes a range of problems.
So a more recent (comparatively more recent, that is; as this idea is some several decades old) design was to have, for each processor in the system, an idle thread. This thread does nothing but loop indefinitely, and is always runnable. So there is always a thread that the dispatcher can pick, and there's never a situation where there is no runnable thread for a processor to run.
In old versions of actual Unix, when system initialization has finished, the initialization code has set up data structures describing it as process #0. This has the traditional name of the "swapper process", because of what it did. It had to do something after initialization had finished, so what it did was run the code that swapped process segments between main RAM and the DASD swap area.
The idea of swapping went away in the late 1970s with the advent of demand paging designs; and process #0 became first the idle process and then the system process that contained all of the idle threads.
And that is what is also happening in Linux.
Of course, power management has been a consideration for over a quarter of a century at this point, and the traditional infinite loop of an unconditional branch instruction branching to itself causes a lot of unnecessary busywork and power drain. Modern (again a relative term) idle threads invoke special processor instructions that instruct the executing processor to wait, potentially lowering its clock rate to save power, for it to receive a hardware interrupt. (Over the years on x86 instruction architectures this has changed from hlt
to pause
, a.k.a. rep nop
, trading the complete release of resources by an execution core within a "hyperthreaded" processor for cross-processor shoulder taps that do not involve interrupts, effectively turning idle threads into perpetual waiters for a spin lock.)
Further reading
- https://superuser.com/a/377675/38062
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
To answer your first question,
What does
cpu_idle
do?
In general (without regards to the context of the question), when the CPU is in an idle state, it means that the kernel currently has no work for the CPU to perform, and thus the CPU is idly awaiting more work from the kernel.
You can think of how the kernel works as a manager, giving work to the CPU (according to a schedule). When no work is available for the CPU to take on, the CPU will be put into an idle state and await an interupt. You can read more about CPU interupts here.
With regards to the context of your question, you can read the exact implementation of what cpu_idle
does:
cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
cpu_relax();
schedule();
}
}
In summary, cpu_idle
puts the CPU into a state where it is idle. This is achieved through using while
loops to handle scheduling of processes when needed; else, the CPU is made idle with cpu_relax
.
Why is it called as the last function of the
start_kernel
routine?
The reason this function is executed as the last instruction in the start_kernel
routine is because the CPU has executed all necessary work to start the kernel - no further instructions will be executed, thus the CPU will become idle, awaiting the next task or interupt. To indicate this, the CPU should be put into an idle state, as it is no longer required for initialization of the kernel.
add a comment |
up vote
5
down vote
To answer your first question,
What does
cpu_idle
do?
In general (without regards to the context of the question), when the CPU is in an idle state, it means that the kernel currently has no work for the CPU to perform, and thus the CPU is idly awaiting more work from the kernel.
You can think of how the kernel works as a manager, giving work to the CPU (according to a schedule). When no work is available for the CPU to take on, the CPU will be put into an idle state and await an interupt. You can read more about CPU interupts here.
With regards to the context of your question, you can read the exact implementation of what cpu_idle
does:
cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
cpu_relax();
schedule();
}
}
In summary, cpu_idle
puts the CPU into a state where it is idle. This is achieved through using while
loops to handle scheduling of processes when needed; else, the CPU is made idle with cpu_relax
.
Why is it called as the last function of the
start_kernel
routine?
The reason this function is executed as the last instruction in the start_kernel
routine is because the CPU has executed all necessary work to start the kernel - no further instructions will be executed, thus the CPU will become idle, awaiting the next task or interupt. To indicate this, the CPU should be put into an idle state, as it is no longer required for initialization of the kernel.
add a comment |
up vote
5
down vote
up vote
5
down vote
To answer your first question,
What does
cpu_idle
do?
In general (without regards to the context of the question), when the CPU is in an idle state, it means that the kernel currently has no work for the CPU to perform, and thus the CPU is idly awaiting more work from the kernel.
You can think of how the kernel works as a manager, giving work to the CPU (according to a schedule). When no work is available for the CPU to take on, the CPU will be put into an idle state and await an interupt. You can read more about CPU interupts here.
With regards to the context of your question, you can read the exact implementation of what cpu_idle
does:
cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
cpu_relax();
schedule();
}
}
In summary, cpu_idle
puts the CPU into a state where it is idle. This is achieved through using while
loops to handle scheduling of processes when needed; else, the CPU is made idle with cpu_relax
.
Why is it called as the last function of the
start_kernel
routine?
The reason this function is executed as the last instruction in the start_kernel
routine is because the CPU has executed all necessary work to start the kernel - no further instructions will be executed, thus the CPU will become idle, awaiting the next task or interupt. To indicate this, the CPU should be put into an idle state, as it is no longer required for initialization of the kernel.
To answer your first question,
What does
cpu_idle
do?
In general (without regards to the context of the question), when the CPU is in an idle state, it means that the kernel currently has no work for the CPU to perform, and thus the CPU is idly awaiting more work from the kernel.
You can think of how the kernel works as a manager, giving work to the CPU (according to a schedule). When no work is available for the CPU to take on, the CPU will be put into an idle state and await an interupt. You can read more about CPU interupts here.
With regards to the context of your question, you can read the exact implementation of what cpu_idle
does:
cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
cpu_relax();
schedule();
}
}
In summary, cpu_idle
puts the CPU into a state where it is idle. This is achieved through using while
loops to handle scheduling of processes when needed; else, the CPU is made idle with cpu_relax
.
Why is it called as the last function of the
start_kernel
routine?
The reason this function is executed as the last instruction in the start_kernel
routine is because the CPU has executed all necessary work to start the kernel - no further instructions will be executed, thus the CPU will become idle, awaiting the next task or interupt. To indicate this, the CPU should be put into an idle state, as it is no longer required for initialization of the kernel.
edited Feb 24 at 1:13
answered Feb 23 at 22:50
aliceinpalth
800116
800116
add a comment |
add a comment |
up vote
2
down vote
A central processing unit always has to be executing something. If there's nothing to do, it simply loops in an infinite loop, which an interrupt (such as the system heartbeat interrupt) will break it out of.
In older multi-process/multi-threaded operating systems, if the dispatcher (the low-level scheduler that picks and switches to the next thread to run off the runnable threads queue) finds no thread ready to run it would simply enter such an infinite loop.
This is a problem for multi-processor operating systems, though, as the infinite loop is executed in the context of whatever thread the dispatcher was leaving. This could end up with the same thread "running" on two processors at once, which causes a range of problems.
So a more recent (comparatively more recent, that is; as this idea is some several decades old) design was to have, for each processor in the system, an idle thread. This thread does nothing but loop indefinitely, and is always runnable. So there is always a thread that the dispatcher can pick, and there's never a situation where there is no runnable thread for a processor to run.
In old versions of actual Unix, when system initialization has finished, the initialization code has set up data structures describing it as process #0. This has the traditional name of the "swapper process", because of what it did. It had to do something after initialization had finished, so what it did was run the code that swapped process segments between main RAM and the DASD swap area.
The idea of swapping went away in the late 1970s with the advent of demand paging designs; and process #0 became first the idle process and then the system process that contained all of the idle threads.
And that is what is also happening in Linux.
Of course, power management has been a consideration for over a quarter of a century at this point, and the traditional infinite loop of an unconditional branch instruction branching to itself causes a lot of unnecessary busywork and power drain. Modern (again a relative term) idle threads invoke special processor instructions that instruct the executing processor to wait, potentially lowering its clock rate to save power, for it to receive a hardware interrupt. (Over the years on x86 instruction architectures this has changed from hlt
to pause
, a.k.a. rep nop
, trading the complete release of resources by an execution core within a "hyperthreaded" processor for cross-processor shoulder taps that do not involve interrupts, effectively turning idle threads into perpetual waiters for a spin lock.)
Further reading
- https://superuser.com/a/377675/38062
add a comment |
up vote
2
down vote
A central processing unit always has to be executing something. If there's nothing to do, it simply loops in an infinite loop, which an interrupt (such as the system heartbeat interrupt) will break it out of.
In older multi-process/multi-threaded operating systems, if the dispatcher (the low-level scheduler that picks and switches to the next thread to run off the runnable threads queue) finds no thread ready to run it would simply enter such an infinite loop.
This is a problem for multi-processor operating systems, though, as the infinite loop is executed in the context of whatever thread the dispatcher was leaving. This could end up with the same thread "running" on two processors at once, which causes a range of problems.
So a more recent (comparatively more recent, that is; as this idea is some several decades old) design was to have, for each processor in the system, an idle thread. This thread does nothing but loop indefinitely, and is always runnable. So there is always a thread that the dispatcher can pick, and there's never a situation where there is no runnable thread for a processor to run.
In old versions of actual Unix, when system initialization has finished, the initialization code has set up data structures describing it as process #0. This has the traditional name of the "swapper process", because of what it did. It had to do something after initialization had finished, so what it did was run the code that swapped process segments between main RAM and the DASD swap area.
The idea of swapping went away in the late 1970s with the advent of demand paging designs; and process #0 became first the idle process and then the system process that contained all of the idle threads.
And that is what is also happening in Linux.
Of course, power management has been a consideration for over a quarter of a century at this point, and the traditional infinite loop of an unconditional branch instruction branching to itself causes a lot of unnecessary busywork and power drain. Modern (again a relative term) idle threads invoke special processor instructions that instruct the executing processor to wait, potentially lowering its clock rate to save power, for it to receive a hardware interrupt. (Over the years on x86 instruction architectures this has changed from hlt
to pause
, a.k.a. rep nop
, trading the complete release of resources by an execution core within a "hyperthreaded" processor for cross-processor shoulder taps that do not involve interrupts, effectively turning idle threads into perpetual waiters for a spin lock.)
Further reading
- https://superuser.com/a/377675/38062
add a comment |
up vote
2
down vote
up vote
2
down vote
A central processing unit always has to be executing something. If there's nothing to do, it simply loops in an infinite loop, which an interrupt (such as the system heartbeat interrupt) will break it out of.
In older multi-process/multi-threaded operating systems, if the dispatcher (the low-level scheduler that picks and switches to the next thread to run off the runnable threads queue) finds no thread ready to run it would simply enter such an infinite loop.
This is a problem for multi-processor operating systems, though, as the infinite loop is executed in the context of whatever thread the dispatcher was leaving. This could end up with the same thread "running" on two processors at once, which causes a range of problems.
So a more recent (comparatively more recent, that is; as this idea is some several decades old) design was to have, for each processor in the system, an idle thread. This thread does nothing but loop indefinitely, and is always runnable. So there is always a thread that the dispatcher can pick, and there's never a situation where there is no runnable thread for a processor to run.
In old versions of actual Unix, when system initialization has finished, the initialization code has set up data structures describing it as process #0. This has the traditional name of the "swapper process", because of what it did. It had to do something after initialization had finished, so what it did was run the code that swapped process segments between main RAM and the DASD swap area.
The idea of swapping went away in the late 1970s with the advent of demand paging designs; and process #0 became first the idle process and then the system process that contained all of the idle threads.
And that is what is also happening in Linux.
Of course, power management has been a consideration for over a quarter of a century at this point, and the traditional infinite loop of an unconditional branch instruction branching to itself causes a lot of unnecessary busywork and power drain. Modern (again a relative term) idle threads invoke special processor instructions that instruct the executing processor to wait, potentially lowering its clock rate to save power, for it to receive a hardware interrupt. (Over the years on x86 instruction architectures this has changed from hlt
to pause
, a.k.a. rep nop
, trading the complete release of resources by an execution core within a "hyperthreaded" processor for cross-processor shoulder taps that do not involve interrupts, effectively turning idle threads into perpetual waiters for a spin lock.)
Further reading
- https://superuser.com/a/377675/38062
A central processing unit always has to be executing something. If there's nothing to do, it simply loops in an infinite loop, which an interrupt (such as the system heartbeat interrupt) will break it out of.
In older multi-process/multi-threaded operating systems, if the dispatcher (the low-level scheduler that picks and switches to the next thread to run off the runnable threads queue) finds no thread ready to run it would simply enter such an infinite loop.
This is a problem for multi-processor operating systems, though, as the infinite loop is executed in the context of whatever thread the dispatcher was leaving. This could end up with the same thread "running" on two processors at once, which causes a range of problems.
So a more recent (comparatively more recent, that is; as this idea is some several decades old) design was to have, for each processor in the system, an idle thread. This thread does nothing but loop indefinitely, and is always runnable. So there is always a thread that the dispatcher can pick, and there's never a situation where there is no runnable thread for a processor to run.
In old versions of actual Unix, when system initialization has finished, the initialization code has set up data structures describing it as process #0. This has the traditional name of the "swapper process", because of what it did. It had to do something after initialization had finished, so what it did was run the code that swapped process segments between main RAM and the DASD swap area.
The idea of swapping went away in the late 1970s with the advent of demand paging designs; and process #0 became first the idle process and then the system process that contained all of the idle threads.
And that is what is also happening in Linux.
Of course, power management has been a consideration for over a quarter of a century at this point, and the traditional infinite loop of an unconditional branch instruction branching to itself causes a lot of unnecessary busywork and power drain. Modern (again a relative term) idle threads invoke special processor instructions that instruct the executing processor to wait, potentially lowering its clock rate to save power, for it to receive a hardware interrupt. (Over the years on x86 instruction architectures this has changed from hlt
to pause
, a.k.a. rep nop
, trading the complete release of resources by an execution core within a "hyperthreaded" processor for cross-processor shoulder taps that do not involve interrupts, effectively turning idle threads into perpetual waiters for a spin lock.)
Further reading
- https://superuser.com/a/377675/38062
answered Feb 24 at 10:36
JdeBP
32.6k468152
32.6k468152
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f426190%2fwhy-is-cpu-idle-called-as-the-last-function-of-the-start-kernel-routine%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown