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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.