arch: change nxsched_suspend/resume_scheduler() called position
for the citimon stats: thread 0: thread 1: enter_critical (t0) up_switch_context note suspend thread0 (t1) thread running IRQ happen, in ISR: post thread0 up_switch_context note resume thread0 (t2) ISR continue f1 ISR continue f2 ... ISR continue fn leave_critical (t3) You will see, the thread 0, critical_section time is: (t1 - t0) + (t3 - t2) BUT, this result contains f1 f2 .. fn time spent, it is wrong to tell user thead0 hold the critical lots of time but actually not belong to it. Resolve: change the nxsched_suspend/resume_scheduler to real hanppends Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
2f4c067c50
commit
1fb4f8f50e
@ -103,6 +103,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -75,6 +75,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -98,6 +98,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -579,12 +579,18 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
cpu = this_cpu();
|
||||
tcb = current_task(cpu);
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
cpu = this_cpu();
|
||||
tcb = current_task(cpu);
|
||||
g_running_tasks[cpu] = tcb;
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
@ -75,6 +75,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -77,6 +77,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -566,11 +566,17 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
cpu = this_cpu();
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
cpu = this_cpu();
|
||||
g_running_tasks[cpu] = tcb;
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
@ -124,6 +124,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -72,10 +72,16 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
/* Deliver the IRQ */
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
tcb = this_task();
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
tcb = this_task();
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -565,11 +565,17 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
cpu = this_cpu();
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
cpu = this_cpu();
|
||||
g_running_tasks[cpu] = tcb;
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
@ -55,27 +55,10 @@
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_interrupt_context())
|
||||
if (!up_interrupt_context())
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
@ -96,6 +96,11 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -55,27 +55,10 @@
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_interrupt_context())
|
||||
if (!up_interrupt_context())
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
@ -236,6 +236,9 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
|
||||
|
||||
if ((uint64_t *)f_regs != ret_regs)
|
||||
{
|
||||
cpu = this_cpu();
|
||||
tcb = current_task(cpu);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
@ -246,12 +249,15 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
cpu = this_cpu();
|
||||
tcb = current_task(cpu);
|
||||
g_running_tasks[cpu] = tcb;
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
@ -78,6 +78,11 @@ uint32_t *ceva_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != up_current_regs())
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(this_task());
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -69,10 +69,6 @@ void ceva_switchcontext(uint32_t **saveregs, uint32_t *restoreregs)
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
sched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_current_regs())
|
||||
@ -83,10 +79,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
rtcb->xcp.regs = up_current_regs();
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(tcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_set_current_regs(tcb->xcp.regs);
|
||||
@ -96,10 +88,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(tcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
@ -111,6 +111,11 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -57,10 +57,6 @@
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_interrupt_context())
|
||||
@ -71,10 +67,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
riscv_savecontext(rtcb);
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
@ -86,10 +78,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb, tcb);
|
||||
|
@ -116,6 +116,11 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(this_task());
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -59,10 +59,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_interrupt_context())
|
||||
@ -75,10 +71,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
x86_64_restore_auxstate(tcb);
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
@ -94,6 +86,8 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
cpu = this_cpu();
|
||||
|
||||
x86_64_restore_auxstate(tcb);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
@ -105,19 +99,20 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
|
||||
addrenv_switch(tcb);
|
||||
#endif
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
||||
restore_critical_section(tcb, this_cpu());
|
||||
restore_critical_section(tcb, cpu);
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(current_task(cpu));
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
cpu = this_cpu();
|
||||
g_running_tasks[cpu] = current_task(cpu);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
@ -97,6 +97,11 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[cpu]);
|
||||
nxsched_resume_scheduler(this_task());
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -82,6 +82,11 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
|
||||
nxsched_resume_scheduler(this_task());
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
|
@ -57,39 +57,10 @@
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_current_regs())
|
||||
if (!up_current_regs())
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
xtensa_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
xtensa_restorestate(tcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(tcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user