mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +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;
|
size_t size;
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
if (tcb->addrenv_own != NULL)
|
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;
|
size_t size;
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
if (tcb->addrenv_own != NULL)
|
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,
|
return avr_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
#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,
|
return ceva_stack_check((uintptr_t)tcb->stack_alloc_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t up_check_intstack(int cpu)
|
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,
|
return or1k_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
#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;
|
size_t size;
|
||||||
|
|
||||||
@@ -169,8 +169,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr,
|
size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
if (tcb->addrenv_own != NULL)
|
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,
|
return sim_stack_check((void *)(uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_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
|
#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;
|
size_t size;
|
||||||
|
|
||||||
@@ -130,8 +130,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr,
|
size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
if (tcb->addrenv_own != NULL)
|
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;
|
size_t size;
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
if (tcb->addrenv_own != NULL)
|
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,
|
return xtensa_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
|
||||||
tcb->adj_stack_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||||
|
|||||||
@@ -1054,8 +1054,10 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
|
|||||||
|
|
||||||
/* Show the stack size */
|
/* Show the stack size */
|
||||||
|
|
||||||
linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
|
linesize = procfs_snprintf(
|
||||||
"StackUsed:", (long)up_check_tcbstack(tcb));
|
procfile->line, STATUS_LINELEN, "%-12s%zu\n",
|
||||||
|
"StackUsed:", up_check_tcbstack(tcb, tcb->adj_stack_size));
|
||||||
|
|
||||||
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
|
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
|
||||||
&offset);
|
&offset);
|
||||||
|
|
||||||
|
|||||||
@@ -2563,7 +2563,7 @@ void irq_dispatch(int irq, FAR void *context);
|
|||||||
|
|
||||||
#ifdef CONFIG_STACK_COLORATION
|
#ifdef CONFIG_STACK_COLORATION
|
||||||
struct tcb_s;
|
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
|
#if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
size_t up_check_intstack(int cpu);
|
size_t up_check_intstack(int cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+3
-3
@@ -335,7 +335,7 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t sp)
|
|||||||
tcbstack_base,
|
tcbstack_base,
|
||||||
tcbstack_size,
|
tcbstack_size,
|
||||||
#ifdef CONFIG_STACK_COLORATION
|
#ifdef CONFIG_STACK_COLORATION
|
||||||
up_check_tcbstack(rtcb)
|
up_check_tcbstack(rtcb, rtcb->adj_stack_size)
|
||||||
#else
|
#else
|
||||||
0
|
0
|
||||||
#endif
|
#endif
|
||||||
@@ -376,7 +376,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_COLORATION
|
#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)
|
if (tcb->adj_stack_size > 0 && stack_used > 0)
|
||||||
{
|
{
|
||||||
/* Use fixed-point math with one decimal place */
|
/* 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->stack_base_ptr
|
||||||
, tcb->adj_stack_size
|
, tcb->adj_stack_size
|
||||||
#ifdef CONFIG_STACK_COLORATION
|
#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, stack_filled % 10
|
||||||
, (stack_filled >= 10 * 80 ? '!' : ' ')
|
, (stack_filled >= 10 * 80 ? '!' : ' ')
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo,
|
|||||||
#ifdef CONFIG_STACK_COLORATION
|
#ifdef CONFIG_STACK_COLORATION
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = up_check_tcbstack(tcb);
|
len = up_check_tcbstack(tcb, tcb->adj_stack_size);
|
||||||
buf = (uintptr_t)tcb->stack_base_ptr +
|
buf = (uintptr_t)tcb->stack_base_ptr +
|
||||||
(tcb->adj_stack_size - len);
|
(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
|
#ifdef CONFIG_STACK_COLORATION
|
||||||
else
|
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 +
|
phdr->p_vaddr = (uintptr_t)tcb->stack_base_ptr +
|
||||||
(tcb->adj_stack_size - phdr->p_filesz);
|
(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
|
#if CONFIG_STACKCHECK_MARGIN > 0
|
||||||
DEBUGASSERT(up_check_tcbstack(tcb) <=
|
DEBUGASSERT(up_check_tcbstack(tcb, CONFIG_STACKCHECK_MARGIN) == 0);
|
||||||
tcb->adj_stack_size - CONFIG_STACKCHECK_MARGIN);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user