Revert "Xtensa SMP: Avoid a nasty situation in SMP by assuring that up_release_pending() is not re-entered."

This reverts commit 733a57b4df.
This commit is contained in:
Gregory Nutt
2016-12-25 07:12:46 -06:00
parent 49fae0ac6b
commit b87fc91466
2 changed files with 57 additions and 84 deletions
-6
View File
@@ -229,9 +229,6 @@ int up_cpu_pause(int cpu)
* handler from returning until up_cpu_resume() is called; g_cpu_paused * handler from returning until up_cpu_resume() is called; g_cpu_paused
* is a handshake that will prefent this function from returning until * is a handshake that will prefent this function from returning until
* the CPU is actually paused. * the CPU is actually paused.
*
* REVISIT: OR should there be logic to just skip this if the other CPU
* is already paused.
*/ */
DEBUGASSERT(!spin_islocked(&g_cpu_wait[cpu]) && DEBUGASSERT(!spin_islocked(&g_cpu_wait[cpu]) &&
@@ -300,9 +297,6 @@ int up_cpu_resume(int cpu)
/* Release the spinlock. Releasing the spinlock will cause the SGI2 /* Release the spinlock. Releasing the spinlock will cause the SGI2
* handler on 'cpu' to continue and return from interrupt to the newly * handler on 'cpu' to continue and return from interrupt to the newly
* established thread. * established thread.
*
* REVISIT: Should there be a more positive handshake to assure that the
* resumption is complete before returning.
*/ */
DEBUGASSERT(spin_islocked(&g_cpu_wait[cpu]) && DEBUGASSERT(spin_islocked(&g_cpu_wait[cpu]) &&
+57 -78
View File
@@ -39,7 +39,6 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdbool.h>
#include <sched.h> #include <sched.h>
#include <debug.h> #include <debug.h>
@@ -69,112 +68,92 @@
void up_release_pending(void) void up_release_pending(void)
{ {
struct tcb_s *rtcb = this_task(); struct tcb_s *rtcb = this_task();
#ifdef CONFIG_SMP
static bool busy = false;
#endif
sinfo("From TCB=%p\n", rtcb); sinfo("From TCB=%p\n", rtcb);
/* In SMP configurations, this function will be called as part of leaving /* Merge the g_pendingtasks list into the ready-to-run task list */
* the critical section. In that case, it may be re-entered as part of
* the sched_addreadytorun() processing. We have to guard against that
* case.
*/
#ifdef CONFIG_SMP /* sched_lock(); */
if (!busy) if (sched_mergepending())
{ {
busy = true; /* The currently active task has changed! We will need to
#endif * switch contexts.
*/
/* Merge the g_pendingtasks list into the ready-to-run task list */ /* Update scheduler parameters */
/* sched_lock(); */ sched_suspend_scheduler(rtcb);
if (sched_mergepending())
/* Are we operating in interrupt context? */
if (CURRENT_REGS)
{ {
/* The currently active task has changed! We will need to /* Yes, then we have to do things differently.
* switch contexts. * Just copy the CURRENT_REGS into the OLD rtcb.
*/ */
xtensa_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */ /* Update scheduler parameters */
sched_suspend_scheduler(rtcb); sched_resume_scheduler(rtcb);
/* Are we operating in interrupt context? */ /* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
if (CURRENT_REGS)
{
/* Yes, then we have to do things differently.
* Just copy the CURRENT_REGS into the OLD rtcb.
*/
xtensa_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
xtensa_restorestate(rtcb->xcp.regs);
}
/* Copy the exception context into the TCB of the task that
* was currently active. if up_saveusercontext returns a non-zero
* value, then this is really the previously running task
* restarting!
*/ */
else if (!xtensa_context_save(rtcb->xcp.regs)) xtensa_restorestate(rtcb->xcp.regs);
{ }
#if XCHAL_CP_NUM > 0
/* Save the co-processor state in in the suspended thread's co-
* processor save area.
*/
xtensa_coproc_savestate(&rtcb->xcp.cpstate); /* Copy the exception context into the TCB of the task that
* was currently active. if up_saveusercontext returns a non-zero
* value, then this is really the previously running task
* restarting!
*/
else if (!xtensa_context_save(rtcb->xcp.regs))
{
#if XCHAL_CP_NUM > 0
/* Save the co-processor state in in the suspended thread's co-
* processor save area.
*/
xtensa_coproc_savestate(&rtcb->xcp.cpstate);
#endif #endif
/* Restore the exception context of the rtcb at the (new) head /* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list. * of the ready-to-run task list.
*/ */
rtcb = this_task(); rtcb = this_task();
#if XCHAL_CP_NUM > 0 #if XCHAL_CP_NUM > 0
/* Set up the co-processor state for the newly started thread. */ /* Set up the co-processor state for the newly started thread. */
xtensa_coproc_restorestate(&rtcb->xcp.cpstate); xtensa_coproc_restorestate(&rtcb->xcp.cpstate);
#endif #endif
#ifdef CONFIG_ARCH_ADDRENV #ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously /* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump, * running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new * MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list. * thread at the head of the ready-to-run list.
*/ */
(void)group_addrenv(rtcb); (void)group_addrenv(rtcb);
#endif #endif
/* Update scheduler parameters */ /* Update scheduler parameters */
sched_resume_scheduler(rtcb); sched_resume_scheduler(rtcb);
/* Then switch contexts */ /* Then switch contexts */
xtensa_context_restore(rtcb->xcp.regs); xtensa_context_restore(rtcb->xcp.regs);
}
} }
#ifdef CONFIG_SMP
busy = false;
} }
#endif
} }