arch: Add IRQ_OFFSET_NESTED feature

The x86 and xtensa implementations of irq_offload() invoke synchronous
interrupts on the local CPU, and are therefore safe to use from within
an interrupt context.  This is a cheap and portable way to exercise
nested interrupts, which are otherwise highly platform-dependent to
test.  Add a kconfig to signal the capability.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2022-02-14 14:30:34 -08:00 committed by Anas Nashif
commit 73453a39d1
3 changed files with 21 additions and 0 deletions

View file

@ -84,6 +84,7 @@ config X86
select ARCH_HAS_TIMING_FUNCTIONS
select ARCH_HAS_THREAD_LOCAL_STORAGE
select ARCH_HAS_DEMAND_PAGING
select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD
select NEED_LIBC_MEM_PARTITION if USERSPACE && TIMING_FUNCTIONS \
&& !BOARD_HAS_TIMING_FUNCTIONS \
&& !SOC_HAS_TIMING_FUNCTIONS
@ -116,6 +117,7 @@ config XTENSA
select HAS_DTS
select USE_SWITCH
select USE_SWITCH_SUPPORTED
select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD
imply ATOMIC_OPERATIONS_ARCH
help
Xtensa architecture
@ -438,6 +440,14 @@ config IRQ_OFFLOAD
run in interrupt context. Only useful for test cases that need
to validate the correctness of kernel objects in IRQ context.
config IRQ_OFFLOAD_NESTED
bool "irq_offload() supports nested IRQs"
depends on IRQ_OFFLOAD
help
When set by the arch layer, indicates that irq_offload() may
legally be called in interrupt context to cause a
synchronous nested interrupt on the current CPU. Not all
hardware is capable.
config EXTRA_EXCEPTION_INFO
bool "Collect extra exception info"

View file

@ -25,6 +25,13 @@ typedef void (*irq_offload_routine_t)(const void *parameter);
* which needs to show that kernel objects work correctly in interrupt
* context.
*
* Additionally, when CONFIG_IRQ_OFFLOAD_NESTED is set by the
* architecture, this routine works to synchronously invoke a nested
* interrupt when called from an ISR context (i.e. when k_is_in_isr()
* is true). Note that not all platforms will have hardware support
* for this capability, and even on those some interrupts may be
* running at unpreemptible priorities.
*
* @param routine The function to run
* @param parameter Argument to pass to the function when it is run as an
* interrupt

View file

@ -890,9 +890,13 @@ K_SEM_DEFINE(offload_sem, 1, 1);
void irq_offload(irq_offload_routine_t routine, const void *parameter)
{
#ifdef CONFIG_IRQ_OFFLOAD_NESTED
arch_irq_offload(routine, parameter);
#else
k_sem_take(&offload_sem, K_FOREVER);
arch_irq_offload(routine, parameter);
k_sem_give(&offload_sem);
#endif
}
#endif