Linux内核中的current_thread_info()内联函数?

Posted

技术标签:

【中文标题】Linux内核中的current_thread_info()内联函数?【英文标题】:current_thread_info() inline function in Linux kernel? 【发布时间】:2017-08-27 20:09:18 【问题描述】:

我了解到 thread_info 存储在堆栈的底部。 在查看内核源代码时,我试图了解如何在 linux 内核中获取当前的 thread_info? 下面的源码是current_stack_pointer的13bits masking。

这是我无法得到的。 我不明白 thread_info 的位置发生了变化。 为什么是当前栈指针而不是栈的开始?

请帮助我理解这段代码

/* * 如何在 C 中获取当前堆栈指针 */ 注册 unsigned long current_stack_pointer asm ("sp"); /* * 如何从 C 中获取线程信息结构体 */ 静态内联结构 thread_info *current_thread_info(void) __attribute_const__; 静态内联结构 thread_info *current_thread_info(void) 返回(结构线程信息*) (current_stack_pointer & ~(THREAD_SIZE - 1));

【问题讨论】:

您使用的是什么架构?查找当前任务信息是依赖于架构的。这就是为什么有include/asm/current.h#define current。在 x86 上,我们有 #define current get_current(),但在 IBM s390 上,我们有 #define current ((struct task_struct *const)S390_lowcore.current_task)。所以,要小心地复制堆栈指针。 感谢您的评论。我正在使用 ARM 架构。 arch/arm/include/asm/thread_info.h 【参考方案1】:

为什么是当前栈指针而不是栈首?

您始终可以从平台特定的堆栈指针获取当前堆栈指针 注册,但你不能轻易找到堆栈的开始 - 它不在那里。

为此,您可以限制线程堆栈在内存中的位置:堆栈在内存中始终按其大小保持对齐,并且其大小始终是 2 的幂。这样,如果堆栈大小为 2^n,则将较低的 n 归零会为您提供堆栈的开始。

在现代 Linux 堆栈中通常为 8 KiB,并且始终以 8 KiB 对齐(其地址的低 13 位始终为 0)。将当前堆栈指针的低 13 位清零即可开始堆栈。

这正是表达式current_stack_pointer & ~(THREAD_SIZE - 1) 所做的:查找当前堆栈的开始。这并不意味着struct thread_info 会在内存中移动——它不会。即使堆栈指针发生变化,将低位清零也会在线程中为您提供相同的值。这就是为什么它也被标记为__attribute_const__,它扩展为__attribute__((const)),并告诉GCC这个函数总是返回相同的值,因此可以省略对该函数的多次调用。


PS:随着堆栈向下增长,“当前堆栈的开始”是指最低地址。

【讨论】:

以上是关于Linux内核中的current_thread_info()内联函数?的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核Linux 操作系统结构 ( Linux 内核在操作系统中的层级 | Linux 内核子系统及关系 | 进程调度 | 内存管理 | 虚拟文件系统 | 网络管理 | 进程间通信 )

Linux 内核编译 Linux 内核 ④ ( 打开 Linux 内核编译 菜单配置 |菜单配置中的光标移动与选中状态 | 保存配置 | 配置项帮助文档 )

Linux 内核中的 Device Mapper 机制

Linux 内核CPU 分类与状态 ( CPU 处理器分类 | 根据物理属性分类 SMTMCSoC | Linux 内核中 CPU 分类 | Linux 内核源码中的 CPU 状态源码 )

Linux 内核崩溃消息中的“代码”是啥?

Linux内核中的中断栈与内核栈的补充说明