#1937 closed defect (fixed)

SMP: inter processor interrupt message problems

Reported by: Daniel Hellstrom Owned by: Joel Sherrill
Priority: normal Milestone: 4.11
Component: score Version: 4.11
Severity: normal Keywords:
Cc: jennifer.averett@…, jiri@…, sebastian.huber@… Blocked By:
Blocking:

Description

Hello,

This patch contains several fixes in the same lines of code:

  1. a IPI should only be generated when the per-cpu core lock is taken, this is because a race may arise when two CPUs generate a IPI to the same CPU at the same time, or one CPU generates two IPIs in a row and the destination CPU is about to handle the incoming IPI. It could lead to percpu[dest_cpu].message becomes 0, and the lock is never returned (see IPI handler)
  1. IPI should not be generated unless message==0, this is of the same reason as above. The IRQ can have been ACKed by the receiving CPU but not handled yet, the sending CPU would generate another IRQ, then after the receiving CPU has handled the message another IRQ will be handled and then message=0 which will result in same dead lock as in 1.

Note that 1. and 2. has removed the use of broadcast IPI. The problems could probably have been solved in another way so that the broadcast could still be used.

  1. In _SMP_Broadcast_message() the lock is taken on the sending CPU (cpu) rather than the receiving CPU (dest_cpu).
  1. _SMP_Request_other_cores_to_dispatch() never sends IPIs to CPU0, I'm not sure this is incorrect due to my limited knowledge of the RTEMS SMP scheduler etc. But at a first glance it look incorrect to me.

Please see attached patch, or below.

Daniel

Index: cpukit/score/src/smp.c
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/score/src/smp.c,v
retrieving revision 1.9
diff -u -r1.9 smp.c
--- cpukit/score/src/smp.c 22 Aug 2011 18:26:08 -0000 1.9
+++ cpukit/score/src/smp.c 17 Oct 2011 11:15:22 -0000
@@ -176,9 +176,13 @@

#endif


level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );

  • _Per_CPU_Information[cpu].message |= message;

+ if (_Per_CPU_Information[cpu].message == 0) {
+ _Per_CPU_Information[cpu].message = message;
+ bsp_smp_interrupt_cpu( cpu );
+ } else {
+ _Per_CPU_Information[cpu].message |= message;
+ }

_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );

  • bsp_smp_interrupt_cpu( cpu ); }


/*

@@ -197,11 +201,15 @@

for ( dest_cpu=0 ; dest_cpu < _SMP_Processor_count; dest_cpu++ ) {

if ( cpu == dest_cpu )

continue;

  • level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
  • _Per_CPU_Information[dest_cpu].message |= message;
  • _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );

+ level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[dest_cpu].lock );
+ if (_Per_CPU_Information[dest_cpu].message == 0) {
+ _Per_CPU_Information[dest_cpu].message = message;
+ bsp_smp_interrupt_cpu( dest_cpu );
+ } else {
+ _Per_CPU_Information[dest_cpu].message |= message;
+ }
+ _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[dest_cpu].lock, level );

}

  • bsp_smp_broadcast_interrupt(); }


/*

@@ -230,7 +238,7 @@

if ( !_System_state_Is_up (_System_state_Current) )

return;

  • for (i=1 ; i < _SMP_Processor_count ; i++ ) {

+ for (i=0 ; i < _SMP_Processor_count ; i++ ) {

if ( cpu == i )

continue;

if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP )

Attachments (1)

smp2.patch (1.9 KB) - added by Daniel Hellstrom on Oct 17, 2011 at 10:20:54 AM.
SMP IPI patch

Download all attachments as: .zip

Change History (4)

Changed on Oct 17, 2011 at 10:20:54 AM by Daniel Hellstrom

Attachment: smp2.patch added

SMP IPI patch

comment:1 Changed on Oct 17, 2011 at 10:21:42 AM by Daniel Hellstrom

Cc: jennifer.averett@… jiri@… added

comment:2 Changed on Mar 31, 2014 at 7:34:37 AM by Sebastian Huber

Resolution: fixed
Status: newclosed, sebastian.huber@embedded-brains.de

This problem should be fixed in the current SMP code.

comment:3 Changed on Nov 24, 2014 at 6:58:28 PM by Gedare Bloom

Version: HEAD4.11

Replace Version=HEAD with Version=4.11 for the tickets with Milestone >= 4.11

Note: See TracTickets for help on using tickets.