我正在研究linux内核,有时候我不了解内核开发人员在特定代码中需要什么。所以我在内核中读取计时器,并使用struct timer_list变量创建计时器,该变量包含每个CPU指针。我试图了解这个每个cpu变量好一点,所以我在linux kerenl中查看,如何创建。 所以我从内核中采用了不同的结构,列出了#defines来整合东西,看到一幅清晰的图片,实际发生了什么。
从这一切开始的结构
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct list_head entry;
unsigned long expires;
struct tvec_base *base;//pointer to per cpu variable, so I checked what is inside
void (*function)(unsigned long);
unsigned long data;
int slack;
#ifdef CONFIG_TIMER_STATS
int start_pid;
void *start_site;
char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
基指针是这样的结构
struct tvec_base {
spinlock_t lock;
struct timer_list *running_timer;
unsigned long timer_jiffies;
unsigned long next_timer;
unsigned long active_timers;
struct tvec_root tv1;
struct tvec tv2;
struct tvec tv3;
struct tvec tv4;
struct tvec tv5;
} ____cacheline_aligned;//??why such a name __cacheline_aligned
struct tvec_base boot_tvec_bases;
EXPORT_SYMBOL(boot_tvec_bases);
static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;//from here I am a little puzzeled as the way things are written been assigned.
DEFINE PER CPU是如此简单的#define来理解,希望它是
#define DEFINE_PER_CPU(type, name) \
DEFINE_PER_CPU_SECTION(type, name, "")
#define DEFINE_PER_CPU_SECTION(type, name, sec) \//?? what exactly we achieve here
__PCPU_DUMMY_ATTRS char __pcpu_scope_##name; \
extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \
__PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \
__PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES __weak \
__typeof__(type) name
#define __PCPU_DUMMY_ATTRS \
__attribute__((section(".discard"), unused))//i think it is a section in map file, but already kernel is built and I am builing a timer module, so what does it do?
如果有人在linux内部有良好的经验,你可以指出我正确的方向。
一些具体的问题如果得到回答可以让我理解整个事情,
`static DEFINE_PER_CPU(struct tvec_base *,tvec_bases)=& boot_tvec_bases;
1)这是什么意思?这个地址'& boot_tvec_bases'去哪儿了?
2)为什么名称____cacheline_aligned;
choosen。它有什么特别之处吗?
3)什么是
#define DEFINE_PER_CPU_SECTION(type, name, sec)
这里?
答案 0 :(得分:0)
____ cacheline_aligned指示编译器在对应于L1开头的地址处实例化结构或变量 高速缓存行,用于特定的体系结构,即,它是L1 缓存行对齐。 ____cacheline_aligned_in_smp类似,但是 实际上L1缓存行只在内核在SMP中编译时才对齐 配置(即使用选项CONFIG_SMP)。这些定义在 file include / linux / cache.h
3。http://www.makelinux.net/ldd3/chp-8-sect-5
每个CPU变量是一个有趣的2.6内核功能。当你 创建一个每CPU变量,系统上的每个处理器都有自己的变量 该变量的副本。这可能看起来像是一件奇怪的事情 做,但它有其优点。访问每个CPU变量需要 (几乎)没有锁定,因为每个处理器都使用自己的副本。