Fatal exceptions on context-switching for more than two isolated threads

Utkarsh Rai utkarsh.rai60 at gmail.com
Tue Nov 10 15:53:18 UTC 2020


On Thu, Nov 5, 2020 at 11:45 AM Sebastian Huber <
sebastian.huber at embedded-brains.de> wrote:

> On 04/11/2020 19:38, Gedare Bloom wrote:
>
> >>   Based on the above suggestions I tried to move the
> User_extensions_Iterator storage to the TCB by adding a new field to the
> structure, but that did not compile(userextimpl.h is not included with
> thread.h because of cyclic dependency).
> >> This made me try out a naive hack, I defined a structure similar to the
> User_extensions_Iterator and then added the field to the TCB. The next
> problem that I faced was during the creation of the idle thread. Since an
> idle thread is created during system
> >> initialization, the 'executing' pointer pointing the TCB is null, and
> hence referencing to the iterator placed in the TCB for the idle thread
> fails. This was resolved by separating the cases for an idle thread and
> other threads. After that I was able to successfully isolate more than two
> thread stacks.
> >> Can you please suggest a more acceptable approach for resolving this
> issue?
> >>
> > At a high level the approach you took makes sense. You have moved the
> > user extensions to the TCB, and then avoid accessing it in case the
> > TCB is null (i.e., the initial context switch). I'd need to see the
> > code to make any further critical analysis. But it sounds acceptable
> > to me.
> The executing thread pointer can be NULL and there is already a check
> for this in _User_extensions_Iterate(). In this case you can use a
> member in the _Per_CPU_Information[].
>
> --
> Sebastian Huber, embedded brains GmbH
>
> Address : Dornierstr. 4, D-82178 Puchheim, Germany
> Phone   : +49 89 189 47 41-16
> Fax     : +49 89 189 47 41-09
> E-Mail  : sebastian.huber at embedded-brains.de
> PGP     : Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>
>
Based on your comments I have made the following changes in the user
extension iterator scheme. Some of the code is still hackish( if-else
conditional for handling TCB pointer when it is NULL ) and I would request
your suggestions on the same.

diff --git a/cpukit/include/rtems/score/percpu.h
b/cpukit/include/rtems/score/percpu.h
index 31bc2b0bff..6e15f4b1ba 100644
--- a/cpukit/include/rtems/score/percpu.h
+++ b/cpukit/include/rtems/score/percpu.h
@@ -25,7 +25,7 @@
   #include <rtems/asm.h>
 #else
   #include <rtems/score/assert.h>
-  #include <rtems/score/chain.h>
+  #include <rtems/score/chainimpl.h>
   #include <rtems/score/isrlock.h>
   #include <rtems/score/smp.h>
   #include <rtems/score/timestamp.h>
@@ -339,6 +339,20 @@ typedef enum {
   PER_CPU_WATCHDOG_COUNT
 } Per_CPU_Watchdog_index;

+#if defined ( RTEMS_THREAD_STACK_PROTECTION )
+  /**
+   * @brief  Per CPU user extensions iterator structure
+   *
+   * This structure is used to refer to the user extensions iterator when
+   * thread stack protection is configured.
+  */
+typedef struct Per_CPU_User_extensions_Iterator {
+  Chain_Iterator                   Iterator;
+  struct Per_CPU_User_extensions_Iterator *previous;
+} Per_CPU_User_extensions_Iterator;
+#endif
+
+
 /**
  *  @brief Per CPU Core Structure
  *
@@ -595,6 +609,10 @@ typedef struct Per_CPU_Control {
     bool boot;
   #endif

+  #if defined (RTEMS_THREAD_STACK_PROTECTION)
+    Per_CPU_User_extensions_Iterator iter;
+  #endif
+
   struct Record_Control *record;

   Per_CPU_Stats Stats;
diff --git a/cpukit/include/rtems/score/thread.h
b/cpukit/include/rtems/score/thread.h
index ee0aee5b79..98b85a66af 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -636,6 +636,13 @@ struct Thread_Action {
   Thread_Action_handler handler;
 };

+#if defined (RTEMS_THREAD_STACK_PROTECTION)
+  typedef struct Thread_User_extensions_Iterator {
+    Chain_Iterator                   Iterator;
+    struct Thread_User_extensions_Iterator *previous;
+  } Thread_User_extensions_Iterator;
+#endif
+
 /**
  * @brief Per-thread information for POSIX Keys.
  */
@@ -864,6 +871,10 @@ struct _Thread_Control {
    */
   struct _pthread_cleanup_context *last_cleanup_context;

+#if defined (RTEMS_THREAD_STACK_PROTECTION)
+  Thread_User_extensions_Iterator iter;
+#endif
+
   /**
    * @brief LIFO list of user extensions iterators.
    */
diff --git a/cpukit/score/src/userextiterate.c
b/cpukit/score/src/userextiterate.c
index 06665a2d7a..814e695018 100644
--- a/cpukit/score/src/userextiterate.c
+++ b/cpukit/score/src/userextiterate.c
@@ -181,22 +181,47 @@ void _User_extensions_Iterate(

   _User_extensions_Acquire( &lock_context );

-  _Chain_Iterator_initialize(
+  if ( executing != NULL ) {
+    executing->iter.previous = executing->last_user_extensions_iterator;
+    executing->last_user_extensions_iterator = &executing->iter;
+
+     _Chain_Iterator_initialize(
     &_User_extensions_List.Active,
     &_User_extensions_List.Iterators,
-    &iter.Iterator,
+    &executing->iter.Iterator,
     direction
   );

-  if ( executing != NULL ) {
-    iter.previous = executing->last_user_extensions_iterator;
-    executing->last_user_extensions_iterator = &iter;
+    while ( ( node = _Chain_Iterator_next( &executing->iter.Iterator ) )
!= end ) {
+    const User_extensions_Control *extension;
+
+    _Chain_Iterator_set_position( &executing->iter.Iterator, node );
+
+    _User_extensions_Release( &lock_context );
+
+    extension = (const User_extensions_Control *) node;
+    ( *visitor )( executing, arg, &extension->Callouts );
+
+    _User_extensions_Acquire( &lock_context );
   }

-  while ( ( node = _Chain_Iterator_next( &iter.Iterator ) ) != end ) {
+    executing->last_user_extensions_iterator = executing->iter.previous;
+
+  _Chain_Iterator_destroy( &executing->iter.Iterator );
+
+  } else {
+
+    _Chain_Iterator_initialize(
+    &_User_extensions_List.Active,
+    &_User_extensions_List.Iterators,
+    &_Per_CPU_Information[0].per_cpu.iter.Iterator,
+    direction
+  );
+
+    while ( ( node = _Chain_Iterator_next(
&_Per_CPU_Information[0].per_cpu.iter.Iterator ) ) != end ) {
     const User_extensions_Control *extension;

-    _Chain_Iterator_set_position( &iter.Iterator, node );
+    _Chain_Iterator_set_position(
&_Per_CPU_Information[0].per_cpu.iter.Iterator, node );

     _User_extensions_Release( &lock_context );

@@ -206,11 +231,9 @@ void _User_extensions_Iterate(
     _User_extensions_Acquire( &lock_context );
   }

-  if ( executing != NULL ) {
-    executing->last_user_extensions_iterator = iter.previous;
-  }
+  _Chain_Iterator_destroy( &_Per_CPU_Information->per_cpu.iter.Iterator );

-  _Chain_Iterator_destroy( &iter.Iterator );
+  }

   _User_extensions_Release( &lock_context );
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20201110/0c038b9d/attachment-0001.html>


More information about the devel mailing list