svn commit: r270850 - in head/sys: i386/i386 i386/include i386/isa x86/acpica
Konstantin Belousov
kostikbel at gmail.com
Sat Aug 30 19:58:16 UTC 2014
On Sat, Aug 30, 2014 at 05:48:38PM +0000, John Baldwin wrote:
> Author: jhb
> Date: Sat Aug 30 17:48:38 2014
> New Revision: 270850
> URL: http://svnweb.freebsd.org/changeset/base/270850
>
> Log:
> Save and restore FPU state across suspend and resume. In earlier revisions
> of this patch, resumectx() called npxresume() directly, but that doesn't
> work because resumectx() runs with a non-standard %cs selector. Instead,
> all of the FPU suspend/resume handling is done in C.
>
> MFC after: 1 week
>
> Modified:
> head/sys/i386/i386/mp_machdep.c
> head/sys/i386/i386/swtch.s
> head/sys/i386/include/npx.h
> head/sys/i386/include/pcb.h
> head/sys/i386/isa/npx.c
> head/sys/x86/acpica/acpi_wakeup.c
>
> Modified: head/sys/i386/i386/mp_machdep.c
> ==============================================================================
> --- head/sys/i386/i386/mp_machdep.c Sat Aug 30 17:39:28 2014 (r270849)
> +++ head/sys/i386/i386/mp_machdep.c Sat Aug 30 17:48:38 2014 (r270850)
> @@ -1522,9 +1522,15 @@ cpususpend_handler(void)
>
> cpu = PCPU_GET(cpuid);
> if (savectx(susppcbs[cpu])) {
> +#ifdef DEV_NPX
> + npxsuspend(&suspcbs[cpu]->pcb_fpususpend);
> +#endif
> wbinvd();
> CPU_SET_ATOMIC(cpu, &suspended_cpus);
> } else {
> +#ifdef DEV_NPX
> + npxresume(&suspcbs[cpu]->pcb_fpususpend);
> +#endif
> pmap_init_pat();
> PCPU_SET(switchtime, 0);
> PCPU_SET(switchticks, ticks);
>
> Modified: head/sys/i386/i386/swtch.s
> ==============================================================================
> --- head/sys/i386/i386/swtch.s Sat Aug 30 17:39:28 2014 (r270849)
> +++ head/sys/i386/i386/swtch.s Sat Aug 30 17:48:38 2014 (r270850)
> @@ -416,45 +416,6 @@ ENTRY(savectx)
> sldt PCB_LDT(%ecx)
> str PCB_TR(%ecx)
>
> -#ifdef DEV_NPX
> - /*
> - * If fpcurthread == NULL, then the npx h/w state is irrelevant and the
> - * state had better already be in the pcb. This is true for forks
> - * but not for dumps (the old book-keeping with FP flags in the pcb
> - * always lost for dumps because the dump pcb has 0 flags).
> - *
> - * If fpcurthread != NULL, then we have to save the npx h/w state to
> - * fpcurthread's pcb and copy it to the requested pcb, or save to the
> - * requested pcb and reload. Copying is easier because we would
> - * have to handle h/w bugs for reloading. We used to lose the
> - * parent's npx state for forks by forgetting to reload.
> - */
> - pushfl
> - CLI
> - movl PCPU(FPCURTHREAD),%eax
> - testl %eax,%eax
> - je 1f
> -
> - pushl %ecx
> - movl TD_PCB(%eax),%eax
> - movl PCB_SAVEFPU(%eax),%eax
> - pushl %eax
> - pushl %eax
> - call npxsave
> - addl $4,%esp
> - popl %eax
> - popl %ecx
> -
> - pushl $PCB_SAVEFPU_SIZE
> - leal PCB_USERFPU(%ecx),%ecx
> - pushl %ecx
> - pushl %eax
> - call bcopy
> - addl $12,%esp
> -1:
> - popfl
> -#endif /* DEV_NPX */
> -
> movl $1,%eax
> ret
> END(savectx)
> @@ -519,10 +480,6 @@ ENTRY(resumectx)
> movl PCB_DR7(%ecx),%eax
> movl %eax,%dr7
>
> -#ifdef DEV_NPX
> - /* XXX FIX ME */
> -#endif
> -
> /* Restore other registers */
> movl PCB_EDI(%ecx),%edi
> movl PCB_ESI(%ecx),%esi
>
> Modified: head/sys/i386/include/npx.h
> ==============================================================================
> --- head/sys/i386/include/npx.h Sat Aug 30 17:39:28 2014 (r270849)
> +++ head/sys/i386/include/npx.h Sat Aug 30 17:48:38 2014 (r270850)
> @@ -53,8 +53,10 @@ void npxexit(struct thread *td);
> int npxformat(void);
> int npxgetregs(struct thread *td);
> void npxinit(void);
> +void npxresume(union savefpu *addr);
> void npxsave(union savefpu *addr);
> void npxsetregs(struct thread *td, union savefpu *addr);
> +void npxsuspend(union savefpu *addr);
> int npxtrap_x87(void);
> int npxtrap_sse(void);
> void npxuserinited(struct thread *);
>
> Modified: head/sys/i386/include/pcb.h
> ==============================================================================
> --- head/sys/i386/include/pcb.h Sat Aug 30 17:39:28 2014 (r270849)
> +++ head/sys/i386/include/pcb.h Sat Aug 30 17:48:38 2014 (r270850)
> @@ -90,6 +90,8 @@ struct pcb {
> struct region_descriptor pcb_idt;
> uint16_t pcb_ldt;
> uint16_t pcb_tr;
> +
> + union savefpu pcb_fpususpend;
> };
Now pcb consumes 512 bytes from each thread' kernel stack, which mostly
stay unused.
Amd64 only stores the pointer to the fpususpend context in pcb, and
acpu_wakeup() allocates the memory as needed. Even this is a waste of 8
bytes which are not needed for normal kernel operations.
Suspend FPU context, as well as amd64 MSRs should go out of pcb into
some per-cpu suspend data block.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20140830/0af516c2/attachment.sig>
More information about the svn-src-head
mailing list