Linux内核进程管理子系统有什么第五十七回 —— 进程主结构详解(53)
接前一篇文章:Linux内核进程管理子系统有什么第五十六回 —— 进程主结构详解(52)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
特此致谢!
进程管理核心结构 —— task_struct
11. stack和thread_info
一目了然,包括以下两个:
#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
……void *stack;
这两个字段的描述如下:
字段 | 类型 | 描述 |
---|---|---|
thread_info | struct thread_info | 内核态堆栈共用体 |
stack | void * | 进程的内核栈 |
(1)struct thread_info thread_info
上一回对于struct thread_info thread_info进行了部分介绍,由于其历史演变过程较为复杂曲折,本回继续对它进行讲解。
旧版本内核中,thread_info对象存在于内核栈中。也就是说,对于每个进程,Linux都将thread_info与进程的内核态堆栈存放在一起,在一个单独为进程分配的内存区域中。这块内存区域通常是8192字节(占两个页框),起始地址必须是8192的整数倍(内核栈默认情况下大小为8KB,8KB的开始(低地址)存放的是thread_info对象)。
由于这个内存区域同时保存了thread_info和stack,因此这两个数据结构被定义在了一个共用体(union thread_union)中,由alloc_thread_info_node函数分配内存空间(该函数在此新版Linux内核中已经没有了,取而代之的是alloc_task_struct_node函数和alloc_thread_stack_node函数)。
union thread_union的定义也在include/linux/sched.h中,如下:
union thread_union {
#ifndef CONFIG_ARCH_TASK_STRUCT_ON_STACKstruct task_struct task;
#endif
#ifndef CONFIG_THREAD_INFO_IN_TASKstruct thread_info thread_info;
#endifunsigned long stack[THREAD_SIZE/sizeof(long)];
};
而在新版本的内核中,在CONFIG_THREAD_INFO_IN_TASK为真的情况下,thread_info变成了struct task_struct的一个字段:
在x86平台上,该宏(CONFIG_THREAD_INFO_IN_TASK)默认为真。因此实际上,x86平台上已经将thread_info的作用弱化了。这也和上一回所讲的“在更新版本的内核中,struct thread_info中也并不是都(显式)地通过成员指向task_struct结构实例了”相对应起来了。
至此,对于struct thread_info thread_info的讲解就暂告一段落了,下一回开始讲解void *stack字段。