mirror of
https://github.com/apache/nuttx.git
synced 2025-12-07 18:12:33 +08:00
arch: optimize up_check_tcbstack for stack overflow detection
Many times, context switching does not occur when the thread stack memory is almost exhausted, so we need to mofify up_check_tcbstack to accurately detect it. Co-authored-by: Chengdong Wang <wangchengdong@lixiang.com> Signed-off-by: guoshengyuan1 <guoshengyuan1@xiaomi.com>
This commit is contained in:
@@ -200,7 +200,7 @@ void arm_stack_color(void *stackbase, size_t nbytes)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
@@ -213,7 +213,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
size = arm_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
|
||||
size = arm_stack_check(tcb->stack_base_ptr, check_size);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (tcb->addrenv_own != NULL)
|
||||
|
||||
@@ -210,7 +210,7 @@ void arm64_stack_color(void *stackbase, size_t nbytes)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
@@ -223,7 +223,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
size = arm64_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
|
||||
size = arm64_stack_check(tcb->stack_base_ptr, check_size);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (tcb->addrenv_own != NULL)
|
||||
|
||||
@@ -144,10 +144,9 @@ size_t avr_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(FAR struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(FAR struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return avr_stack_check((uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
return avr_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
|
||||
@@ -139,10 +139,9 @@ size_t ceva_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return ceva_stack_check((uintptr_t)tcb->stack_alloc_ptr,
|
||||
tcb->adj_stack_size);
|
||||
return ceva_stack_check((uintptr_t)tcb->stack_alloc_ptr, check_size);
|
||||
}
|
||||
|
||||
size_t up_check_intstack(int cpu)
|
||||
|
||||
@@ -115,10 +115,9 @@ size_t or1k_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return or1k_stack_check((uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
return or1k_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
|
||||
@@ -156,7 +156,7 @@ size_t riscv_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
@@ -169,8 +169,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (tcb->addrenv_own != NULL)
|
||||
|
||||
@@ -154,8 +154,7 @@ size_t sim_stack_check(void *alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return sim_stack_check((void *)(uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
return sim_stack_check((void *)(uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
}
|
||||
|
||||
@@ -200,9 +200,9 @@ void sparc_stack_color(void *stackbase, size_t nbytes)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return sparc_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
|
||||
return sparc_stack_check(tcb->stack_base_ptr, check_size);
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
|
||||
@@ -117,7 +117,7 @@ size_t tricore_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
@@ -130,8 +130,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (tcb->addrenv_own != NULL)
|
||||
|
||||
@@ -154,7 +154,7 @@ void x86_64_stack_color(void *stackbase, size_t nbytes)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
@@ -167,7 +167,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
size = x86_64_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
|
||||
size = x86_64_stack_check(tcb->stack_base_ptr, check_size);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (tcb->addrenv_own != NULL)
|
||||
|
||||
@@ -158,10 +158,9 @@ size_t xtensa_stack_check(uintptr_t alloc, size_t size)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
|
||||
{
|
||||
return xtensa_stack_check((uintptr_t)tcb->stack_base_ptr,
|
||||
tcb->adj_stack_size);
|
||||
return xtensa_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
|
||||
@@ -1054,8 +1054,10 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
|
||||
|
||||
/* Show the stack size */
|
||||
|
||||
linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
|
||||
"StackUsed:", (long)up_check_tcbstack(tcb));
|
||||
linesize = procfs_snprintf(
|
||||
procfile->line, STATUS_LINELEN, "%-12s%zu\n",
|
||||
"StackUsed:", up_check_tcbstack(tcb, tcb->adj_stack_size));
|
||||
|
||||
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
|
||||
&offset);
|
||||
|
||||
|
||||
@@ -2563,7 +2563,7 @@ void irq_dispatch(int irq, FAR void *context);
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
struct tcb_s;
|
||||
size_t up_check_tcbstack(FAR struct tcb_s *tcb);
|
||||
size_t up_check_tcbstack(FAR struct tcb_s *tcb, size_t check_size);
|
||||
#if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
size_t up_check_intstack(int cpu);
|
||||
#endif
|
||||
|
||||
@@ -335,7 +335,7 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t sp)
|
||||
tcbstack_base,
|
||||
tcbstack_size,
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
up_check_tcbstack(rtcb)
|
||||
up_check_tcbstack(rtcb, rtcb->adj_stack_size)
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
@@ -376,7 +376,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
stack_used = up_check_tcbstack(tcb);
|
||||
stack_used = up_check_tcbstack(tcb, tcb->adj_stack_size);
|
||||
if (tcb->adj_stack_size > 0 && stack_used > 0)
|
||||
{
|
||||
/* Use fixed-point math with one decimal place */
|
||||
@@ -431,7 +431,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
, tcb->stack_base_ptr
|
||||
, tcb->adj_stack_size
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
, up_check_tcbstack(tcb)
|
||||
, up_check_tcbstack(tcb, tcb->adj_stack_size)
|
||||
, stack_filled / 10, stack_filled % 10
|
||||
, (stack_filled >= 10 * 80 ? '!' : ' ')
|
||||
#endif
|
||||
|
||||
@@ -411,7 +411,7 @@ static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo,
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
else
|
||||
{
|
||||
len = up_check_tcbstack(tcb);
|
||||
len = up_check_tcbstack(tcb, tcb->adj_stack_size);
|
||||
buf = (uintptr_t)tcb->stack_base_ptr +
|
||||
(tcb->adj_stack_size - len);
|
||||
}
|
||||
@@ -576,7 +576,7 @@ static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo,
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
else
|
||||
{
|
||||
phdr->p_filesz = up_check_tcbstack(tcb);
|
||||
phdr->p_filesz = up_check_tcbstack(tcb, tcb->adj_stack_size);
|
||||
phdr->p_vaddr = (uintptr_t)tcb->stack_base_ptr +
|
||||
(tcb->adj_stack_size - phdr->p_filesz);
|
||||
}
|
||||
|
||||
@@ -78,8 +78,7 @@ void nxsched_suspend_scheduler(FAR struct tcb_s *tcb)
|
||||
}
|
||||
|
||||
#if CONFIG_STACKCHECK_MARGIN > 0
|
||||
DEBUGASSERT(up_check_tcbstack(tcb) <=
|
||||
tcb->adj_stack_size - CONFIG_STACKCHECK_MARGIN);
|
||||
DEBUGASSERT(up_check_tcbstack(tcb, CONFIG_STACKCHECK_MARGIN) == 0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user