[Bug 1935] New: SMP: nested locking count variable overwritten

bugzilla-daemon at rtems.org bugzilla-daemon at rtems.org
Tue Oct 11 16:28:26 UTC 2011


https://www.rtems.org/bugzilla/show_bug.cgi?id=1935

           Summary: SMP: nested locking count variable overwritten
           Product: RTEMS
           Version: HEAD
          Platform: All
        OS/Version: RTEMS
            Status: NEW
          Severity: normal
          Priority: P3
         Component: cpukit
        AssignedTo: joel.sherrill at oarcorp.com
        ReportedBy: daniel at gaisler.com


Created attachment 1353
  --> https://www.rtems.org/bugzilla/attachment.cgi?id=1353
SMP Nested locks patch

Hello,

Please see patch below, it tries to fix a problem when a nested lock is taken
more than once (lock->count > 1) and another CPU not owning it tries to acquire
it. What happens is that count is overwritten by SWAP with a value of 1, since
it is used as the locking variable as well. This could have been made working
if the CASA instruction was used.

To fix the problem I see no other solution than to add a locking variable, so I
did, please see below.

Regards,
Daniel


Index: cpukit/score/src/smplock.c
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/score/src/smplock.c,v
retrieving revision 1.4
diff -u -r1.4 smplock.c
--- cpukit/score/src/smplock.c    22 Aug 2011 18:26:08 -0000    1.4
+++ cpukit/score/src/smplock.c    11 Oct 2011 16:18:12 -0000
@@ -114,6 +114,7 @@
   SMP_lock_spinlock_nested_Control *lock
 )
 {
+  lock->lock = 0;
   lock->count = 0;
   lock->cpu_id = -1;
 }
@@ -143,8 +144,9 @@
   if (lock->count == 1) {
     lock->cpu_id = -1;
     debug_logit( 'U', lock );
-    RTEMS_COMPILER_MEMORY_BARRIER();
     lock->count  = 0;
+    RTEMS_COMPILER_MEMORY_BARRIER();
+    lock->lock = 0;
   } else {
     debug_logit( 'u', lock );
     lock->count--;
@@ -174,7 +176,7 @@
    */
   while (1) {
     RTEMS_COMPILER_MEMORY_BARRIER();
-    SMP_CPU_SWAP( &lock->count, value, previous );
+    SMP_CPU_SWAP( &lock->lock, value, previous );
     RTEMS_COMPILER_MEMORY_BARRIER();
     if ( previous == 0 ) {
       /* was not locked */
@@ -190,6 +192,7 @@
   }

   lock->cpu_id = cpu_id;
+  lock->count = 1;
   debug_logit( 'L', lock );

   return level;
Index: cpukit/score/include/rtems/score/smplock.h
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/score/include/rtems/score/smplock.h,v
retrieving revision 1.5
diff -u -r1.5 smplock.h
--- cpukit/score/include/rtems/score/smplock.h    1 Aug 2011 17:30:20 -0000   
1.5
+++ cpukit/score/include/rtems/score/smplock.h    11 Oct 2011 16:18:12 -0000
@@ -50,6 +50,7 @@
  *  times.
  */
 typedef struct {
+  SMP_lock_spinlock_simple_Control lock;
   uint32_t  count;
   int       cpu_id;
 } SMP_lock_spinlock_nested_Control;

-- 
Configure bugmail: https://www.rtems.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the bugs mailing list