per cpu variable
per cpu变量可以export出来给其它模块使用
方法:
1.define per cpu variable
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; EXPORT_PER_CPU_SYMBOL(vm_event_states);
2.declare per cpu variable
在你需要使用这个per cpu变量的模块里declare它后即可在这个模块里使用它了
DECLARE_PER_CPU(struct vm_event_state, vm_event_states);
对struct类型per cpu变量里的field进行per cpu操作
4.19/mm/vmstat.c
#ifdef CONFIG_VM_EVENT_COUNTERS DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; EXPORT_PER_CPU_SYMBOL(vm_event_states);
include/linux/vmstat.h
struct vm_event_state { unsigned long event[NR_VM_EVENT_ITEMS]; }; DECLARE_PER_CPU(struct vm_event_state, vm_event_states); /* * vm counters are allowed to be racy. Use raw_cpu_ops to avoid the * local_irq_disable overhead. */ static inline void __count_vm_event(enum vm_event_item item) { raw_cpu_inc(vm_event_states.event[item]); } static inline void count_vm_event(enum vm_event_item item) { this_cpu_inc(vm_event_states.event[item]); } static inline void __count_vm_events(enum vm_event_item item, long delta) { raw_cpu_add(vm_event_states.event[item], delta); } static inline void count_vm_events(enum vm_event_item item, long delta) { this_cpu_add(vm_event_states.event[item], delta); }
以上面raw_cpu_inc()为例,它是基于vm_event_states.event[item]的地址加上__my_cpu_offset得到(this cpu)的地址,然后将这个地址上的数据(unsigned long型)加1。
所以可以看到per cpu变量是vm_event_states,这个per cpu变量是struct类型的,但是还是可以对这个struct里的field进行per cpu操作:
#ifndef arch_raw_cpu_ptr #define arch_raw_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, __my_cpu_offset) #endif