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:
parent
c174ade4a1
commit
73453a39d1
3 changed files with 21 additions and 0 deletions
10
arch/Kconfig
10
arch/Kconfig
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue