1. Foreword
From the description of the Linux CPU Core power Management (1) _ Overview, kernel CPU control is located in ". \kernel\cpu.c", a connecting module that is responsible for shielding arch-dependent implementation details, Provides the top-level software with a unified API for controlling CPU core (mainly including the implementation of interfaces such as Cpu_up/cpu_down). This article will be based on these APIs, from top to bottom, analysis of the CPU core from boot to shutdown of the entire process (mainly CPU HotPlug), to further understand the system running process of CPU core power management related behavior.
Note 1: In fact, this part is not in the category of power management, but the system-level software behavior (boot, scheduling, power management, etc.), the reason is put here, the main reason is that these complex behavior behind, the purpose of only a----energy-saving. Therefore, this article will focus on the CPU core power state switching process, involving other knowledge, such as process scheduling, only a stroke. 2. Possible/present/active/online CPUs
As mentioned in the previous article, kernel uses 4 bitmap to save CPU core:possible, present, active, and online, respectively, in 4 states. What the meaning of these four states is. Here we will answer this question based on the relevant code logic.
Before you start, take a look at the comments in the kernel:
1: * include/linux/cpumask.h * *
2:
3:
4:/*
5: * The following particular system Cpumasks and operations manage
6: * Possible, present, active and online CPUs.
7: *
8: * cpu_possible_mask-has bit ' CPU ' Set IFF CPU is populatable
9: * cpu_present_mask-has bit ' CPU ' Set IFF CPU is populated
* Cpu_online_mask -has bit ' CPU ' Set IFF CPU available to scheduler
One: * cpu_active_mask -has bit ' CPU ' Set IFF CPU available to migration
: *
* If! CONFIG_HOTPLUG_CPU, Present = = possible, and active = = online.
*: *
* The cpu_possible_mask is fixed in boot time, as the set of CPU ID ' s
* This it is possible might ever to plugged in anytime the
* Life of that system boot. The Cpu_present_mask is dynamic (*),
*: * representing which CPUs are currently plugged in. and
: * Cpu_online_mask is the dynamic subset of Cpu_present_mask,
* indicating those CPUs available for scheduling.
: *
* If HOTPLUG is enabled, then cpu_possible_mask are forced to have
* All Nr_cpus bits set, otherwise it are just the set of CPUS that
: * ACPI reports present at boot.
: *
Num: * If HOTPLUG is enabled, then cpu_present_mask varies dynamically,
* Depending on what ACPI reports as currently plugged in, otherwise
* Cpu_present_mask is just a copy of Cpu_possible_mask.
*/
The effect is this:
Possible state of the CPU means is "populatable (think this word is not possible understand)", can be understood as the existence of this CPU resources, but has not been included in the kernel management scope;
Present state of the CPU, is already "populated" CPU, can be understood as has been kernel taken over;
The CPU on the online state, indicating that it can be used by the scheduler;
The active state of the CPU, which means that it can be migrate (what it means. );
If the system does not enable CPU HotPlug function, then present equals possible,active equals online.
It is not very easy to understand, not anxious, we an analysis. 2.1 Possible CPU
Possible's CPUs, which represents all the CPUs that can be used in the system, is not modified after the boot phase is determined. Take ARM64 as an example, its initialization process is as follows.
1 after the system on the power, boot CPU boot, execute Start_kernel (INIT/MAIN.C), and respectively invoke Boot_cpu_init and Setup_arch two interfaces, possible CPU-related initialization.
2) Boot_cpu_init is responsible for placing the current boot CPU in the bitmap of the possible CPU, and, similarly, the boot CPU is present, Oneline, active CPU (therefore, subsequent descriptions are for non-boot CPU). As follows:
1: * INIT/MAIN.C * *
2:
3:static void __init boot_cpu_init (void)
4: {
5: int cpu = SMP_PROCESSOR_ID ();
6: * Mark the Boot CPU "present", "online" etc for SMP and up case * *
7: set_cpu_online (CPU, true);
8: set_cpu_active (CPU, true);
9: set_cpu_present (CPU, true);
Ten: set_cpu_possible (CPU, true);
11:}
SMP_PROCESSOR_ID is used to get the current CPU ID;
Set_cpu_xxx interface, you can set the specified CPU to (or clear) the specified state.
3 Setup_arch is responsible for parsing and setting up other possible CPUs according to the MPIDR registers, as well as DTS configuration, as follows:
1: * ARCH/ARM64/KERNEL/SETUP.C * *
2:
3:void __init Setup_arch (char **cmdline_p)
4: {
5:..
6: cpu_logical_map (0) = Read_cpuid_mpidr () & Mpidr_hwid_bitmask;
7: cpu_read_bootcpu_ops ();
8: #ifdef CONFIG_SMP
9: Smp_init_cpus ();
Ten: Smp_build_mpidr_hash ();
One: #endif
A: ...
13:}
3a) Cpu_logical_map Array
Kernel uses an orthopedic array (CPU_LOGICAL_MAP, defined below) to hold a mapping between the physical CPU (identified by ID) and the logical CPU (index of the array), which is determined by Nr_cpus.
1: * arch/arm64/include/asm/smp_plat.h * *
2:
3:/*
4: * Logical CPU mapping.
5: */
6:extern U64 __cpu_logical_map[nr_cpus];
7: #define CPU_LOGICAL_MAP (CPU) __CPU_LOGICAL_MAP[CPU]
The sixth line of the above Setup_arch code reads the ID (physical ID) of the current CPU (the boot CPU) through the READ_CPUID_MPIDR interface, and is saved in the first location of the map table.
3b) Smp_init_cpus
If you enable SMP, call the Smp_init_cpus interface and complete the following things:
The HW ID of the other CPUs (through the ' reg ' keyword, as below) is parsed from DTS and stored in the CPU_LOGICAL_MAP array;
Perform set_cpu_possible operations on all CPUs in the Cpu_logical_map array and set them to the possible state.
1: {
2:..
3: CPUs {
4: #address-cells = <2>;
5: #size-cells = <0>;
6:
7: cpu@0 {
8: device_type = "CPU";
9: compatible = "Arm,cortex-a53", "ARM,ARMV8";
reg = <0x0 0x0>;
One: Enable-method = "Psci";
cpu-idle-states = <&cpu_sleep_0 &CPU_SLEEP_1>;
: };
14:
: cpu@1 {
: Device_type = "CPU";
compatible = "Arm,cortex-a53", "ARM,ARMV8";
reg = <0x0 0x1>;
: Enable-method = "Psci";
cpu-idle-states = <&cpu_sleep_0 &CPU_SLEEP_1>;
: };
A: ...
: };
A: ...
25:}
Example of a CPU DTS file.
4) Summary
For ARM64, the possible CPU is the physical presence of the CPU core, as specified in DTS. 2.2 present CPU
Or take ARM64 as an example, "Start_kernel->setup_arch" after successful execution, continue with the Start_kernel->rest_init->kernel_init (PID 1,init Task)- >kernel_init_freeable ", the interface of Arch-dependent is invoked in kernel_init_freeable: Smp_prepare_cpus, which has two main functions:
1 The structure of the CPU in the system, the specific reference to the "Linux CPU Core power Management (2) _cpu topology".
2 after the construction of the topological structure, according to the CPU topology, initialize the system present CPU mask, the code is as follows:
1:void __init smp_prepare_cpus (unsigned int max_cpus)
2: {
3:..
4:/ * Don ' t bother if we ' re effectively up */
5: if (Max_cpus <= 1)
6: Return ;
7:
8:/ *
9: * initialise the present map (which describes the set of CPUs
* Actually populated at the "Present time" and release the
One: * secondaries from the bootloader.
: *
* Make sure we online at most (max_cpus-1) additional CPUs.
*/
: max_cpus--;
: for_each_possible_cpu (CPU) {
: if (max_cpus = 0)
: Break ;
19:
if (CPU = = smp_processor_id ())
: continue;
22:
: if (!CPU_OPS[CPU])
: continue;
25:
: err = cpu_ops[cpu]->cpu_prepare (CPU);
: if (err)
: continue;
29:
: set_cpu_present (CPU, true);
: max_cpus--;
: }
33:}
4~6: Of course, if the number of CPUs is not greater than 1, then it is not an SMP system, there is no follow-up concept, direct return.
16~32 Line, poll all Possib