Linux per-cpu机制
Linux操作系統,特別是針對SMP或者NUMA架構的多CPU系統的時候,描述每個CPU的私有數據的時候,Linux操作系統提供了per_cpu機制。?
1.1???? 定義
per_cpu機制就是讓每個CPU都有自己的私有數據段,便于保護與訪問。
相關宏定義在include/linux/percpu-defs.h文件中:
/*?????
?* Normal declaration and definition macros.
?*/
#define DECLARE_PER_CPU_SECTION(type, name, sec)??????????????????????? \
??????? extern __PCPU_ATTRS(sec) __typeof__(type) name
?
#define DEFINE_PER_CPU_SECTION(type, name, sec)???????????????????????? \
??????? __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES??????????????????????? \
??????? __typeof__(type) name
#endif
?
/*
?* Variant on the per-CPU variable declaration/definition theme used for
?* ordinary per-CPU variables.
?*/
#define DECLARE_PER_CPU(type, name)???????????????????????????????????? \
??????? DECLARE_PER_CPU_SECTION(type, name, "")
?
#define DEFINE_PER_CPU(type, name)????????????????????????????????????? \
??????? DEFINE_PER_CPU_SECTION(type, name, "")
include/linux/percpu-defs.h文件
#define __PCPU_ATTRS(sec)?????????????????????????????????????????????? \
??????? __percpu __attribute__((section(PER_CPU_BASE_SECTION sec)))???? \
??????? PER_CPU_ATTRIBUTES
這個__PCPU_ATTRS是每個CPU變量聲明和定義的最基本實現。總之就是創建CPU的一個私有變量。其中#define PER_CPU_BASE_SECTION ".data..percpu"定義其存放的數據段,定義在arch/ia64/include/asm/percpu.h文件中。
1.2???? 示例
例如定義描述每個IA64CPU信息的數據結構變量ia64_cpu_info, 在文件
arch/ia64/include/asm/processor.h,DEFINE_PER_CPU,定義這種私有數據,放在特定的數據段中。
DECLARE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
在文件arch/ia64/include/asm/processor.h中,定義了結構體cpuinfo_ia64。其中定義了CPU類型,硬件BUG標志, CPU狀態等。
struct cpuinfo_ia64 {
??????? unsigned int softirq_pending;??
??????? unsigned long itm_delta;??????? /* # of clock cycles between clock ticks */
??? ????unsigned long itm_next;???????? /* interval timer mask value to use for next clock tick */
??????? unsigned long nsec_per_cyc;???? /* (1000000000<<IA64_NSEC_PER_CYC_SHIFT)/itc_freq */
??????? unsigned long unimpl_va_mask;?? /* mask of unimplemented virtual address bits (from PAL) */
??????? unsigned long unimpl_pa_mask;?? /* mask of unimplemented physical address bits (from PAL) */
??????? unsigned long itc_freq;???????? /* frequency of ITC counter */
??????? unsigned long proc_freq;??????? /* frequency of processor */
??????? unsigned long cyc_per_usec;???? /* itc_freq/1000000 */
??????? unsigned long ptce_base;
??????? unsigned int ptce_count[2];
??????? unsigned int ptce_stride[2];
??????? struct task_struct *ksoftirqd;? /* kernel softirq daemon for this CPU */
?
#ifdef CONFIG_SMP
??????? unsigned long loops_per_jiffy;
??????? int cpu;
??????? unsigned int socket_id; /* physical processor socket id */
??????? unsigned short core_id; /* core id */
??????? unsigned short thread_id; /* thread id */
????? ??unsigned short num_log; /* Total number of logical processors on
???????????????????????????????? * this socket that were successfully booted */
??????? unsigned char cores_per_socket; /* Cores per processor socket */
??????? unsigned char threads_per_core; /* Threads per core */
#endif?
???????
??????? /* CPUID-derived information: */
??????? unsigned long ppn;
??????? unsigned long features;
??????? unsigned char number;
??????? unsigned char revision;
??????? unsigned char model;
??????? unsigned char family;
??????? unsigned char archrev;
??????? char vendor[16];
??????? char *model_name;
?
#ifdef CONFIG_NUMA
??????? struct ia64_node_data *node_data;
#endif
};
1.3???? 初始化
在start_kernel函數中調用執行函數setup_per_cpu_areas( ),其會將.data.percpu中的數據拷貝到每個CPU的數據段中,每個CPU一份。?其中CPU n 對應的專有數據區的首地址為__per_cpu_offset[n]。?
1.4???? 讀取變量
在不同的內核版本中,略有差異,這里取的是最新的2018/3/19日的主線版本中代碼。include/linux/percpu-defs.h
#define get_cpu_var(var)??????????????????????????????????????????????? \
(*({?????????????????????????????????????????????????????????? ?????????\
??????? preempt_disable();????????????????????????????????????????????? \
??????? this_cpu_ptr(&var);???????????????????????????????????????????? \
}))
?
總結
以上是生活随笔為你收集整理的Linux per-cpu机制的全部內容,希望文章能夠幫你解決所遇到的問題。

- 上一篇: css优先级和权重问题
- 下一篇: yy网名大全霸气113个