Moved the ARC ISR enter callout onto the system stack (#700)

_tx_thread_context_save() calls _tx_execution_isr_enter when
TX_ENABLE_EXECUTION_CHANGE_NOTIFY is defined. On the path where an interrupt
preempted a running thread, that call was made before the switch to the system
stack, so the 32-byte call frame and the whole stack footprint of the callout
were taken from the interrupted thread's stack, on top of the 160-byte interrupt
frame the port had already allocated there.

The callout is supplied by the application, so its stack usage is not bounded by
ThreadX, and it is charged to every thread that happens to be running when an
interrupt arrives.

The two other callout sites in the same routine, the nested save and the idle
system save, already run on the system stack, as does the _tx_execution_isr_exit
call in _tx_thread_context_restore. _tx_thread_schedule was reordered in 6.1.9
so that _tx_execution_thread_enter runs on the system stack rather than the
thread stack; the same reorder was never applied to the context save.

The switch to the system stack now happens before the callout in the ARCv2_EM,
ARC_HS and SMP ARC_HS ports. _tx_thread_context_fast_save is unchanged because
the fast interrupt path never switches stacks by design.

Fixes #149

Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
Frédéric Desbiens
2026-09-08 15:42:39 -04:00
committed by GitHub
parent 29afcc3946
commit 945f5f5caa
3 changed files with 47 additions and 33 deletions
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
; * Copyright (c) 2026 Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,8 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
; Some portions generated by Copilot (Opus 5).
;/**************************************************************************/
;/**************************************************************************/
;/** */
@@ -176,19 +179,10 @@ __tx_thread_not_nested_save:
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
st sp, [r1, 8] ; Save thread's stack pointer
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
.ifdef TX_ENABLE_HW_STACK_CHECKING
lr r2, [status32] ; Pickup current STATUS32
and r2, r2, ~STATUS32_SC ; Clear the hardware stack checking enable bit (SC)
@@ -199,16 +193,26 @@ __tx_thread_not_nested_save:
sr r1, [KSTACK_BASE] ; Setup KSTACK_BASE
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
or r2, r2, STATUS32_SC ; Or in hardware stack checking enable bit (SC)
j_s.d [blink] ; Return to calling ISR
kflag r2 ; Enable hardware stack checking
.else
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
j_s.d [blink] ; Return to calling ISR
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
.endif
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. The call is
; made after the switch to the system stack so that it does not consume any
; of the interrupted thread's stack. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
bl.d _tx_execution_isr_enter ; Call the ISR enter function
nop ; Delay slot
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
j_s [blink] ; Return to calling ISR
;
; }
; else
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
; * Copyright (c) 2026 Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,8 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
; Some portions generated by Copilot (Opus 5).
;/**************************************************************************/
;/**************************************************************************/
;/** */
@@ -173,10 +176,17 @@ __tx_thread_not_nested_save:
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
st sp, [r1, 8] ; Save thread's stack pointer
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
; /* Call the ISR enter function to indicate an ISR is executing. The call is
; made after the switch to the system stack so that it does not consume any
; of the interrupted thread's stack. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
@@ -186,12 +196,7 @@ __tx_thread_not_nested_save:
add sp, sp, 32 ; Recover the stack space
.endif
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
j_s.d [blink] ; Return to calling ISR
ld sp, [gp, _tx_thread_system_stack_ptr@sda] ; Switch to system stack
j_s [blink] ; Return to calling ISR
;
; }
; else
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
; * Copyright (c) 2026 Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
; Some portions generated by Copilot (Opus 5).
;
;/**************************************************************************/
;/**************************************************************************/
@@ -187,10 +189,19 @@ __tx_thread_not_nested_save:
; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
;
st sp, [r1, 8] ; Save thread's stack pointer
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr[core];
;
mov r1, _tx_thread_system_stack_ptr ; Build address of system stack pointer
add r1, r1, r3 ;
ld sp, [r1] ; Switch to system stack
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
; /* Call the ISR enter function to indicate an ISR is executing. The call is
; made after the switch to the system stack so that it does not consume any
; of the interrupted thread's stack. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
@@ -199,14 +210,8 @@ __tx_thread_not_nested_save:
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr[core];
;
mov r1, _tx_thread_system_stack_ptr ; Build address of system stack pointer
add r1, r1, r3 ;
j_s.d [blink] ; Return to calling ISR
ld sp, [r1] ; Switch to system stack
j_s [blink] ; Return to calling ISR
;
; }
; else