linux kernel synchronization 2

Per CPU Variables

  • A CPU should not access the elements of the array corresponding to other CPU.
  • 每个CPU拥有该变量的独立副本
  • 无需加锁 - 由于每个CPU只操作自己的副本,因此读写自己的副本时不会产生竞争条件
  • 缓存优化 - 每个数据结构在主存中对齐,确保每个数据结构落在硬件缓存的不同行,提高缓存命中率
点击查看代码
// 获取当前CPU ID并禁用抢占
int cpu = get_cpu(); 
// 在这里执行需要在当前CPU上运行的代码
// 重新启用抢占
put_cpu();

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/percpu.h>

MODULE_LICENSE("GPL");

//定义per cpu 变量
DEFINE_PER_CPU(int, counter);

static int __init test_hello_init(void)
{
	int num_cpus = num_online_cpus();
	int i = 0;
	int val;

	pr_info("Number of cpus available:%d\n", num_cpus);
	for (i = 0; i < num_cpus; i++) {
		int value = per_cpu(counter, i); //获取per cpu counter变量
		pr_info("Value of counter is %d at Processor:%d\n", value, i);
	}

	get_cpu_var(counter) = 10; //获取per cpu counter变量
	pr_info("Printing counter value of all processor after updating current processor:%d\n",
			smp_processor_id());
	put_cpu_var(counter);

	for (i = 0; i < num_cpus; i++) {
		int value = per_cpu(counter, i);
		pr_info("Value of counter is %d at Processor:%d\n", value, i);
        }

    return -1;
}

static void __exit test_hello_exit(void)
{
    pr_info("%s: In exit\n", __func__);
}

module_init(test_hello_init);
module_exit(test_hello_exit);

Dynamically allocated per-CPU variables

点击查看代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/percpu.h>

MODULE_LICENSE("GPL");

static int *dynamic_counter;

static int __init test_hello_init(void)
{
	int cpu = get_cpu();
	int i;
	dynamic_counter = alloc_percpu(int);
	pr_info("cpu:%d\n", cpu);
	*per_cpu_ptr(dynamic_counter, cpu) = 1000;
	put_cpu();
	for (i = 0; i < num_online_cpus(); i++)
		pr_info("cpu:%d\tcounter:%d\n",i, *per_cpu_ptr(dynamic_counter, i));
	free_percpu(dynamic_counter);
	return -1;
}

static void __exit test_hello_exit(void)
{
    pr_info("%s: In exit\n", __func__);
}

module_init(test_hello_init);
module_exit(test_hello_exit);

只能保护多个cpu并发
posted @ 2025-09-20 22:29  fangshuo  阅读(6)  评论(0)    收藏  举报