Linux arm cpu topology

Linux arm cpu topology

目录

Linux arm cpu topology

CPU拓扑结构核心结构体

架构实现

init_cpu_topology

store_cpu_topology

MPIDR


CPU拓扑结构核心结构体

struct cpu_topology {
    int thread_id; //一个core中的
    int core_id; //core概念
    int package_id; //cluster概念
    int llc_id;
    cpumask_t thread_sibling;
    cpumask_t core_sibling;
    cpumask_t llc_sibling;
};

该结构体定义出的per-cpu变量
302  struct cputopo_arm cpu_topology[NR_CPUS];
303  EXPORT_SYMBOL_GPL(cpu_topology);

cpu topology分为三级
cluster0
|_core0
  |_thread0
  |_thread1
|_core1
|_core2
|_core3
cluster1
|_core4
|_core5
|_core6
|_core7


smp_store_cpu_info
|___store_cpu_topology

架构实现

arch/arm/kernel/topology.c

该文件中提供如下几个函数

init_cpu_topology

parse_dt_topology

store_cpu_topology

update_cpu_capacity

init_cpu_topology

调用关系

reset_cpu_topology的逻辑比较简单,就是给per-cpu的变量一个初始值。

void __init reset_cpu_topology(void)
{
    unsigned int cpu;

    for_each_possible_cpu(cpu) {
        struct cpu_topology *cpu_topo = &cpu_topology[cpu];

        cpu_topo->thread_id = -1;
        cpu_topo->core_id = -1;
        cpu_topo->package_id = -1;
        cpu_topo->llc_id = -1;

        clear_cpu_topology(cpu);
    }
}

static void clear_cpu_topology(int cpu)
{
    struct cpu_topology *cpu_topo = &cpu_topology[cpu];

    cpumask_clear(&cpu_topo->llc_sibling);
    cpumask_set_cpu(cpu, &cpu_topo->llc_sibling);

    cpumask_clear(&cpu_topo->core_sibling);
    cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
    cpumask_clear(&cpu_topo->thread_sibling);
    cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
}

在parse_dt_topology中,从dt获取cpu capacity,调用update_cpu_capacity更新相关变量。

cpu capacity代表了一个cpu的处理能力,它与各个cpu运行在哪个频点有关,在big-LITTLE架构下的cpu,大核与小核的capacity应设置为不同值。

在这个函数中没有进行dt中cluster / core topology的读取,即当前的kernel源码在arm架构下不支持dt可配置的拓扑结构(一切均从mpidr读取)。

store_cpu_topology

在每个core初始化时,都会调用到store_cpu_topology,填充本cpu的cpu_topology变量。

MPIDR

读取该寄存器值,(HEX)为

armv7 A7 : 80000000 / 80000001 / 80000002 / 80000003

armv8 A55 :

aarch64 : 0000000080000000 / 0000000080000100 / 0000000080000200 ...

aarch32 : 80000000 / 80000100 / 80000200 ...

bit [30] & bit [31],在代码中会进行判断,若bit [30] = 0 & bit [31] = 1,代表系统支持多core。

相关代码为

if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
    ...
} else {
    unsupport...
}

#define MPIDR_SMP_BITMASK (0x3 << 30)

#define MPIDR_SMP_VALUE (0x2 << 30)

bit [24],判断是否支持cpu内多线程,该机制常用于x86架构,arm基本不支持。

Aff0 / Aff1 / Aff2分为表示 coreid / packageid(clusterid) / threadid

相关代码如下:

        if (mpidr & MPIDR_MT_BITMASK) {
            /* core performance interdependency */
            cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
            cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
            cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
        } else {
            /* largely independent cores */
            cpuid_topo->thread_id = -1;
            cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
            cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
        }

drivers/base/arch_topology.c
这个文件给出的是一些通用接口,在具体的架构下进行调用

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值