Unexpected Behavior of Implementation of Priority Ceiling Protocol with INTC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Unexpected Behavior of Implementation of Priority Ceiling Protocol with INTC

555 Views
peter_vranken
Contributor IV

I've experienced a unexpected behavior applying the Priority Ceiling Protocol with the INTC of an MPC5643L device. The code pattern proposed in the reference manual is:


    GetResource:
    wrteei 0 # disable external interrupts to the Processor
    raise PRI # Write to CPR, cache inhibit, guarded
    mbar # flush out writes from store buffer
    wrteei 1 # enable external interrupts to the Processor
    isync # re-fetch Processor pipeline


    ReleaseResource:
    mbar # flush out writes from store buffer
    wrteei 0 # disable external interrupts to the Processor
    lower PRI # Write to CPR, cache inhibit, guarded
    wrteei 1 # enable external interrupts to the Processor


The mentioned unexpected behavior are occasional preemptions of ISR A, which is executing pattern GetResource, by ISR B after A raising the current priority. B had a higher priority than A but still not higher than the priority written into CPR by A.


The intention of the code patterns, mutual exclusion of A and B, or shaping a critical code section between GetResource and ReleaseResource, is not harmed by this effect; the preemption of A only happened immediately after the "wrteei 1" in pattern GetResource; the very first instruction of A inside the critical code section was executed only after completion of and return from the preempting B. (This is currently my explanation why we need the isync in the GetResource pattern.)


It looks as if interrupts, which are asserted in the short period between the "wrteei 0" and the "raise PRI" are routed by the INTC to the CPU and that the CPU sees such an interrupt even after the update of CPR so that it handles the interrupt immediately after the "wrteei 1".


My questions:


Am I doing something wrong?

Am I misunderstanding something?

Is there anybody who can confirm my observations?

The observed behavior is critical for my use case of the PCP; therefore I would like to deeply understand it.

0 Kudos
1 Reply

408 Views
peter_vranken
Contributor IV

Dear NXP Team,


Would you kindly comment this issue? I will explain, why it is relevant to me.


 I'm working on a multi-threading kernel and wanted to use kernel relevant External Interrupts of different priority levels. "Kernel relevant" means that it are interrupts, which may end with a context switch to another task. The kernel itself should be executed with MSR(EE)=1 so that non kernel relevant interrupts of higher priority are still serviced. If several kernel interrupts of different priority levels appear at nearly the same time, the following can happen. My example assumes two interrupts A and B of priority 1 and 2, respectively, and 2 be at the same time the highest permitted priority for kernel relevant interrupts:

- Interrupt A occurs and is handled by the CPU
- In IVOR#4(A) priority 0 is pushed on INTC's priority stack, CPR is 1
- Being in IVOR#4(A) and prior to wrteei 1, interrupt B occurs
- IVOR#4(A) sets INTC.CPR = 2 and only then wrteei 1
- Interrupt B is still asserted and now handled by the CPU
- In IVOR#4(B), on acknowledge, priority 2 is pushed on INTC's priority stack, CPR is again 2

(kernel code is executed, on return to IVOR#4(B) it decides to switch to another task)

- IVOR#4(B) sets wrteei 0 and signals EOI to INTC, 2 is popped from the priority stack (the value written by IVOR#4(A) into CPR)
- IVOR#4(B) initiates the task switch ==> Failure

Failure: New task is active although interrupt A is still pending (or, with other words, suspended together with the deactivated task) and any interrupt should have precedence over any task.


A simple solution:


Kernel interrupts all use the same priority and do not change CPR, so that they will never preempt one another. IVOR #8 software interrupts still raise CPR to this priority and can still be preempted by a kernel relevant External Interrupt immediately after the wrteei 1, but this doesn't care, they may be pending until the same task is reactivated. (However, the possibly preempting IVOR #4 has to save and restore the CPR in order to not destroy the critical section of the system call when it is later resumed.)


Unfortunately, this is an avoidance strategy only. Kernel interrupts of different priority cannot be implemented this way.

Note, there is an impact for any normal application, too, even if context switches are not a matter:


Normally, if a group of interrupts on different priorities use the INTC's PCP for mutual exclusion then the application designer could consider only one stack frame for all of them in his worst case stack consumption calculation. Example:

There are 7 interrupt priorities in use, 1..7. The interrupts of levels 1, 2, 3 use the PCP mutual exclude one another. A natural way to compute the worst case stack consumption would assume one stack frame size for the group 1,2,3 plus one frame size for each of the others, 5 frame sizes in total.


This will fail, since interrupt 2 can rarely preempt 1 and be -- even if only much more rarely -- be preempted in the same occurrence by interrupt 3. The worst case calculation always needs to consider all interrupt levels, regardless of the PCP.

My questions:

- Can you confirm this behavior?

- If yes, why is it not documented? It should go into the reference manual of the MPC5643L, section 28.6.6, where the PCP is explained in detail.

Regards,

Peter

0 Kudos