Dynamic switching of co-processor context
Till Straumann
strauman at slac.stanford.edu
Mon Oct 19 14:30:56 UTC 2009
I think this is a nice idea but there may be users who prefer
the simpler and more deterministic approach of just always
switching the co-processor context.
If we go with dynamic switching then there could be a slightly
different strategy which might (I haven't thought of this deeply)
eliminate all the issues with keeping MSR state consistent.
a) Keep existing lazy-context switching code. If -- at context-switch
time -- the saved MSR indicates that the 'heir' task needs the
coprocessor then change ownership.
b) If a task incurs an exception because it tries to use the co-processor
but it is disabled then let the exception handler change ownership
and enable the co-processor for the task.
Note that the co-processor-enable bit is never changed for a non-executing
task.
This strategy seems reasonable under the assumption that a task
who uses the co-processor once is likely to use it in the future again.
For tasks that 'always' use the co-processor it eliminates the need
for handling an exception every time the task is given the CPU.
-- Till
Sebastian Huber wrote:
> Hi!
>
> This discussion focus on the PowerPC, but other architectures may be similar.
>
> Suppose you have a co-processor (floating-point, digital signal processing,
> vector unit) which only few tasks need (more than one) or that is seldom used
> by tasks (printf() for example), then it is desirable to remove the
> co-processor context switching from the normal context switch. The separation
> of the context switching results in a reduced context switch time. This
> reduces also the worst case time of disabled interrupts (= worst case interrupt
> latency WCIL). On the PowerPC the WCIL is very likely this sequence:
>
> 1. An interrupt handler finishes its work
> 2. External exceptions are disabled at the end of interrupt processing
> 3. First half of the exception epilogue
> 4. A context switch is necessary
> 5. Context switch to a task that was suspended by an interrupt
> 6. Second half of the exception epilogue
> 7. Return from exception
> 8. External exceptions are enabled again
>
> In total we have "maximum context switch time" + "exception epilogue time" = WCIL.
> The co-processor context switching will be done in a task context and thus does
> not affect higher priority tasks.
>
> It will be assumed that you can enable or disable the co-processor availability
> in a machine state register. At most one task may be the owner of the
> co-processor context. If another task needs the co-processor the ownership has
> to change. This requires saving of the context for the previous owner and
> restoring of the context for the new owner. The tasks not owning the
> co-processor trigger an exception if they use a co-processor facility. The
> exception handler hands over the ownership. This leads to the problem that the
> machine state of a not executing task has to be modified. Typically the
> sequence to modify the machine state is
>
> 1. Move the machine state register into a general purpose register.
> 2. Modify the value in the general purpose register.
> 3. Write the modfied value back into the machine state register.
>
> Here we have the problem that this sequence may be interrupted at any time. If
> a context switch happens during 2. and 3. and the co-processor ownership
> changes in the meantime, then the task overwrites the updated machine state
> directly after it resumes execution and this may leads to a corrupted
> co-processor context. On the PowerPC such a sequence is used to disable the
> interrupts, so we need a workaround.
>
> Variant 1:
> Use a special instruction to disable interrupts atomically. Not
> every variant may have this.
>
> Variant 2:
> Disable the co-processor availability in every modified machine
> state register value. Example:
>
> msr = read_from_msr()
> modify(msr)
> disable_co_processor(msr)
> write_to_msr(msr)
> synchronize()
>
> The PowerPC needs a synchronization instruction after the move to MSR if
> the FP bit is switched off.
>
> This variant is easy. The drawback is that the co-processor may be
> switched off more often than it is needed.
>
> Variant 3:
> Check the co-processor ownership after the machine state register
> update and disable the co-processor availability if required. Example:
>
> executing = _Thread_Executing
> msr = read_from_msr()
> modify(msr)
> write_to_msr(msr)
> if co_processor_owner != executing
> disable_co_processor(msr)
> write_to_msr(msr)
> synchronize()
>
> Each variant will result in a modified interrupt enable, flash, and disable
> code in the Cpukit. The user has to review its code for usages of the machine
> state register. The question is how to deal with this? We also need an
> exception handler. Currently on the PowerPC exception handlers are not
> available in the Cpukit. I converted most of the BSPs to use the shared
> exception code (only mpc5xx is missing) and will commit this in the near
> future. So it is feasible that we have the PowerPC exception code back in the
> Cpukit some time.
>
> I would be glad if you send me some comments to this.
>
>
More information about the users
mailing list