[rtems commit] score: Fix interrupt profiling

Sebastian Huber sebh at rtems.org
Thu Nov 24 08:13:13 UTC 2016


Module:    rtems
Branch:    master
Commit:    4b5ff47d159872ef9e1096713fd68367f4640576
Changeset: http://git.rtems.org/rtems/commit/?id=4b5ff47d159872ef9e1096713fd68367f4640576

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Nov 23 16:15:13 2016 +0100

score: Fix interrupt profiling

Callers of _Thread_Do_dispatch() must have a valid
Per_CPU_Control::Stats::thread_dispatch_disabled_instant.

Call _Profiling_Outer_most_interrupt_entry_and_exit() with the interrupt
stack to not exceed Per_CPU_Control::Interrupt_frame.

Update #2751.

---

 .../bspsupport/ppc_exc_async_normal.S              | 33 +++++++++-------------
 cpukit/score/include/rtems/score/profiling.h       |  6 ++++
 cpukit/score/src/profilingisrentryexit.c           | 19 +++++++++----
 3 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
index 34777e5..3162370 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
@@ -260,6 +260,9 @@ ppc_exc_wrap_async_normal:
 
 	/* Increment ISR nest level and thread dispatch disable level */
 	cmpwi	ISR_NEST_REGISTER, 0
+#ifdef RTEMS_PROFILING
+	cmpwi	cr2, ISR_NEST_REGISTER, 0
+#endif
 	addi	ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
 	addi	DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
 	stw	ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
@@ -285,6 +288,16 @@ ppc_exc_wrap_async_normal:
 	bl	bsp_interrupt_dispatch
 #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
 
+#ifdef RTEMS_PROFILING
+	/* Update profiling data if necessary */
+	bne	cr2, .Lprofiling_done
+	GET_SELF_CPU_CONTROL	r3
+	mr	r4, ENTRY_INSTANT_REGISTER
+	GET_TIME_BASE	r5
+	bl	_Profiling_Outer_most_interrupt_entry_and_exit
+.Lprofiling_done:
+#endif /* RTEMS_PROFILING */
+
 	/* Load some per-CPU variables */
 	GET_SELF_CPU_CONTROL	SELF_CPU_REGISTER
 	lbz	SCRATCH_0_REGISTER, PER_CPU_DISPATCH_NEEDED(SELF_CPU_REGISTER)
@@ -304,37 +317,17 @@ ppc_exc_wrap_async_normal:
 	or	SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, SCRATCH_1_REGISTER
 	subi	DISPATCH_LEVEL_REGISTER, SCRATCH_2_REGISTER, 1
 	or.	SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, DISPATCH_LEVEL_REGISTER
-#ifdef RTEMS_PROFILING
-	cmpwi	cr2, SCRATCH_0_REGISTER, 0
-	subic.	ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
-#else
 	subi	ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
-#endif
 
 	/* Store thread dispatch disable and ISR nest levels */
 	stw	DISPATCH_LEVEL_REGISTER, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
 	stw	ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
 
-#ifdef RTEMS_PROFILING
-	/* Store profiling data if necessary */
-	bne	.Lprofiling_done
-	mr	r3, SELF_CPU_REGISTER
-	mr	r4, ENTRY_INSTANT_REGISTER
-	GET_TIME_BASE	r5
-	bl	_Profiling_Outer_most_interrupt_entry_and_exit
-	GET_SELF_CPU_CONTROL	SELF_CPU_REGISTER
-.Lprofiling_done:
-#endif /* RTEMS_PROFILING */
-
 	/*
 	 * Check thread dispatch necessary, ISR dispatch disable and thread
 	 * dispatch disable level.
 	 */
-#ifdef RTEMS_PROFILING
-	bne	cr2, .Lthread_dispatch_done
-#else
 	bne	.Lthread_dispatch_done
-#endif
 
 	/* Thread dispatch */
 .Ldo_thread_dispatch:
diff --git a/cpukit/score/include/rtems/score/profiling.h b/cpukit/score/include/rtems/score/profiling.h
index a6ab283..6ba5d29 100644
--- a/cpukit/score/include/rtems/score/profiling.h
+++ b/cpukit/score/include/rtems/score/profiling.h
@@ -119,6 +119,12 @@ static inline void _Profiling_Update_max_interrupt_delay(
 #endif
 }
 
+/**
+ * @brief Updates the interrupt profiling statistics.
+ *
+ * Must be called with the interrupt stack and before the thread dispatch
+ * disable level is decremented.
+ */
 void _Profiling_Outer_most_interrupt_entry_and_exit(
   Per_CPU_Control *cpu,
   CPU_Counter_ticks interrupt_entry_instant,
diff --git a/cpukit/score/src/profilingisrentryexit.c b/cpukit/score/src/profilingisrentryexit.c
index c7842a5..98df154 100644
--- a/cpukit/score/src/profilingisrentryexit.c
+++ b/cpukit/score/src/profilingisrentryexit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -17,6 +17,7 @@
 #endif
 
 #include <rtems/score/profiling.h>
+#include <rtems/score/assert.h>
 
 void _Profiling_Outer_most_interrupt_entry_and_exit(
   Per_CPU_Control *cpu,
@@ -24,19 +25,27 @@ void _Profiling_Outer_most_interrupt_entry_and_exit(
   CPU_Counter_ticks interrupt_exit_instant
 )
 {
-#if defined( RTEMS_PROFILING )
-  Per_CPU_Stats *stats = &cpu->Stats;
-  CPU_Counter_ticks delta = _CPU_Counter_difference(
+#if defined(RTEMS_PROFILING)
+  Per_CPU_Stats     *stats;
+  CPU_Counter_ticks  delta;
+
+  _Assert( cpu->isr_nest_level == 1 );
+
+  stats = &cpu->Stats;
+  delta = _CPU_Counter_difference(
     interrupt_exit_instant,
     interrupt_entry_instant
   );
-
   ++stats->interrupt_count;
   stats->total_interrupt_time += delta;
 
   if ( stats->max_interrupt_time < delta ) {
     stats->max_interrupt_time = delta;
   }
+
+  if ( cpu->thread_dispatch_disable_level == 1 ) {
+    stats->thread_dispatch_disabled_instant = interrupt_entry_instant;
+  }
 #else
   (void) cpu;
   (void) interrupt_entry_instant;




More information about the vc mailing list