网站开发转码手机,阳江网站建设,销售新品牌如何推广,如何做跨境电商需要哪些条件接前一篇文章#xff1a;Linux内核进程管理子系统有什么第五十五回 —— 进程主结构详解#xff08;51#xff09; 本文内容参考#xff1a;
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇#xff1a;第三部分 进程管理》—— 刘超
《…接前一篇文章Linux内核进程管理子系统有什么第五十五回 —— 进程主结构详解51 本文内容参考
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_infostruct thread_info内核态堆栈共用体stackvoid *进程的内核栈
1struct thread_info thread_info
Linux通过slab分配器分配task_struct结构这样能达到对象复用和缓存着色cache coloring的目的。在2.6版本以前的内核中各个进程的task_struct存放在其内核栈的尾端内核栈和task_struct一共占用2个连续的物理页。这样做是为了让那些寄存器较少的硬件体系结构如x86只要通过栈指针就能计算出它的位置从而避免使用额外的寄存器专门记录。
随着内核的不断发展task_struct结构的内容越来越多其所占的空间也就越来越大导致内核栈不断被压缩。为了解决这一问题新版本内核引入了thread_info结构替代task_struct结构利用其中的成员struct task_struct *task指向task_struct结构实例。thread_info结构相对固定因此这样做实际上是将task_struct结构独立出来不再受task_struct结构不断增长的影响了。由于现在用slab分配器动态生成task struct因此只需要在栈底向下增长的栈或栈顶向上增长的栈创建一个新的结构struct thread_info。
struct thread_info这个结构体是体系结构相关的。
在x86架构上其定义在文件arch/x86/include/asm/thread_info.h中源码如下
struct thread_info {unsigned long flags; /* low level flags */unsigned long syscall_work; /* SYSCALL_WORK_ flags */u32 status; /* thread synchronous flags */
#ifdef CONFIG_SMPu32 cpu; /* current CPU */
#endif
};
在arm架构上其定义在文件arch/arm/include/asm/thread_info.h中源码如下
/** low level task data that entry.S needs immediate access to.* __switch_to() assumes cpu_context follows immediately after cpu_domain.*/
struct thread_info {unsigned long flags; /* low level flags */int preempt_count; /* 0 preemptable, 0 bug */__u32 cpu; /* cpu */__u32 cpu_domain; /* cpu domain */struct cpu_context_save cpu_context; /* cpu context */__u32 abi_syscall; /* ABI type and syscall nr */__u8 used_cp[16]; /* thread used copro */unsigned long tp_value[2]; /* TLS registers */union fp_state fpstate __attribute__((aligned(8)));union vfp_state vfpstate;
#ifdef CONFIG_ARM_THUMBEEunsigned long thumbee_state; /* ThumbEE Handler Base register */
#endif
};
在mips架构上其定义在文件arch/mips/include/asm/thread_info.h中源码如下
/** low level task data that entry.S needs immediate access to* - this struct should fit entirely inside of one cache line* - this struct shares the supervisor stack pages* - if the contents of this structure are changed, the assembly constants* must also be changed*/
struct thread_info {struct task_struct *task; /* main task structure */unsigned long flags; /* low level flags */unsigned long tp_value; /* thread pointer */__u32 cpu; /* current CPU */int preempt_count; /* 0 preemptable, 0 BUG */struct pt_regs *regs;long syscall; /* syscall number */
};
在riscv架构上其定义在文件arch/riscv/include/asm/thread_info.h中源码如下
/** low level task data that entry.S needs immediate access to* - this struct should fit entirely inside of one cache line* - if the members of this struct changes, the assembly constants* in asm-offsets.c must be updated accordingly* - thread_info is included in task_struct at an offset of 0. This means that* tp points to both thread_info and task_struct.*/
struct thread_info {unsigned long flags; /* low level flags */int preempt_count; /* 0preemptible, 0BUG *//** These stack pointers are overwritten on every system call or* exception. SP is also saved to the stack it can be recovered when* overwritten.*/long kernel_sp; /* Kernel stack pointer */long user_sp; /* User stack pointer */int cpu;
};
在loongarch架构上其定义在文件arch/loongarch/include/asm/thread_info.h中源码如下
/** low level task data that entry.S needs immediate access to* - this struct should fit entirely inside of one cache line* - this struct shares the supervisor stack pages* - if the contents of this structure are changed, the assembly constants* must also be changed*/
struct thread_info {struct task_struct *task; /* main task structure */unsigned long flags; /* low level flags */unsigned long tp_value; /* thread pointer */__u32 cpu; /* current CPU */int preempt_count; /* 0 preemptible, 0 BUG */struct pt_regs *regs;unsigned long syscall; /* syscall number */unsigned long syscall_work; /* SYSCALL_WORK_ flags */
};
这样看来在更新版本的内核中struct thread_info中也并不是都显式地通过成员指向task_struct结构实例了只有mips和loongarch的struct thread_info定义中还有struct task_struct *task即指向struct task_struct的指针。
关于struct thread_info thread_info的更多介绍和讲解请看下回。