score: Fix task stack initialization

Do not adjust the stack area begin address since this may confuse the
stack allocator and result in failed stack frees.

Account for the alignment overhead in the stack space size estimate.

Check that the stack size is in the expected interval.
This commit is contained in:
Sebastian Huber
2021-03-27 11:15:43 +01:00
parent d4d2f6487a
commit e0aba8cb9e
7 changed files with 41 additions and 16 deletions

View File

@@ -10,7 +10,7 @@
*/
/*
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
* Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,12 +55,27 @@
#include <rtems/score/stack.h>
#include <rtems/sysinit.h>
#if CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT
#define _CONFIGURE_TASK_STACK_ALLOC_SIZE( _stack_size ) \
( RTEMS_ALIGN_UP( \
( _stack_size ) + CONTEXT_FP_SIZE, \
CPU_STACK_ALIGNMENT \
) + CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT )
#else
#define _CONFIGURE_TASK_STACK_ALLOC_SIZE( _stack_size ) \
RTEMS_ALIGN_UP( ( _stack_size ) + CONTEXT_FP_SIZE, CPU_STACK_ALIGNMENT )
#endif
#ifdef CONFIGURE_TASK_STACK_FROM_ALLOCATOR
#define _Configure_From_stackspace( _stack_size ) \
CONFIGURE_TASK_STACK_FROM_ALLOCATOR( _stack_size + CONTEXT_FP_SIZE )
CONFIGURE_TASK_STACK_FROM_ALLOCATOR( \
_CONFIGURE_TASK_STACK_ALLOC_SIZE( _stack_size ) \
)
#else
#define _Configure_From_stackspace( _stack_size ) \
_Configure_From_workspace( _stack_size + CONTEXT_FP_SIZE )
_Configure_From_workspace( \
_CONFIGURE_TASK_STACK_ALLOC_SIZE( _stack_size ) \
)
#endif
#ifndef CONFIGURE_EXTRA_TASK_STACKS

View File

@@ -135,7 +135,7 @@ RTEMS_INLINE_ROUTINE size_t _Stack_Extend_size(
)
{
size_t extra_size;
size_t alignment_overhead;
size_t allocator_overhead;
extra_size = _TLS_Get_allocation_size();
@@ -153,18 +153,16 @@ RTEMS_INLINE_ROUTINE size_t _Stack_Extend_size(
* can be allocated for the stack, we have to align it up to the next stack
* boundary.
*/
alignment_overhead = CPU_STACK_ALIGNMENT - 1;
extra_size += CPU_STACK_ALIGNMENT - 1;
#if CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT
/*
* If the heap allocator does not meet the stack alignment requirement, then
* we have to do the stack alignment manually in _Thread_Initialize() and
* need to allocate extra space for this.
*/
alignment_overhead += CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT;
#endif
allocator_overhead = CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT;
if ( stack_size > SIZE_MAX - extra_size - alignment_overhead ) {
if ( stack_size > SIZE_MAX - extra_size - allocator_overhead ) {
/*
* In case of an unsigned integer overflow, saturate at the maximum value.
*/
@@ -172,9 +170,9 @@ RTEMS_INLINE_ROUTINE size_t _Stack_Extend_size(
}
stack_size += extra_size;
stack_size = RTEMS_ALIGN_UP( stack_size, CPU_STACK_ALIGNMENT );
stack_size = RTEMS_ALIGN_DOWN( stack_size, CPU_STACK_ALIGNMENT );
return stack_size;
return stack_size + allocator_overhead;
}
/**

View File

@@ -132,7 +132,6 @@ static bool _Thread_Try_initialize(
stack_begin = config->stack_area;
stack_end = stack_begin + config->stack_size;
stack_align = CPU_STACK_ALIGNMENT;
stack_begin = (char *) RTEMS_ALIGN_UP( (uintptr_t) stack_begin, stack_align );
stack_end = (char *) RTEMS_ALIGN_DOWN( (uintptr_t) stack_end, stack_align );
/* Allocate floating-point context in stack area */

View File

@@ -78,7 +78,11 @@ static rtems_task test_task(rtems_task_argument arg)
sc = pthread_attr_getstack( &attr, &addr, &size );
rtems_test_assert( sc == 0 );
rtems_test_assert( addr != NULL );
rtems_test_assert( size == RTEMS_MINIMUM_STACK_SIZE );
rtems_test_assert( size >= RTEMS_MINIMUM_STACK_SIZE );
rtems_test_assert(
size <= RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT -
CPU_HEAP_ALIGNMENT
);
value = -1;
sc = pthread_attr_getscope( &attr, &value );

View File

@@ -480,7 +480,11 @@ static rtems_task Init(rtems_task_argument argument)
eno = pthread_attr_getstacksize(&attr, &stack_size);
rtems_test_assert(eno == 0);
rtems_test_assert(stack_size == CPU_STACK_MINIMUM_SIZE);
rtems_test_assert(stack_size >= CPU_STACK_MINIMUM_SIZE);
rtems_test_assert(
stack_size <= CPU_STACK_MINIMUM_SIZE + CPU_STACK_ALIGNMENT -
CPU_HEAP_ALIGNMENT
);
eno = pthread_attr_destroy(&attr);
rtems_test_assert(eno == 0);

View File

@@ -101,7 +101,11 @@ static void test_stack_config(void)
eno = pthread_attr_getstacksize(&attr, &stack_size);
rtems_test_assert(eno == 0);
rtems_test_assert(stack_size == 2 * CPU_STACK_MINIMUM_SIZE);
rtems_test_assert(stack_size >= 2 * CPU_STACK_MINIMUM_SIZE);
rtems_test_assert(
stack_size <= 2 * CPU_STACK_MINIMUM_SIZE + CPU_STACK_ALIGNMENT -
CPU_HEAP_ALIGNMENT
);
eno = pthread_attr_destroy(&attr);
rtems_test_assert(eno == 0);

View File

@@ -48,7 +48,8 @@
#define TASK_STORAGE_SIZE \
RTEMS_TASK_STORAGE_SIZE( \
MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE + \
CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT, \
TASK_ATTRIBUTES \
)