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:
ligd 2024-07-26 23:14:13 +08:00 committed by Mateusz Szafoni
parent 2f4c067c50
commit 1fb4f8f50e
23 changed files with 108 additions and 110 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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 */

View File

@ -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.

View File

@ -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.

View File

@ -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 */

View File

@ -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.

View File

@ -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.

View File

@ -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 */

View File

@ -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.
*/

View File

@ -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.

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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.

View File

@ -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.
*/

View File

@ -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.

View File

@ -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);

View File

@ -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.

View File

@ -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 */

View File

@ -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.

View File

@ -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.

View File

@ -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.
*/