无法理解“当前"状态如何宏适用于x86体系结构 [英] Unable to understand how the "current" macro works for x86 architecture
问题描述
我试图了解current
宏的工作原理,因此开始浏览Linux内核源代码版本4.19.试图了解x86体系结构
I was trying to understand how current
macro works, so started browsing the Linux Kernel source code version 4.19. Was trying to understand for x86 architecture
include/asm-generic/current.h:8
include/asm-generic/current.h:8
#define get_current() (current_thread_info()->task)
#define current get_current()
然后我试图找到current_thread_info()的定义.
I then tried to find the definition of current_thread_info().
include/linux/thread_info.h
include/linux/thread_info.h
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
* definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
* including <asm/current.h> can cause a circular dependency on some platforms.
*/
#include <asm/current.h>
#define current_thread_info() ((struct thread_info *)current)
#endif
然后我尝试查找当前定义
I then tried to find current definition
arch/x86/include/asm/current.h
arch/x86/include/asm/current.h
DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
return this_cpu_read_stable(current_task);
}
#define current get_current()
get_current()再次返回struct task_struct,为什么我们将其类型转换为current_thread_info()中的struct thread_info.
get_current() is again returning struct task_struct, why are we typecasting it to struct thread_info in current_thread_info().
能请您解释一下如何执行电流.我读到它放在内核堆栈顶部或底部的某个地方
Can you please explain how current gets executed. I read somewhere that it is placed at the top or bottom of the kernel stack
推荐答案
用于强制转换指针-struct thread_info thread_info
是
For casting the pointer - the struct thread_info thread_info
is the first member of the struct task_struct
:
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* For reasons of header soup (see current_thread_info()), this
* must be the first element of task_struct.
*/
struct thread_info thread_info;
#endif
强制转换是合法的-我们将返回一个指向struct
的第一个成员的指针.它可能使用类似的¤t->thread_info
,但是如果struct task_struct
的定义在某些情况下是 opaque (即它是不完整的类型),则无法使用!
The cast is legal - we're returning a pointer to the first member of a struct
. It could have similarly used ¤t->thread_info
but that cannot be used if the definition of struct task_struct
is opaque in some contexts (i.e. it is an incomplete type)!
关于DECLARE_PER_CPU
东西的工作方式,这要视情况而定.您过去所学的内容可能不再适用于此.使用特殊宏可以读取和更新用DECLARE_PER_CPU
声明的变量.其他
这是因为在x86上,读取是通过特殊的段寄存器进行的.然后,其他CPU架构必须使用某些完全不同的方法来访问每CPU值.
As for how the DECLARE_PER_CPU
stuff works, that depends. What you have learnt in the past might not apply here any more. The variables declared with DECLARE_PER_CPU
are read and updated using special macros. Other
This is because on x86 the reads happen through a special segment register. Other CPU architectures must then use some completely different means of accessing per-cpu values.
通常,应使用this_cpu_read
读取per-cpu变量,这不允许GCC以任何方式缓存它,但是当前线程信息是一个例外,因为当前线程始终在当前线程中运行,而不管CPU是什么它开着.来自 arch/x86/include/asm/percpu.h
:
Ordinarily the per-cpu variables should be read using this_cpu_read
which doesn't allow GCC to cache it in any way, but current thread info is an exception since the current thread always runs in the current thread no matter what CPU it is on. From arch/x86/include/asm/percpu.h
:
/*
* this_cpu_read() makes gcc load the percpu variable every time it is
* accessed while this_cpu_read_stable() allows the value to be cached.
* this_cpu_read_stable() is more efficient and can be used if its value
* is guaranteed to be valid across cpus. The current users include
* get_current() and get_thread_info() both of which are actually
* per-thread variables implemented as per-cpu variables and thus
* stable for the duration of the respective task.
*/
这篇关于无法理解“当前"状态如何宏适用于x86体系结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!