ARM Linux size kernel switch--cortex-a7 big. LITTLE size Kernel switch code Analysis

Source: Internet
Author: User

ARM Linux size kernel switch -cortex-a7 big. LITTLE size switch Code Analysis

8-core CPUs or more cores, these CPUs may not be completely symmetrical. There are 4 A15 and 4 A7, or 4 A57 and 4 A53, even like HiSilicon Kylin 935 processor (4 Core A53 2.2 GHz + 4 core A53 1.5 GHz), the frequencies of these 8 cores may not be the same, then the use of the process requires the size of the core switch (high frequency is the large core, The low frequency is the small nucleus). This paper takes arm cortex-a7 as an example to analyze the code of size and core switching , focusing on the analysis of switching code, for why this switch, and when to switch, do not do too much discussion.

Main code Distribution:

Arch/arm/common/bl_switcher.c

Arch/arm/include/asm/bl_switcher.h

Drivers/cpufreq/arm_big_little.c

Two drive modules formed after compilation:

__initcall_bl_switcher_init6

__initcall_bl_cpufreq_register7

The execution flowchart is shown below.

On the left is the Bl_switcher_init execution process.

On the right is the switch thread bl_switcher_thread execution process, which is the core code. The upper part of the code is a CPU that is running, and then this CPU completes the power-down. The lower half is shown in blue, and the CPU that is up is running, which completes the switching operation of the size core.

1 Bl_switcher_init

The Bl_switcher_init execution process is as follows:

If the maximum number of CPU groups (clusters) is not 2, an error is then returned

Bl_running_cluster is assigned a value of 1, which is set by default to be the first cluster running

No_bl_switcher initial value is False

Bl_switcher_enable

Bl_switcher_halve_cpus shutdown of unnecessary CPUs

Create a toggle thread for each of the online CPUs Bl_switcher_thread

bl_switcher_active assigned value 1

Bl_switcher_sysfs_init creating sys/kernel/bl_switcher

Bl_switcher_restore_unpaired_cpus Restore the unpaired CPUs, power them up.

After you create the Sys/kernel/bl_switcher, you can manually view/set the ability to toggle, view/Set the CPU switching between the clusters by using the command below.

cat/sys/kernel/bl_switcher/active

echo 0/1 >/sys/kernel/bl_switcher/active

Cat/sys/kernel/bl_switcher/do_switch

echo 0/1 >/sys/kernel/bl_switcher/do_switch

2 Switching Request Bl_switch_request

This is an inline function, requires two parameters, the first one is the CPU ID, the second is the cluster number, the kernel is transferred to three places.

One is in Arm_big_little.c:bl_cpufreq_set_rate: when different cluster switching is required;

Second, three is in the implementation of ECHO 0/1 >/sys/kernel/bl_switcher/do_switch, call to Bl_do_switch_store function, which determines whether the need to switch

This inline function executes the BL_SWITCH_REQUEST_CB directly, with the arguments being 2 preceding, plus two null.

BL_SWITCH_REQUEST_CB:

Determines whether the ID of the first parameter CPU is out of range;

Gets the thread function pointer for the current CPU

Assignment Wanted_cluster

Wakes the work queue of the current thread function

3 Toggle Thread Bl_switcher_thread

Bl_switcher_thread Execution Process:

Wait for the event. Two possible conditions to meet the event:

One is the BL_SWITCH_REQUEST_CB function above, wake up the thread, and switch to the number of CPU clusters is not-1;

The second is the bl_switcher_disable function called Kthread_stop, which wakes up the thread

Bl_switch_to

Find paired CPU ID, cluster number

Mcpm_cpu_power_up to power the CPU, jump to Mcpm_entry_point

Gic_send_sgi send it a soft interrupt number No. 0

Wait_for_completion_timeout (&inbound_alive wait for it to send me a soft interrupt ipi_completion

Turn off IRQ, FIQ

Migration interrupted to the corresponding CPU

Turn off clock tick

Cpu_pm_enter Gic_cpu_save Save Interrupt settings

Cpu_suspend , this is very similar to the sleep process.

Bl_switchpoint

call_with_stack arch/arm/lib/call_with_stack. If S fails, it can be returned.

Bl_do_switch

Let the newly-up CPU jump to cpu_resumeand send it SEv

If the handshake variable is 0, enter the WFE

After the wait is not 0, the Mcpm_cpu_power_down power to itself

call_with_stack: Three parameters to carry, the first is the function, the second is the parameter used in the function call, and the third is the stack address

Place SP, LR into the top of the stack in turn

SP assignment the address after two registers

R0 Fu to R2

R1 Fu to R0

LR Assignment below the label 1 place

R2 to the PC, that is, jump to R2

If it fails, it jumps to LR, marking 1.

Eject LR

Eject SP

LR assigns to the PC, jumps to the bl_switchpoint, calls the call_with_stack function Place.

The setting here is really ingenious, the CPU ID of the different clusters is 0, then the CPU that just got up can pass the following steps

Mcpm_entry_point, cpu_resume , Cpu_do_resume=cpu_v7_do_resume, Cpu_resume_mmu, again jump to the above call __ The cpu_suspend continues to run.

that is to power down the CPU just after the stack is saved, and the CPU is just on the power resumed.

The next step is to power up the CPU and run it again.

Cpu_pm_exit Gic_cpu_restore Recovery Interrupt settings

The clock then runs Tick, and the two CPU beats timer is the same.

Open IRQ, FIQ

*handshake_ptr = 1;

Dsb_sev send events to that CPU

This completes the CPU switchover, the first half of this function is a CPU in execution, and the second half becomes the other CPU in the execution.

4 Bl_cpufreq_register

Get the value of bl_switcher_active, set this value (TRUE or false) to the bl_switching_enabled variable;

Initialize the mutex lock cluster_lock;

Register Cpufreq_driver driver Bl_cpufreq_driver.

If the above driver registration is successful, the Bl_switcher_notifier is hung on the bl_activation_notifier linked list;

If mount fails, uninstall driver Bl_cpufreq_driver

Bl_cpufreq_driver is defined as follows:

static struct Cpufreq_driver Bl_cpufreq_driver = {

. Name = "Arm-big-little",

. Flags = Cpufreq_sticky,

. Verify = Bl_cpufreq_verify_policy,

. target = Bl_cpufreq_set_target,

. get = Bl_cpufreq_get_rate,

. init = Bl_cpufreq_init,

. Have_governor_per_policy = True,

. attr = Bl_cpufreq_attr,

};

If the Bl_cpufreq_driver registration succeeds, execute the following command, you can see that there is a driver is arm-big-little.

Cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors

Conservative OnDemand userspace PowerSave Interactive performance

Cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_governors

Interactive

Cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver

arm-big-little

With BL_CPUFREQ_DRIVER this FM policy, it executes to bl_cpufreq_set_target and then executes Bl_cpufreq_set_rate, and it is possible to call to Bl_switch_request.

ARM Linux size kernel switch--cortex-a7 big. LITTLE size Kernel switch code Analysis

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.