本文是真对《vfp 原生bug导致开机概率定屏问题》cpu down时进程上下文的保存与恢复流程做简要分析,以便更好的理解这个问题。
在分析上下文切换流程前,先要对thread_info结构有个简单的认识,可以参见http://blog.jobbole.com/107656/ 博客。下面是arm体系中thread_info结构的定义
kernel/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 */ mm_segment_t addr_limit; /* address limit */ struct task_struct *task; /* main task structure */ __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ struct cpu_context_save cpu_context; /* cpu context */ __u32 syscall; /* syscall number */ __u8 used_cp[16]; /* thread used copro */ unsigned long tp_value[2]; /* TLS registers */ #ifdef CONFIG_CRUNCH struct crunch_state crunchstate; #endif union fp_state fpstate __attribute__((aligned(8))); union vfp_state vfpstate; #ifdef CONFIG_ARM_THUMBEE unsigned long thumbee_state; /* ThumbEE Handler Base register */ #endif }; ############################################### union vfp_state { struct vfp_hard_struct hard;}; ############################################### |
/*
* VFP storage area has:
* - FPEXC, FPSCR, FPINST and FPINST2.
* - 16 or 32 double precision data registers
* - an implementation-dependent word of state for FLDMX/FSTMX (pre-ARMv6)
*
* FPEXC will always be non-zero once the VFP has been used in this process.
*/
struct vfp_hard_struct {
#ifdef CONFIG_VFPv3
__u64 fpregs[32];
#else
__u64 fpregs[16];
#endif
#if __LINUX_ARM_ARCH__ < 6
__u32 fpmx_state;
#endif
__u32 fpexc;
__u32 fpscr;
/*
* VFP implementation specific state
*/
__u32 fpinst;
__u32 fpinst2;
#ifdef CONFIG_SMP
__u32 cpu;
#endif
};
在看代码流程前我们先要明确两个概念,用户空间栈和内核栈,一个进程是分两个栈的,从用户空间切换到内核空间,使用的栈帧地址是不同的。用户栈是指向用户空间地址,内核栈指向内核地址。这两个栈的切换是进程由于中断或系统调用从用户态切换到内核态时进行栈的保存与恢复。vfp hotplug这个问题主要原因就是cpu拔核,间接引发上下文切换,切换过程中会