vmalloc_init()函数中的for_each_possible_cpu宏,代码运行是否只有一个cpu?还是每个 cpu?

for_each_possible_cpu macro in vmalloc_init() function, does the code run in only one cpu? or in every cpu?

这不是关于编程的,但我在这里问.. 在 linux start_kernel() 函数中,在 mm_init() 函数中,我看到 vmalloc_init() 函数。 在函数内部我看到这样的代码。

void __init vmalloc_init(void)
{
    struct vmap_area *va;
    struct vm_struct *tmp;
    int i;
        
    /*  
     * Create the cache for vmap_area objects.
     */
    vmap_area_cachep = KMEM_CACHE(vmap_area, SLAB_PANIC);

    for_each_possible_cpu(i) {
        struct vmap_block_queue *vbq;
        struct vfree_deferred *p;
                    
        vbq = &per_cpu(vmap_block_queue, i);
        spin_lock_init(&vbq->lock);
        INIT_LIST_HEAD(&vbq->free);
        p = &per_cpu(vfree_deferred, i);
        init_llist_head(&p->list);
        INIT_WORK(&p->wq, free_work);
    }

    /* Import existing vmlist entries. */
    for (tmp = vmlist; tmp; tmp = tmp->next) {
        va = kmem_cache_zalloc(vmap_area_cachep, GFP_NOWAIT);
        if (WARN_ON_ONCE(!va))
            continue;

        va->va_start = (unsigned long)tmp->addr;
        va->va_end = va->va_start + tmp->size;
        va->vm = tmp;
        insert_vmap_area(va, &vmap_area_root, &vmap_area_list);
    }

    /*
     * Now we can initialize a free vmap space.
     */
    vmap_init_free_space();
    vmap_initialized = true;
}

我不确定此代码是 运行 在每个 cpu(核心)上还是仅在第一个 cpu 上?
如果此代码 运行 在每个 smp 核心上,此代码在 for_each_possible_cpu 循环中如何 运行?
smp 设置似乎在此功能之前完成。

start_kernel() 调用 mm_init(),后者调用 vmalloc_init()。此时只有第一个(引导)CPU 处于活动状态。稍后,start_kernel() 调用 arch_call_rest_init(),后者调用 rest_init().

rest_init() 为具有入口点 kernel_init() 的 init 任务创建内核线程。 kernel_init() 致电 kernel_init_freeable()kernel_init_freeable() 最终调用 smp_init() 来激活剩余的 CPU。

for_each_cpu系列中的每个宏都只是for()循环的包装器,其中迭代器是CPU索引.

例如,这个系列的核心宏是defined as

#define for_each_cpu(cpu, mask)             \
    for ((cpu) = -1;                \
        (cpu) = cpumask_next((cpu), (mask)),    \
        (cpu) < nr_cpu_ids;)

for_each_cpu 系列中的每个宏都使用自己的 CPUs mask,它只是一组对应于 CPU 索引的位.例如。 for_each_possible_cpu 宏的掩码为 CPU 的每个索引设置了位,这可以在当前机器会话中启用。