Re: [PATCH dovetail v5 03/12] riscv: irq_pipeline: enable hard IRQs during in-band trap handling
Philippe Gerum <[email protected]>
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
Until mark_trap_entry/exit do call oob_trap_notify/unwind to forward the event to the companion core, this code can be merged into the previous patch introducing the interrupt pipeline. Tobias Schaffner <[email protected]> writes: > When running with interrupt pipelining, re-enable hard interrupts > while handling traps on the in-band stage so that out-of-band events > can be delivered promptly. > > Signed-off-by: Tobias Schaffner <[email protected]> > --- > arch/riscv/kernel/traps.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c > index 267b8ec5a1bf..5b84e1ff0eeb 100644 > --- a/arch/riscv/kernel/traps.c > +++ b/arch/riscv/kernel/traps.c > @@ -112,10 +112,30 @@ void die(struct pt_regs *regs, const char *str) > make_task_dead(SIGSEGV); > } > > +static __always_inline > +bool mark_trap_entry(int signo, struct pt_regs *regs) > +{ > + if (likely(running_inband())) { > + hard_cond_local_irq_enable(); > + return true; > + } > + > + return false; > +} > + > +static __always_inline > +void mark_trap_exit(int signo, struct pt_regs *regs) > +{ > + hard_cond_local_irq_disable(); > +} > + > void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) > { > struct task_struct *tsk = current; > > + if (!mark_trap_entry(signo, regs)) > + return; > + > if (show_unhandled_signals && unhandled_signal(tsk, signo) > && printk_ratelimit()) { > pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT, > @@ -127,6 +147,8 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) > } > > force_sig_fault(signo, code, (void __user *)addr); > + > + mark_trap_exit(signo, regs); > } > > static void do_trap_error(struct pt_regs *regs, int signo, int code, > @@ -137,6 +159,12 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, > if (user_mode(regs)) { > do_trap(regs, signo, code, addr); > } else { > + /* > + * Dovetail: If we trapped from kernel space, either > + * we can fix up the situation, or we can't and we may > + * happily crash with hard irqs off. Either way, don't > + * bother. > + */ > if (!fixup_exception(regs)) > die(regs, str); > } -- Philippe.