context switch vs. signal delivery [was: Re: Accelerating user mode linux]
A message that is not in the archive (sent off-list or not yet received): 20020805163910.C7130@kushida.apsleyroad.org.suse.lists.linux.kernel
A message that is not in the archive (sent off-list or not yet received): Pine.LNX.4.44.0208050922570.1753-100000@home.transmeta.com.suse.lists.linux.kernel
Quoted 3 lines · Linus Torvalds
So it would have to be explicitly enabled with a
SA_NOFPSIGHANDLERflag or something.
That is all what my patch was doing. It added a SA_NOFP, with default to off.
Nothing about enabling it by default. The first hunk is an minor optimization.
-Andi
I attached the old patch for 2.4.9 for reference. If you think it is ok I can submit it for 2.5
arch/i386/kernel/signal.c renamed from arch/i386/kernel/signal.c-NOFP +14 -12
@@ -322,15 +322,15 @@static int setup_sigcontext (struct sigcontext *sc,struct _fpstate *fpstate, -struct pt_regs *regs,unsigned long mask) +struct pt_regs *regs,unsigned long mask,int fp) { -int tmp, err =0 ; +int err =0 ; +int tmp; - tmp =0 ; - __asm__("movl %%gs,%0" :"=r" (tmp):"0" (tmp)); - err |=__put_user (tmp, (unsigned int *)&sc->gs); - __asm__("movl %%fs,%0" :"=r" (tmp):"0" (tmp)); - err |=__put_user (tmp, (unsigned int *)&sc->fs); + __asm__("movl %%gs,%0" :"=r" (tmp)); + err |=__put_user (tmp &0xffff , (unsigned int *)&sc->gs); + __asm__("movl %%fs,%0" :"=r" (tmp)); + err |=__put_user (tmp &0xffff , (unsigned int *)&sc->fs); err |=__put_user (regs->xes, (unsigned int *)&sc->es); err |=__put_user (regs->xds, (unsigned int *)&sc->ds);
@@ -350,11 +350,12 @@ err |=__put_user (regs->esp, &sc->esp_at_signal); err |=__put_user (regs->xss, (unsigned int *)&sc->ss); - tmp =save_i387 (fpstate); -if (tmp <0 ) +if (fp) + fp =save_i387 (fpstate); +if (fp <0 ) err =1 ;else - err |=__put_user (tmp ? fpstate :NULL , &sc->fpstate); + err |=__put_user (fp ? fpstate :NULL , &sc->fpstate);/* non-iBCS2 extensions.. */ err |=__put_user (mask, &sc->oldmask);
@@ -410,7 +411,8 @@if (err) goto give_sigsegv; - err |=setup_sigcontext (&frame->sc, &frame->fpstate, regs, set->sig[0 ]); + err |=setup_sigcontext (&frame->sc, &frame->fpstate, regs, set->sig[0 ], + (ka->sa.sa_flags&SA_NOFP ));if (err) goto give_sigsegv;
@@ -491,7 +493,7 @@ &frame->uc.uc_stack.ss_flags); err |=__put_user (current->sas_ss_size, &frame->uc.uc_stack.ss_size); err |=setup_sigcontext (&frame->uc.uc_mcontext, &frame->fpstate, - regs, set->sig[0 ]); + regs, set->sig[0 ], !!(ka->sa.sa_flags&SA_NOFP )); err |=__copy_to_user (&frame->uc.uc_sigmask, set,sizeof (*set));if (err) goto give_sigsegv;
arch/i386/kernel/i387.c renamed from arch/i386/kernel/i387.c-NOFP +5 -5
@@ -323,11 +323,6 @@if ( !current->used_math )return 0 ; -/* This will cause a "finit" to be triggered by the next -* attempted FPU operation by the 'current' process. -*/ - current->used_math =0 ; -if (HAVE_HWFP ) {if ( cpu_has_fxsr ) {return save_i387_fxsave ( buf );
@@ -335,6 +330,11 @@return save_i387_fsave ( buf ); } }else { +/* This will cause a "finit" to be triggered by the next +* attempted FPU operation by the 'current' process. +*/ + current->used_math =0 ; +return save_i387_soft ( ¤t->thread.i387.soft, buf ); } }
include/asm-i386/signal.h renamed from include/asm-i386/signal.h-NOFP +2 -0
@@ -80,6 +80,7 @@* SA_RESETHAND clears the handler when the signal is delivered. * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. * SA_NODEFER prevents the current signal from being masked in the handler. +* SA_NOFP Don't save FP state. * * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single * Unix names RESETHAND and NODEFER respectively.
@@ -97,6 +98,7 @@#define SA_INTERRUPT 0x20000000/* dummy -- ignored */ #define SA_RESTORER 0x04000000 +#define SA_NOFP 0x02000000/* * sigaltstack controls
A couple of questions.
arch/i386/kernel/signal.c
Quoted 6 lines · Andi Kleen
arch/i386/kernel/signal.c renamed from arch/i386/kernel/signal.c-NOFP +3
-1+ err |=setup_sigcontext (&frame->sc, &frame->fpstate, regs, set->sig[0 ], + (ka->sa.sa_flags&SA_NOFP )); err |=setup_sigcontext (&frame->uc.uc_mcontext, &frame->fpstate, - regs, set->sig[0 ]); + regs, set->sig[0 ], !!(ka->sa.sa_flags&SA_NOFP ));
1: Why the inconsistency between the two ways the SA_NOFP flag is checked?
2: What happens when the user's signal handler decides it wants to save the FPU state itself (after all) and proceed with some FPU use. Will sigreturn restore the user-saved FPU state? Just curious.
-- Jamie
Quoted 9 lines · Jamie Lokier
arch/i386/kernel/signal.c
Quoted 6 lines · Andi Kleen
arch/i386/kernel/signal.c renamed from arch/i386/kernel/signal.c-NOFP +3
-1+ err |=setup_sigcontext (&frame->sc, &frame->fpstate, regs, set->sig[0 ], + (ka->sa.sa_flags&SA_NOFP )); err |=setup_sigcontext (&frame->uc.uc_mcontext, &frame->fpstate, - regs, set->sig[0 ]); + regs, set->sig[0 ], !!(ka->sa.sa_flags&SA_NOFP ));1: Why the inconsistency between the two ways the
SA_NOFPflag is checked?
I don't remember. Probably there was some reason in an earlier version of the code. The !! could be probably removed now.
Quoted 4 lines
2: What happens when the user's signal handler decides it wants to save the FPU state itself (after all) and proceed with some FPU use. Will sigreturn restore the user-saved FPU state? Just curious.
Nope it won't because there is no saved state. The previous context's FPU state will be silently corrupted.
-Andi
Quoted 6 lines · Andi Kleen
Quoted 3 lines
2: What happens when the user's signal handler decides it wants to save the FPU state itself (after all) and proceed with some FPU use. Will sigreturn restore the user-saved FPU state? Just curious.
Nope it won't because there is no saved state. The previous context's FPU state will be silently corrupted.
I meant if the user's signal handler decides it wants to save the FPU state directly into the signal context struct, after deciding to do that. Won't that work?
-- Jamie
Quoted 11 lines · Jamie Lokier
Quoted 6 lines · Andi Kleen
Quoted 3 lines
2: What happens when the user's signal handler decides it wants to save the FPU state itself (after all) and proceed with some FPU use. Will sigreturn restore the user-saved FPU state? Just curious.
Nope it won't because there is no saved state. The previous context's FPU state will be silently corrupted.
I meant if the user's signal handler decides it wants to save the FPU state directly into the signal context struct, after deciding to do that. Won't that work?
In theory yes. The space should be already allocated on the stack, it just has to be filled in.
-Andi