powerpc fptask issue again
Till Straumann
strauman at SLAC.Stanford.EDU
Fri Apr 19 21:38:28 UTC 2002
Joel.
Sorry for the delay - we had networking problems...
Joel Sherrill wrote:
> Till Straumann wrote:
> >
> > Joel Sherrill wrote:
> >
> > > Till Straumann wrote:
> > > >
> > > > Hi.
> > > >
> > > > I'm sure this does not appear on this list for the first time.
> > > >
> > > > Can somebody explain to me why enabling deferred/lazy
> > > > floating point context save/restore (as is currently the default
> > > > for the Powerpc/new_exception_processing) and NOT
> > > > disabling MSR_FP for integer tasks (current behavior)
> > > > is assumed to be safe ???
> > >
> > > In general, if you have the capability to disable the
> > > FPU for integer only tasks, you should do it. You have
> > > to be careful to honor this in interrupts and context
> > > switches.
> > >
> >
> > I couldn't agree more. However, currently the FPU (on ppc)
> > is _never_ disabled. There is a comment stating that it is
> > left enabled because newlibc vfprintf (around '97) behaved
> > just like my task 'B', i.e. it is not modifying but merely
> > saving/restoring FP regs.
>
> And in the old exceptions port (from memory), all tasks are FP
> because of this.
>
> > My point is:
> >
> > 1) _only_ do lazy FPcontext save/restore if you
> > switch the FPU off for integer tasks otherwise
> > there is a risk of corruption that goes undetected.
>
> On lower end CPUs, the benefits are relatively greater
> from integer only tasks and the odds of being able to
> disable an FPU are low. On the PPC or any other CPU
> with FPU disable, I agree totally.
>
> > 2) if there are integer tasks who push/pop the FPregs
> > without modifying them, you can leave the FPU enabled
> > _but_ FPContext must be saved/restored at every context
> > switch.
>
> Exactly and this is why the old exceptions model declared
> that all tasks were FP.
>
> > Note that powerpc-rtems currently violates 1), i.e. it uses
> > lazy FPsave/restore but does not disable the FPU for integer
> > tasks!
>
> Yes.
>
> > One more interesting thing: if you do 1) you will discover that
> > threaddispatch.c is actually incorrect. PR/patch is in preparation
>
> What is the problem? I think you might be referring to the
> same thing Greg Menke did. The FP context save/restore code
> must protect itself and enable the FPU.
right
> But if there is
> an easy way to get this as a side-effect, be our guest. :)
>
If I don't oversee something, it is easy - just make sure you
do the FPsave/restore always in the context of the FP task,
see the diff.
-- Till
-------------- next part --------------
This patch addresses the following FP context switching issues:
- if CPU_USE_DEFERRED_FP_SWITCH, make sure (on the PowerPC only)
that nonFP tasks have the FPU disabled.
- make CPU_USE_DEFERRED_FP_SWITCH FALSE the default
- fix context switching: to FPsave and FPrestore in the context
of the FP task itself.
Author: Till Straumann <strauman at slac.stanford.edu>, 4/19/2002
Index: c/src/exec/score/src/threaddispatch.c
===================================================================
RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/exec/score/src/threaddispatch.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 threaddispatch.c
*** threaddispatch.c 2001/12/14 22:49:52 1.1.1.1
--- threaddispatch.c 2002/04/19 21:16:20
***************
*** 93,115 ****
*/
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
! if ( (heir->fp_context != NULL) && !_Thread_Is_allocated_fp( heir ) ) {
if ( _Thread_Allocated_fp != NULL )
_Context_Save_fp( &_Thread_Allocated_fp->fp_context );
! _Context_Restore_fp( &heir->fp_context );
! _Thread_Allocated_fp = heir;
}
#else
if ( executing->fp_context != NULL )
! _Context_Save_fp( &executing->fp_context );
!
! if ( heir->fp_context != NULL )
! _Context_Restore_fp( &heir->fp_context );
#endif
#endif
-
- _Context_Switch( &executing->Registers, &heir->Registers );
executing = _Thread_Executing;
--- 93,119 ----
*/
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ #if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
+ if ( executing->fp_context != NULL )
+ _Context_Save_fp( &executing->fp_context );
+ #endif
+ #endif
+
+ _Context_Switch( &executing->Registers, &heir->Registers );
+
+ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
! if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) {
if ( _Thread_Allocated_fp != NULL )
_Context_Save_fp( &_Thread_Allocated_fp->fp_context );
! _Context_Restore_fp( &executing->fp_context );
! _Thread_Allocated_fp = executing;
}
#else
if ( executing->fp_context != NULL )
! _Context_Restore_fp( &executing->fp_context );
#endif
#endif
executing = _Thread_Executing;
Index: c/src/lib/libbsp/powerpc/support//new_exception_processing/cpu.c
===================================================================
RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libbsp/powerpc/support/new_exception_processing/cpu.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 cpu.c
*** cpu.c 2001/12/15 00:14:11 1.1.1.1
--- cpu.c 2002/04/19 21:29:25
***************
*** 93,100 ****
* time (7 July 1997), this restructuring is not being done.
*/
! /*if ( is_fp ) */
the_context->msr |= PPC_MSR_FP;
the_context->pc = (unsigned32)entry_point;
}
--- 93,112 ----
* time (7 July 1997), this restructuring is not being done.
*/
! /* Till Straumann: For deferred FPContext save/restore, make sure integer
! * tasks have no FPU access in order to catch violations.
! * Otherwise, the FP registers may be corrupted.
! * Since we set the_contex->msr using our current MSR,
! * we must make sure MSR_FP is off if (!is_fp)...
! */
! #if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE)
! if ( is_fp )
! #endif
the_context->msr |= PPC_MSR_FP;
+ #if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE)
+ else
+ the_context->msr &= ~PPC_MSR_FP;
+ #endif
the_context->pc = (unsigned32)entry_point;
}
Index: c/src/lib/libbsp/powerpc/support//new_exception_processing/rtems/score/cpu.h
===================================================================
RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 cpu.h
*** cpu.h 2001/12/15 00:14:11 1.1.1.1
--- cpu.h 2002/04/19 21:29:25
***************
*** 229,240 ****
* until a context switch is made to another, different FP task.
* Thus in a system with only one FP task, the FP context will never
* be saved or restored.
*/
/*
* ACB Note: This could make debugging tricky..
*/
! #define CPU_USE_DEFERRED_FP_SWITCH TRUE
/*
* Does this port provide a CPU dependent IDLE task implementation?
--- 229,247 ----
* until a context switch is made to another, different FP task.
* Thus in a system with only one FP task, the FP context will never
* be saved or restored.
+ *
+ * Note, however that compilers may use floating point registers/
+ * instructions for optimization or they may save/restore FP registers
+ * on the stack. You must not use deferred switching in these cases
+ * and on the PowerPC attempting to do so will raise a "FP unavailable"
+ * exception.
*/
/*
* ACB Note: This could make debugging tricky..
*/
! /* conservative setting; probably doesn't affect performance too much */
! #define CPU_USE_DEFERRED_FP_SWITCH FALSE
/*
* Does this port provide a CPU dependent IDLE task implementation?
More information about the users
mailing list