Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Aug 2014 22:58:09 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r270850 - in head/sys: i386/i386 i386/include i386/isa x86/acpica
Message-ID:  <20140830195809.GS2737@kib.kiev.ua>
In-Reply-To: <201408301748.s7UHmc6H059701@svn.freebsd.org>
References:  <201408301748.s7UHmc6H059701@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--zTZp/B23emyWiNs8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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
>=20
> Log:
>   Save and restore FPU state across suspend and resume.  In earlier revis=
ions
>   of this patch, resumectx() called npxresume() directly, but that doesn't
>   work because resumectx() runs with a non-standard %cs selector.  Instea=
d,
>   all of the FPU suspend/resume handling is done in C.
>  =20
>   MFC after:	1 week
>=20
> 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
>=20
> Modified: head/sys/i386/i386/mp_machdep.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- 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)
> =20
>  	cpu =3D 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);
>=20
> Modified: head/sys/i386/i386/swtch.s
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- 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)
> =20
> -#ifdef DEV_NPX
> -	/*
> -	 * If fpcurthread =3D=3D 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 !=3D 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
> =20
> -#ifdef DEV_NPX
> -	/* XXX FIX ME */
> -#endif
> -
>  	/* Restore other registers */
>  	movl	PCB_EDI(%ecx),%edi
>  	movl	PCB_ESI(%ecx),%esi
>=20
> Modified: head/sys/i386/include/npx.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- 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 *);
>=20
> Modified: head/sys/i386/include/pcb.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- 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.

--zTZp/B23emyWiNs8
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBAgAGBQJUAizQAAoJEJDCuSvBvK1Bj7oP/RtHm39XHxHaKoV7noWYzOD2
5S9dm6P3TQsWdjDZQ2TtYLroCiur3bRzTpR12FbSRLp7oL1jAhiWRFvvF/1gz9BU
tn86/4Z2KrXys+oGr0B2Ozi7kotVNM07CWpoQuELa3V3P9rNsb1Ko+AwwYgozeMZ
UZGL4yjZtBb9NnRhzDelAhwYpnOv56j0trKkwKAR5n/vZ3NYEVgjjVHu4rDIONUd
DMTHNUI/A2c0RtjqWI07wK1va44nZdEi7MKXv8u2VXWfrDjT6Yj7qku7Z3JfMacM
Vr5bakRVTaVtoKSqKaN0bL8y7MFMut8vJ4lf7obBxv21UAy9zjIboDkgZOKRpnsT
pWuD8Ns6CKrFXBdV9yoG0VAzuPPHpZrbZQlwX3OeVMbZkA3z1yFH+o/3ASwV3H+J
HfJMwNRUi25zXHhAC5sQkjPl7mL4gy3fBxLYIoBVrCu5NeGrz5OYemqXYm1u/6QO
eTFi8oKmXbM9dz5aainairqiGDWNlf1934XgI28RbSTqjs73HiwnqXQdIzxtjqS2
5ynLKGVKj+9PjuNj2kDRuLgHAB13dqX0H1Nr6OKK1S/4aa0S+aWH7p716QTL0O8p
L9dVasea6ZcZGSVtX6d6G5CrT2AJ9UbhBiwVWzN7H5IR6YJybouC3AO0lgnsUglZ
RrscyL8rfFfo+J3/2enb
=AjuO
-----END PGP SIGNATURE-----

--zTZp/B23emyWiNs8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140830195809.GS2737>