ARM Linux 大小核切换 ——cortex-A7 big.LITTLE 大小核 切换代码分析
ARM Linux 大小核切换——cortex-A7 big.LITTLE 大小切换代码分析
8核CPU或者是更多核的处理器,这些CPU有可能不完全对称。有的是4个A15和4个A7,或者是4个A57和4个A53,甚至像海思麒麟935处理器(4核A53 2.2 GHz + 4核A53 1.5 GHz),这8个核的频率可能不一样,则使用过程中需要大小核切换(频率高的是大核,频率低的是小核)。本文以ARM cortex-A7为例,分析大小核切换的代码,着重于分析实现切换的代码,对于为什么要这样切换、以及什么时候切换,不做过多探讨。
主要代码分布:
arch/arm/common/bL_switcher.c
arch/arm/include/asm/bL_switcher.h
drivers/cpufreq/Arm_big_little.c
编译后形成的两个驱动模块:
__initcall_bL_switcher_init6
__initcall_bL_cpufreq_register7
执行流程图如下所示。
上图的左边是bL_switcher_init执行流程。
右边是切换线程bL_switcher_thread执行流程,这个线程是核心代码。代码的上半部分是一个CPU在运行,然后这个CPU完成下电后。下半部分蓝色所示,是起来的那个CPU在运行,这样就完成了大小核的切换操作。
1 bL_switcher_init
bL_switcher_init执行流程如下:
如果最大CPU组数(簇)不为2,则报错,然后返回
bL_running_cluster赋值1,默认设为是第一簇在运行
no_bL_switcher初值为FALSE
bL_switcher_enable
bL_switcher_halve_cpus 关闭不必要的CPU
为每个online的CPU创建切换线程bL_switcher_thread
bL_switcher_active赋值1
bL_switcher_sysfs_init 创建sys/kernel/bL_switcher
bL_switcher_restore_unpaired_cpus 恢复不成对的CPU,给它们上电
创建完sys/kernel/bL_switcher,则可以通过下面的命令,手动查看/设置能否切换、查看/设置切换那个簇的CPU。
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 切换请求bL_switch_request
这是个内联函数,需要两个参数,第一个是CPU的ID,第二个是簇号,内核调到的有三处。
一是在Arm_big_little.c:bL_cpufreq_set_rate:需要不同的簇切换时;
二、三是在执行echo 0/1 > /sys/kernel/ bL_switcher/ do_switch ,调用到bL_do_switch_store函数,这里面判断是否需要切换
这个内联函数,直接执行bL_switch_request_cb,参数是前面的2个,再加上两个NULL。
bL_switch_request_cb:
判断第一个参数CPU的ID是否超出范围;
获取当前CPU的线程函数指针
赋值wanted_cluster
唤醒当前线程函数的工作队列
3 切换线程bL_switcher_thread
bL_switcher_thread执行流程:
等待事件。满足事件的两个可能条件:
一是上面的bL_switch_request_cb函数,唤醒线程,且切换到的CPU簇数不为-1;
二是bL_switcher_disable函数调用kthread_stop,唤醒线程
bL_switch_to
找到成对的CPU ID ,簇号
mcpm_cpu_power_up 给CPU上电,跳转到 mcpm_entry_point
gic_send_sgi 给其发送0号软中断
wait_for_completion_timeout(&inbound_alive 等待它给我发送软中断 IPI_COMPLETION
关闭IRQ、FIQ
迁移中断到对应的CPU上
关闭时钟Tick
cpu_pm_enter gic_cpu_save 保存中断设置
cpu_suspend 这个跟睡眠的流程很相似
bL_switchpoint
call_with_stack arch/arm/lib/call_with_stack.S 若失败了,是可以返回的
bL_do_switch
让刚起来的CPU跳转到cpu_resume,给其发送sev
若handshake变量为0,则进入wfe
等待不为0后,mcpm_cpu_power_down对自身断电
call_with_stack: 携带的三个参数,第一个是函数,第二个是函数调用时用到的参数,第三个是栈地址
将SP、LR依次放入栈的顶部
SP赋值让开两个寄存器后的地址
R0赋给R2
R1赋给R0
LR赋值下面的标号1处
R2赋给PC,即跳转到R2
若失败了,则跳转到LR处,就是标号1处
弹出LR
弹出SP
LR赋给PC,跳转到了bL_switchpoint,调用call_with_stack函数的地方。
此处设置真是巧妙,不同簇对应的CPU ID都是0,则刚起来的CPU正好能通过下面的步骤
mcpm_entry_point -> cpu_resume -> cpu_do_resume=cpu_v7_do_resume -> cpu_resume_mmu -> 再次跳转到上面调用__cpu_suspend处继续运行了。
即要下电的CPU刚保存后堆栈,又被刚上电的CPU恢复了。
接下来就是上电的CPU再运行了。
cpu_pm_exit gic_cpu_restore 恢复中断设置
时钟接着运行 Tick,两个CPU用到的节拍Timer是同一个。
开启IRQ、FIQ
*handshake_ptr = 1;
dsb_sev 给那个CPU发送事件
这样就完成了CPU的切换,这个函数的前一半是一个CPU在执行,后一半变成了另一个CPU在执行。
4 bL_cpufreq_register
获取bL_switcher_active的值,将这个值(真或者假)设置给bL_switching_enabled变量;
初始化互斥锁cluster_lock;
注册cpufreq_driver驱动bL_cpufreq_driver。
如果上面的驱动注册成功,则将bL_switcher_notifier 挂在bL_activation_notifier链表上;
若挂载失败,则卸载驱动bL_cpufreq_driver
bL_cpufreq_driver定义如下:
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,
};
若bL_cpufreq_driver注册成功,执行下面的命令,就可以看到有个驱动是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
用bL_cpufreq_driver这种调频策略时,就会执行到bL_cpufreq_set_target,然后执行bL_cpufreq_set_rate,则有可能调用到bL_switch_request。
ARM Linux 大小核切换 ——cortex-A7 big.LITTLE 大小核 切换代码分析的更多相关文章
- Linux kernel的中断子系统之(七):GIC代码分析
返回目录:<ARM-Linux中断系统>. 总结: 原文地址:<linux kernel的中断子系统之(七):GIC代码分析> 参考代码:http://elixir.free- ...
- ARM Linux中断发生时内核堆栈切换
转载注明出处:http://www.wowotech.net/forum/viewtopic.php?id=54 对ARM Linux中断非常简洁.精确的描述. 发生了中断,最重要的是保存现场,在中断 ...
- ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现
ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现 承接 http://www.wowotech.net/pm_subsystem/suspend_and_re ...
- ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联
ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联 CCI-400 集合了互联和一致性功能,有 2 个 ACE slave 接口和 3 个 ACE-Li ...
- arm linux kernel 从入口到start_kernel 的代码分析
参考资料: <ARM体系结构与编程> <嵌入式Linux应用开发完全手册> Linux_Memory_Address_Mapping http://www.chinaunix. ...
- Arm Linux系统调用流程详细解析
Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口. 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的 ...
- Linux时间子系统之(十七):ARM generic timer驱动代码分析
专题文档汇总目录 Notes:ARM平台Clock/Timer架构:System counter.Timer以及两者之间关系:Per cpu timer通过CP15访问,System counter通 ...
- Linux时间子系统(十七) ARM generic timer驱动代码分析
一.前言 关注ARM平台上timer driver(clocksource chip driver和clockevent chip driver)的驱动工程师应该会注意到timer硬件的演化过程.在单 ...
- ARM linux的启动部分源代码简略分析【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/11/07/2396784.html ARM linux的启动部分源代码简略分析 以友善之臂的mini2 ...
随机推荐
- c语言printf实现同一位置打印输出
控制台同一位置打印输出,例如:进度1%->100%在同一位置显示.刚学习c语言的时候一直想做起来,可惜查询好多资料不行.时隔6年多,空闲之余又想起这个问题,便决定一试,虽然c语言已经几乎忘光了, ...
- Spring_Spring与IoC_基于注解的DI
一.基本注解的使用 (1)导入AOP的Jar包 (2) 与set()无关 二.组件扫描器的base-package 三.@Component相关注解 四.@Scope 五.域属性的注入 (1)byTy ...
- thinkphp session设置
<?php namespace Home\Controller; use think\Controller; /*登录*/ class LoginController extends Publi ...
- mysql 的用法
SELECT CASEWHEN //当count(userId) = 0的时候 让其为null 不然报警告 // count(DISTINCT userId) 不用处理 count(userId ...
- 高德地图 API JavaScript API
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm12.aspx ...
- [国家集训队2012]middle(陈立杰)
我是萌萌的传送门 我是另一个萌萌的传送门 脑残错误毁一下午…… 其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值 ...
- Python-并发编程(线程)
之前我们说了并发编程中的进程问题,几天我们来聊聊并发编程中的线程问题. 一.背景知识 1.进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能 ...
- 转动的八卦图纯css实现
这类的东西网上一搜就是大把的,看着比较空旷的博客,所以自己也来写一个. <!DOCTYPE html> <html> <head> <meta chars ...
- 006服务监控看板Hystrix Dashboard
1.POM配置 和普通Spring Boot工程相比,仅仅添加了Hystrix Dashboard和Spring Boot Starter Actuator依赖 <dependencies> ...
- Java基础学习总结一(Java语言发展历史、JDK下载安装以及配置环境变量)
最近一段时间计划复习一下java基础知识,使用的视频课程是尚学堂高淇老师的,上课过程中的心得体会直接总结一下,方便以后复习. 一:计算机语言的发展 1:机器语言,最原始的语言,主要有“01”构成,最早 ...