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.hDEFINE_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);                                             \

}))

 

目录
相关文章
|
1月前
|
缓存 Linux 开发者
Linux内核中的并发控制机制
本文深入探讨了Linux操作系统中用于管理多线程和进程的并发控制的关键技术,包括原子操作、锁机制、自旋锁、互斥量以及信号量。通过详细分析这些技术的原理和应用,旨在为读者提供一个关于如何有效利用Linux内核提供的并发控制工具以优化系统性能和稳定性的综合视角。
|
13天前
|
存储 编译器 Linux
动态链接的魔法:Linux下动态链接库机制探讨
本文将深入探讨Linux系统中的动态链接库机制,这其中包括但不限于全局符号介入、延迟绑定以及地址无关代码等内容。
187 19
|
21天前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
4月前
|
缓存 监控 Linux
在Linux中,如何看当前系统有几颗物理CPU和每颗CPU的核数?
在Linux中,如何看当前系统有几颗物理CPU和每颗CPU的核数?
|
25天前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
1月前
|
缓存 监控 Linux
|
1月前
|
算法 Linux 开发者
Linux内核中的锁机制:保障并发控制的艺术####
本文深入探讨了Linux操作系统内核中实现的多种锁机制,包括自旋锁、互斥锁、读写锁等,旨在揭示这些同步原语如何高效地解决资源竞争问题,保证系统的稳定性和性能。通过分析不同锁机制的工作原理及应用场景,本文为开发者提供了在高并发环境下进行有效并发控制的实用指南。 ####
|
1月前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
46 5
|
1月前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
62 6
|
1月前
|
消息中间件 存储 Linux