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 的每个索引设置了位,这可以在当前机器会话中启用。
这不是关于编程的,但我在这里问.. 在 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 的每个索引设置了位,这可以在当前机器会话中启用。