linux smp_setup_processor_id

smp模型指的是对称多处理模型(Symmetric Multi-Processor),与它对应的是NUMA非一致性存储访问结果(Non-Uniform Memory Access)和MPP海量并行处理结构(Massive Parallel Processing)。它们的区别分别在于,SMP指的是多个CPU之间是平等关系,共享全部总线,内存和IO等。但是这个结构扩展性不好,往往CPU数量多了之后,很容易遇到抢占资源的问题。NUMA结构则是把CPU分模块,每个模块具有独立的内存,IO插槽等。各个模块之间通过互联模块进行数据交互。但是这样,就表示了有的内存数据在这个CPU模块中,那么处理这个数据当然最好是选择当前的CPU模块,这样每个CPU实际上地位就不一致了。所以叫做非一致性的存储访问结构。而MPP呢,则是由多个SMP服务器通过互联网连接起来,支持SMP模型的CPU有AMD/AMD64,而支持NUMA的的X86,而smp_setup_process_id在普通情况下是空实现,在不同的体系,比如arc/arm/kernel/setup.c就有对应的逻辑。

//.../arch/arm/kernel/setup.c
void __init smp_setup_processor_id(void)
{
    int i;
    //判断是否是smp系统,如果是则从arm协处理器读取当前cpuid,否则为0
    u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
    //根据level确定cpu号,即cpu=(mpidr>>0)&0xff
    u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
     
    //设置cpu的map数组
    //#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
    cpu_logical_map(0) = cpu;
    //nr_cpu_ids表示系统中cpu总数
    for (i = 1; i < nr_cpu_ids; ++i)
        cpu_logical_map(i) = i == cpu ? 0 : i;
        
    set_my_cpu_offset(0);
     
    pr_info("Booting Linux on physical CPU 0x%x\n", mpidr);
}
//检测是否为SMP架构
static inline bool is_smp(void)
{
#ifndef CONFIG_SMP
    return false;
    //CONFIG_SMP_ON_UP表示可以支援SMP Kernel运行在UniProcessor(單核心)的处理器上
#elif defined(CONFIG_SMP_ON_UP)
    extern unsigned int smp_on_up;
    return !!smp_on_up;
#else
    return true;
#endif
}

//arch/arm/include/asm/cputype.h
static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
{
    //从arm协处理器CP15的c0中读取当前cpu id
    return read_cpuid(CPUID_MPIDR);
}

#define CPUID_MPIDR 5
#define read_cpuid(reg) \
        ({ \
            unsigned int __val;                                        \
            asm("mrc p15, 0, %0, c0, c0, " __stringify(reg)            \
            : "=r" (__val)     \
            :     \
            : "cc");     \
            __val; \
        })

#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
        ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)

static inline void set_my_cpu_offset(unsigned long off)
{
    //Set TPIDRPRW
    asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值