start_kernel——setup_per_cpu_areas

setup_per_cpu_areas是针对SMP系统内核内存管理初始化的关键函数,负责为每个处理器创建per-cpu数据,减少缓存一致性问题。在内核加载过程中,.data.percpu段被复制NR_CPUS次,每个CPU的percpu区域开始地址存储在__per_cpu_offset数组中。PAGE_SIZE常量在不同场景中的处理也进行了说明。
摘要由CSDN通过智能技术生成

setup_per_cpu_areas是为了对内核的内存管理(mm)进行初始化而调用的函数之一。只在SMP系统中调用,UP中不执行任何操作。
setup_per_cpu_areas函数为SMP的每个处理器生成per-cpu数据。
per-cpu数据按照不同的CPU类别使用,以将性能低下引发的缓存一致性(cache coherency)问题减小到最小。per-cpu数据由各cpu独立使用,即使不锁也可访问,十分有效。
以下摘抄自:http://blog.csdn.net/yunsongice/article/details/5605239

每CPU变量主要是数据结构的数组,系统的每个CPU对应数组的一个元素。

一个CPU不应该访问与其他CPU对应的数组元素,另外,它可以随意读或修改它自己的元素而不用担心出现竞争条件,因为它是唯一有资格这么做的CPU。但是,这也意味着每CPU变量基本上只能在特殊情况下使用,也就是当它确定在系统的CPU上的数据在逻辑上是独立的时候。

每CPU的数组元素在主存中被排列以使每个数据结构存放在硬件高速缓存的不同行,因此,对每CPU数组的并发访问不会导致高速缓存行的窃用和失效(这种操作会带来昂贵的系统开销)。

虽然每CPU变量为来自不同CPU的并发访问提供保护,但对来自异步函数(中断处理程序和可延迟函数)的访问不提供保护,在这种情况下需要另外的同步技术。

此外,在单处理器和多处理器系统中,内核抢占都可能使每CPU变量产生竞争条件。总的原则是内核控制路径应该在禁用抢占的情况下访问每CPU变量。因为当一个内核控制路径获得了它的每CPU变量本地副本的地址,然后它因被抢占而转移到另外一个CPU上,但仍然引用原来CPU元素的地址,这是非常危险的。

init/main.c中的setup_per_cpu_areas调用arch/x86/kernel/setup_percpu.c

void __init setup_per_cpu_areas(void)
{
    unsigned int cpu;
    unsigned long delta;
    int rc;

    printk(KERN_EMERG "NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n",
        NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids);

    /*
     * Allocate percpu area.  Embedding allocator is our favorite;
     * however, on NUMA configurations, it can result in very
     * sparse unit mapping and vmalloc area isn't spacious enough
     * on 32bit.  Use page in that case.
     */
#ifdef CONFIG_X86_32
    if (pcpu_chosen_fc == PCPU_FC_AUTO && pcpu_need_numa())
        pcpu_chosen_fc = PCPU_FC_PAGE;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值