使用 on_each_cpu
在多核系统中执行对称操作
背景介绍
在多核系统中,有时需要在每个 CPU 上执行特定的操作。这种操作需要确保每个 CPU 都能执行相同的函数,以实现对称的处理。在 Linux 内核中,提供了一个标准函数 on_each_cpu
,可以方便地实现这一需求。
on_each_cpu
函数介绍
函数原型
int on_each_cpu(void (*func)(void *info), void *info, int wait);
func
:要在每个 CPU 上执行的函数。info
:传递给func
的参数。wait
:是否等待所有 CPU 完成函数执行。0
表示不等待,1
表示等待。
使用示例
以下是一个示例,展示如何使用 on_each_cpu
在每个 CPU 上执行一个简单的函数:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/delay.h>
static void print_hello(void *info)
{
printk(KERN_INFO "Hello from CPU %d\n", smp_processor_id());
}
static int __init hello_init(void)
{
on_each_cpu(print_hello, NULL, 1);
return 0;
}
static void __exit hello_exit(void)
{
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple example of on_each_cpu");
在这个示例中,print_hello
函数将在每个 CPU 上执行,并打印当前 CPU 的 ID。
on_each_cpu
的实现原理
on_each_cpu
的实现涉及到在多核系统中调度和执行函数。其核心思想是通过 IPIs(Inter-Processor Interrupts)在每个 CPU 上触发函数执行。
实现步骤
- 发送 IPI:向所有 CPU 发送 IPI,通知它们执行指定的函数。
- 执行函数:每个 CPU 在接收到 IPI 后,执行指定的函数。
- 等待完成:如果
wait
参数为1
,则等待所有 CPU 完成函数执行。
代码实现
以下是 on_each_cpu
的简化实现示例,省略了一些复杂的细节:
void on_each_cpu(void (*func)(void *info), void *info, int wait)
{
int cpu;
for_each_online_cpu(cpu) {
smp_call_function_single(cpu, func, info, wait);
}
}
on_each_cpu
实际上调用了 smp_call_function_single
,后者用于在指定的 CPU 上执行函数。
smp_call_function_single
的实现
smp_call_function_single
是一个更底层的函数,它负责向单个 CPU 发送 IPI 并执行函数。其简化实现如下:
int smp_call_function_single(int cpu, void (*func)(void *info), void *info, int wait)
{
// 向指定 CPU 发送 IPI
send_IPI(cpu);
// 执行函数
if (cpu == smp_processor_id()) {
// 在当前 CPU 上直接执行
func(info);
} else {
// 在其他 CPU 上,通过 IPI 执行
enqueue_function(cpu, func, info);
if (wait) {
// 等待目标 CPU 完成执行
wait_for_completion(cpu);
}
}
return 0;
}
总结
on_each_cpu
是一个强大的工具,用于在多核系统中对每个 CPU 执行对称操作。其核心原理是通过 IPIs 调度函数执行,同时提供了简单的接口来确保所有 CPU 的操作都能按需完成。通过理解其实现,可以更好地利用多核系统的并行处理能力。