This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new e4a0470527 riscv: add a return value to riscv_swint indicating whether 
a context switch is required
e4a0470527 is described below

commit e4a047052745251cff26b5cbb39c239ad8f1a3e9
Author: hujun5 <huj...@xiaomi.com>
AuthorDate: Sat Sep 21 11:14:18 2024 +0800

    riscv: add a return value to riscv_swint indicating whether a context 
switch is required
    
    This commit fixes the regression from 
https://github.com/apache/nuttx/pull/13561
    
    Signed-off-by: hujun5 <huj...@xiaomi.com>
---
 arch/risc-v/src/common/riscv_fork.c                       |  7 +++++++
 arch/risc-v/src/common/riscv_internal.h                   |  4 ++++
 arch/risc-v/src/common/riscv_swint.c                      |  1 +
 arch/risc-v/src/common/supervisor/riscv_perform_syscall.c | 10 +++-------
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_fork.c 
b/arch/risc-v/src/common/riscv_fork.c
index 40e463b2ae..896d8d46c4 100644
--- a/arch/risc-v/src/common/riscv_fork.c
+++ b/arch/risc-v/src/common/riscv_fork.c
@@ -108,11 +108,16 @@ pid_t riscv_fork(const struct fork_s *context)
   uintptr_t newtop;
   uintptr_t stacktop;
   uintptr_t stackutil;
+  irqstate_t flags;
 #ifdef CONFIG_SCHED_THREAD_LOCAL
   uintptr_t tp;
 #endif
   UNUSED(context);
 
+  /* parent regs may change in irq, we should disable irq here */
+
+  flags = up_irq_save();
+
   /* Allocate and initialize a TCB for the child task. */
 
   child = nxtask_setup_fork((start_t)parent->xcp.regs[REG_RA]);
@@ -164,6 +169,8 @@ pid_t riscv_fork(const struct fork_s *context)
   child->cmn.xcp.regs[REG_TP] = tp;
 #endif
 
+  up_irq_restore(flags);
+
   /* And, finally, start the child task.  On a failure, nxtask_start_fork()
    * will discard the TCB by calling nxtask_abort_fork().
    */
diff --git a/arch/risc-v/src/common/riscv_internal.h 
b/arch/risc-v/src/common/riscv_internal.h
index d9165356a9..c8b5f184bf 100644
--- a/arch/risc-v/src/common/riscv_internal.h
+++ b/arch/risc-v/src/common/riscv_internal.h
@@ -109,6 +109,10 @@
 #define PMP_ACCESS_DENIED   (-1)    /* Access set and denied */
 #define PMP_ACCESS_FULL     (1)     /* Access set and allowed */
 
+/* Return values from riscv_swint */
+
+#define SWINT_CONTEXT_SWITCH (1)    /* Indicate we need context switch */
+
 #ifndef __ASSEMBLY__
 
 /* Use ASM as rv64ilp32 compiler generated address is limited */
diff --git a/arch/risc-v/src/common/riscv_swint.c 
b/arch/risc-v/src/common/riscv_swint.c
index 510161db6f..4cf68ac0aa 100644
--- a/arch/risc-v/src/common/riscv_swint.c
+++ b/arch/risc-v/src/common/riscv_swint.c
@@ -496,6 +496,7 @@ int riscv_swint(int irq, void *context, void *arg)
   if (regs != new_regs)
     {
       restore_critical_section(this_task(), this_cpu());
+      return SWINT_CONTEXT_SWITCH;
     }
 
   return OK;
diff --git a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c 
b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
index 8e26221e40..022c58155e 100644
--- a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
+++ b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
@@ -39,6 +39,7 @@ void *riscv_perform_syscall(uintreg_t *regs)
 {
   struct tcb_s *tcb;
   int cpu;
+  int ret;
 
   /* Set up the interrupt register set needed by swint() */
 
@@ -46,10 +47,9 @@ void *riscv_perform_syscall(uintreg_t *regs)
 
   /* Run the system call handler (swint) */
 
-  riscv_swint(0, regs, NULL);
-  tcb = this_task();
+  ret = riscv_swint(0, regs, NULL);
 
-  if (regs != tcb->xcp.regs)
+  if (ret == SWINT_CONTEXT_SWITCH)
     {
 #ifdef CONFIG_ARCH_ADDRENV
       /* Make sure that the address environment for the previously
@@ -69,10 +69,6 @@ void *riscv_perform_syscall(uintreg_t *regs)
       tcb = current_task(cpu);
       g_running_tasks[cpu] = tcb;
 
-      /* Restore the cpu lock */
-
-      restore_critical_section(tcb, cpu);
-
       /* If a context switch occurred while processing the interrupt then
        * current_regs may have change value.  If we return any value
        * different from the input regs, then the lower level will know

Reply via email to