mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
score: Fix per-CPU data allocation
Allocate the per-CPU data for secondary processors directly from the heap areas before heap initialization and not via _Workspace_Allocate_aligned(). This avoids dependency on the workspace allocator. It fixes also a problem on some platforms (e.g. QorIQ) where at this early point in the system initialization the top of the RAM is used by low-level startup code on secondary processors (boot pages). Update #3507.
This commit is contained in:
@@ -193,7 +193,8 @@ typedef enum {
|
||||
INTERNAL_ERROR_LIBIO_STDOUT_FD_OPEN_FAILED = 36,
|
||||
INTERNAL_ERROR_LIBIO_STDERR_FD_OPEN_FAILED = 37,
|
||||
INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT = 38,
|
||||
INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL = 39
|
||||
INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL = 39,
|
||||
INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA = 40
|
||||
} Internal_errors_Core_list;
|
||||
|
||||
typedef CPU_Uint32ptr Internal_errors_t;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012, 2017 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
@@ -66,7 +66,8 @@ static const char *const internal_error_text[] = {
|
||||
"INTERNAL_ERROR_LIBIO_STDOUT_FD_OPEN_FAILED",
|
||||
"INTERNAL_ERROR_LIBIO_STDERR_FD_OPEN_FAILED",
|
||||
"INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT",
|
||||
"INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL"
|
||||
"INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL",
|
||||
"INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA"
|
||||
};
|
||||
|
||||
const char *rtems_internal_error_text( rtems_fatal_code error )
|
||||
|
||||
@@ -77,37 +77,43 @@ static uintptr_t _Workspace_Space_for_TLS( uintptr_t page_size )
|
||||
return space;
|
||||
}
|
||||
|
||||
static uintptr_t _Workspace_Space_for_per_CPU_data( uintptr_t page_size )
|
||||
{
|
||||
uintptr_t space;
|
||||
|
||||
#ifdef RTEMS_SMP
|
||||
uintptr_t size;
|
||||
static void *_Workspace_Allocate_from_areas(
|
||||
Heap_Area *areas,
|
||||
size_t area_count,
|
||||
uintptr_t size,
|
||||
uintptr_t alignment
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
size = RTEMS_LINKER_SET_SIZE( _Per_CPU_Data );
|
||||
_Assert( size % CPU_CACHE_LINE_BYTES == 0 );
|
||||
for ( i = 0; i < area_count; ++i ) {
|
||||
Heap_Area *area;
|
||||
uintptr_t alloc_begin;
|
||||
uintptr_t alloc_size;
|
||||
|
||||
if ( size > 0 ) {
|
||||
/*
|
||||
* Memory allocated with an alignment constraint is allocated from the end of
|
||||
* a free block. The last allocation may need one free block of minimum
|
||||
* size.
|
||||
*/
|
||||
space = _Heap_Min_block_size( page_size );
|
||||
area = &areas[ i ];
|
||||
alloc_begin = (uintptr_t) area->begin;
|
||||
alloc_begin = ( alloc_begin + alignment - 1 ) & ~( alignment - 1 );
|
||||
alloc_size = size;
|
||||
alloc_size += alloc_begin - (uintptr_t) area->begin;
|
||||
|
||||
space += ( rtems_configuration_get_maximum_processors() - 1 )
|
||||
* _Heap_Size_with_overhead( page_size, size, CPU_CACHE_LINE_BYTES );
|
||||
} else {
|
||||
space = 0;
|
||||
if ( area->size >= alloc_size ) {
|
||||
area->begin = (void *) ( alloc_begin + size );
|
||||
area->size -= alloc_size;
|
||||
|
||||
return (void *) alloc_begin;
|
||||
}
|
||||
#else
|
||||
space = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return space;
|
||||
}
|
||||
|
||||
static void _Workspace_Allocate_per_CPU_data( void )
|
||||
static void _Workspace_Allocate_per_CPU_data(
|
||||
Heap_Area *areas,
|
||||
size_t area_count
|
||||
)
|
||||
{
|
||||
#ifdef RTEMS_SMP
|
||||
uintptr_t size;
|
||||
@@ -126,11 +132,23 @@ static void _Workspace_Allocate_per_CPU_data( void )
|
||||
|
||||
for ( cpu_index = 1 ; cpu_index < cpu_max ; ++cpu_index ) {
|
||||
cpu = _Per_CPU_Get_by_index( cpu_index );
|
||||
cpu->data = _Workspace_Allocate_aligned( size, CPU_CACHE_LINE_BYTES );
|
||||
_Assert( cpu->data != NULL );
|
||||
cpu->data = _Workspace_Allocate_from_areas(
|
||||
areas,
|
||||
area_count,
|
||||
size,
|
||||
CPU_CACHE_LINE_BYTES
|
||||
);
|
||||
|
||||
if( cpu->data == NULL ) {
|
||||
_Internal_error( INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA );
|
||||
}
|
||||
|
||||
memcpy( cpu->data, RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ), size);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) areas;
|
||||
(void) area_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -148,11 +166,12 @@ void _Workspace_Handler_initialization(
|
||||
uintptr_t overhead;
|
||||
size_t i;
|
||||
|
||||
_Workspace_Allocate_per_CPU_data( areas, area_count );
|
||||
|
||||
page_size = CPU_HEAP_ALIGNMENT;
|
||||
|
||||
remaining = rtems_configuration_get_work_space_size();
|
||||
remaining += _Workspace_Space_for_TLS( page_size );
|
||||
remaining += _Workspace_Space_for_per_CPU_data( page_size );
|
||||
|
||||
init_or_extend = _Heap_Initialize;
|
||||
do_zero = rtems_configuration_get_do_zero_of_workspace();
|
||||
@@ -208,7 +227,6 @@ void _Workspace_Handler_initialization(
|
||||
}
|
||||
|
||||
_Heap_Protection_set_delayed_free_fraction( &_Workspace_Area, 1 );
|
||||
_Workspace_Allocate_per_CPU_data();
|
||||
}
|
||||
|
||||
void *_Workspace_Allocate(
|
||||
|
||||
@@ -237,6 +237,17 @@ smpfatal08_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_smpfatal08) \
|
||||
endif
|
||||
endif
|
||||
|
||||
if HAS_SMP
|
||||
if TEST_smpfatal09
|
||||
smp_tests += smpfatal09
|
||||
smp_screens += smpfatal09/smpfatal09.scn
|
||||
smp_docs += smpfatal09/smpfatal09.doc
|
||||
smpfatal09_SOURCES = smpfatal09/init.c
|
||||
smpfatal09_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_smpfatal09) \
|
||||
$(support_includes)
|
||||
endif
|
||||
endif
|
||||
|
||||
if HAS_SMP
|
||||
if TEST_smpipi01
|
||||
smp_tests += smpipi01
|
||||
|
||||
@@ -53,6 +53,7 @@ RTEMS_TEST_CHECK([smpfatal04])
|
||||
RTEMS_TEST_CHECK([smpfatal05])
|
||||
RTEMS_TEST_CHECK([smpfatal06])
|
||||
RTEMS_TEST_CHECK([smpfatal08])
|
||||
RTEMS_TEST_CHECK([smpfatal09])
|
||||
RTEMS_TEST_CHECK([smpipi01])
|
||||
RTEMS_TEST_CHECK([smpload01])
|
||||
RTEMS_TEST_CHECK([smplock01])
|
||||
|
||||
87
testsuites/smptests/smpfatal09/init.c
Normal file
87
testsuites/smptests/smpfatal09/init.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (C) 2018 embedded brains GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/score/percpudata.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
#include <tmacros.h>
|
||||
|
||||
static PER_CPU_DATA_ITEM(int, i) = 123;
|
||||
|
||||
const char rtems_test_name[] = "SMPFATAL 9";
|
||||
|
||||
static void Init( rtems_task_argument arg )
|
||||
{
|
||||
Heap_Area area = { .begin = NULL, .size = 0 };
|
||||
int i;
|
||||
|
||||
TEST_BEGIN();
|
||||
i = *PER_CPU_DATA_GET( _Per_CPU_Get_snapshot(), int, i );
|
||||
RTEMS_OBFUSCATE_VARIABLE( i );
|
||||
rtems_test_assert( i == 123 );
|
||||
|
||||
_Workspace_Handler_initialization( &area, 1, NULL );
|
||||
rtems_test_assert( 0 );
|
||||
}
|
||||
|
||||
static void fatal_extension(
|
||||
rtems_fatal_source source,
|
||||
bool always_set_to_false,
|
||||
rtems_fatal_code code
|
||||
)
|
||||
{
|
||||
if (
|
||||
source == INTERNAL_ERROR_CORE
|
||||
&& !always_set_to_false
|
||||
&& code == INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA
|
||||
) {
|
||||
TEST_END();
|
||||
}
|
||||
}
|
||||
|
||||
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
|
||||
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS \
|
||||
{ .fatal = fatal_extension }, \
|
||||
RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_PROCESSORS 2
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
#include <rtems/confdefs.h>
|
||||
11
testsuites/smptests/smpfatal09/smpfatal09.doc
Normal file
11
testsuites/smptests/smpfatal09/smpfatal09.doc
Normal file
@@ -0,0 +1,11 @@
|
||||
This file describes the directives and concepts tested by this test set.
|
||||
|
||||
test set name: smpfatal09
|
||||
|
||||
directives:
|
||||
|
||||
- _Workspace_Handler_initialization()
|
||||
|
||||
concepts:
|
||||
|
||||
- Provoke the INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA fatal error.
|
||||
7
testsuites/smptests/smpfatal09/smpfatal09.scn
Normal file
7
testsuites/smptests/smpfatal09/smpfatal09.scn
Normal file
@@ -0,0 +1,7 @@
|
||||
*** BEGIN OF TEST SMPFATAL 9 ***
|
||||
*** TEST VERSION: 5.0.0.cfa82b34b0c53ab4e3d84dd8ab5225793d48fcd0
|
||||
*** TEST STATE: EXPECTED-PASS
|
||||
*** TEST BUILD: RTEMS_SMP
|
||||
*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB ddba5372522da341fa20b2c75dfe966231cb6790, Newlib df6915f029ac9acd2b479ea898388cbd7dda4974)
|
||||
|
||||
*** END OF TEST SMPFATAL 9 ***
|
||||
@@ -36,7 +36,7 @@ static void test_internal_error_text(void)
|
||||
} while ( text != text_last );
|
||||
|
||||
rtems_test_assert(
|
||||
error - 3 == INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL
|
||||
error - 3 == INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
*** BEGIN OF TEST SPINTERNALERROR 2 ***
|
||||
*** TEST VERSION: 5.0.0.cfa82b34b0c53ab4e3d84dd8ab5225793d48fcd0
|
||||
*** TEST STATE: EXPECTED-PASS
|
||||
*** TEST BUILD:
|
||||
*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB ddba5372522da341fa20b2c75dfe966231cb6790, Newlib df6915f029ac9acd2b479ea898388cbd7dda4974)
|
||||
INTERNAL_ERROR_NO_CONFIGURATION_TABLE
|
||||
INTERNAL_ERROR_NO_CPU_TABLE
|
||||
INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
|
||||
@@ -31,6 +35,15 @@ INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK
|
||||
INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE
|
||||
INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL
|
||||
INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT
|
||||
INTERNAL_ERROR_RTEMS_INIT_TASK_CREATE_FAILED
|
||||
INTERNAL_ERROR_POSIX_INIT_THREAD_CREATE_FAILED
|
||||
INTERNAL_ERROR_LIBIO_USER_ENV_KEY_CREATE_FAILED
|
||||
INTERNAL_ERROR_LIBIO_SEM_CREATE_FAILED
|
||||
INTERNAL_ERROR_LIBIO_STDOUT_FD_OPEN_FAILED
|
||||
INTERNAL_ERROR_LIBIO_STDERR_FD_OPEN_FAILED
|
||||
INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT
|
||||
INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL
|
||||
INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA
|
||||
?
|
||||
?
|
||||
INTERNAL_ERROR_CORE
|
||||
@@ -79,4 +92,5 @@ RTEMS_IO_ERROR
|
||||
RTEMS_PROXY_BLOCKING
|
||||
?
|
||||
?
|
||||
|
||||
*** END OF TEST SPINTERNALERROR 2 ***
|
||||
|
||||
Reference in New Issue
Block a user