[PATCH v6 2/8] riscv: vector: refactor context switch for kernel-mode vector

Andy Chiu tchiu at tenstorrent.com
Fri Sep 18 14:51:16 PDT 2026


When context switching out a thread in preemptible kernel-mode vector,
there are 2 distinct cases: One is voluntary switch and the other is
trap-introduced switch. We don't need to save vector context for
voluntary switch and the context is always !dirty as long as we clear
the dirty bit at riscv_v_context_nesting_end().

Signed-off-by: Andy Chiu <tchiu at tenstorrent.com>
---
Changelog v6:
 - new patch since v6
---
 arch/riscv/include/asm/vector.h        | 5 +++--
 arch/riscv/kernel/kernel_mode_vector.c | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index fccf9edb4e6a..6aa125d66ace 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -378,10 +378,11 @@ static inline void __switch_to_vector(struct task_struct *prev,
 
 	if (riscv_preempt_v_started(prev)) {
 		if (!(current->thread.riscv_v_flags & RISCV_V_CTX_DEPTH_MASK)) {
+			/* Voluntary schedule(): nesting_end closed any dirty. */
+			WARN_ON(riscv_preempt_v_dirty(prev));
 			riscv_v_disable();
 			prev->thread.riscv_v_flags |= RISCV_PREEMPT_V_IN_SCHEDULE;
-		}
-		if (riscv_preempt_v_dirty(prev)) {
+		} else if (riscv_preempt_v_dirty(prev)) {
 			__riscv_v_vstate_save(&prev->thread.kernel_vstate,
 					      prev->thread.kernel_vstate.datap);
 			riscv_preempt_v_clear_dirty(prev);
diff --git a/arch/riscv/kernel/kernel_mode_vector.c b/arch/riscv/kernel/kernel_mode_vector.c
index 5ad93ddf6a10..b9481a3e40e3 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -219,6 +219,7 @@ asmlinkage void riscv_v_context_nesting_end(struct pt_regs *regs)
 			__riscv_v_vstate_clean(regs);
 			riscv_preempt_v_reset_flags();
 		}
+		riscv_preempt_v_clear_dirty(current);
 	}
 }
 #else
-- 
2.43.0




More information about the linux-riscv mailing list