This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 90dcd5edd33b3c9929a3c29372f6b1fafd5834c7
Author: ligd <liguidi...@xiaomi.com>
AuthorDate: Thu May 30 11:05:24 2024 +0800

    critmonitor: add caller support
    
    Signed-off-by: ligd <liguidi...@xiaomi.com>
---
 fs/procfs/fs_procfsproc.c       | 10 ++++++----
 include/nuttx/sched.h           |  4 ++++
 sched/irq/irq_csection.c        |  8 ++++----
 sched/sched/sched.h             |  6 ++++--
 sched/sched/sched_critmonitor.c | 22 ++++++++++++++++------
 sched/sched/sched_lock.c        |  6 +++---
 sched/sched/sched_unlock.c      |  4 ++--
 7 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index 4a45f1ed9c..0a04aec23c 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -792,9 +792,10 @@ static ssize_t proc_critmon(FAR struct proc_file_s 
*procfile,
 
   /* Generate output for maximum time pre-emption disabled */
 
-  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,",
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu %p,",
                              (unsigned long)maxtime.tv_sec,
-                             (unsigned long)maxtime.tv_nsec);
+                             (unsigned long)maxtime.tv_nsec,
+                             tcb->premp_max_caller);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                            &offset);
 
@@ -827,9 +828,10 @@ static ssize_t proc_critmon(FAR struct proc_file_s 
*procfile,
 
   /* Generate output for maximum time in a critical section */
 
-  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,",
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu %p,",
                              (unsigned long)maxtime.tv_sec,
-                             (unsigned long)maxtime.tv_nsec);
+                             (unsigned long)maxtime.tv_nsec,
+                             tcb->crit_max_caller);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                            &offset);
 
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index e78a16ce80..bf844ed7ed 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -663,11 +663,15 @@ struct tcb_s
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
   clock_t premp_start;                   /* Time when preemption disabled   */
   clock_t premp_max;                     /* Max time preemption disabled    */
+  void   *premp_caller;                  /* Caller of preemption disabled   */
+  void   *premp_max_caller;              /* Caller of max preemption        */
 #endif
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
   clock_t crit_start;                    /* Time critical section entered   */
   clock_t crit_max;                      /* Max time in critical section    */
+  void   *crit_caller;                   /* Caller of critical section      */
+  void   *crit_max_caller;               /* Caller of max critical section  */
 #endif
 
   /* State save areas *******************************************************/
diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c
index 7209ddc87b..3397741a76 100644
--- a/sched/irq/irq_csection.c
+++ b/sched/irq/irq_csection.c
@@ -383,7 +383,7 @@ try_again_in_irq:
           /* Note that we have entered the critical section */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-          nxsched_critmon_csection(rtcb, true);
+          nxsched_critmon_csection(rtcb, true, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
           sched_note_csection(rtcb, true);
@@ -423,7 +423,7 @@ irqstate_t enter_critical_section(void)
           /* Note that we have entered the critical section */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-          nxsched_critmon_csection(rtcb, true);
+          nxsched_critmon_csection(rtcb, true, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
           sched_note_csection(rtcb, true);
@@ -524,7 +524,7 @@ void leave_critical_section(irqstate_t flags)
           /* No.. Note that we have left the critical section */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-          nxsched_critmon_csection(rtcb, false);
+          nxsched_critmon_csection(rtcb, false, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
           sched_note_csection(rtcb, false);
@@ -578,7 +578,7 @@ void leave_critical_section(irqstate_t flags)
           /* Note that we have left the critical section */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-          nxsched_critmon_csection(rtcb, false);
+          nxsched_critmon_csection(rtcb, false, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
           sched_note_csection(rtcb, false);
diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index 64abe7ba98..79c01eeada 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -447,11 +447,13 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb);
 #endif
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state);
+void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
+                                FAR void *caller);
 #endif
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state);
+void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
+                              FAR void *caller);
 #endif
 
 /* TCB operations */
diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c
index 72b9cf1669..16ae7287fe 100644
--- a/sched/sched/sched_critmonitor.c
+++ b/sched/sched/sched_critmonitor.c
@@ -180,11 +180,13 @@ static void nxsched_critmon_cpuload(FAR struct tcb_s 
*tcb, clock_t current,
  * Assumptions:
  *   - Called within a critical section.
  *   - Never called from an interrupt handler
+ *   - Caller is the address of the function that is changing the pre-emption
  *
  ****************************************************************************/
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
+void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
+                                FAR void *caller)
 {
   int cpu = this_cpu();
 
@@ -195,6 +197,7 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool 
state)
       /* Disabling.. Save the thread start time */
 
       tcb->premp_start   = perf_gettime();
+      tcb->premp_caller  = caller;
       g_premp_start[cpu] = tcb->premp_start;
     }
   else
@@ -206,7 +209,8 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool 
state)
 
       if (elapsed > tcb->premp_max)
         {
-          tcb->premp_max = elapsed;
+          tcb->premp_max        = elapsed;
+          tcb->premp_max_caller = tcb->premp_caller;
           CHECK_PREEMPTION(tcb->pid, elapsed);
         }
 
@@ -230,11 +234,13 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, 
bool state)
  * Assumptions:
  *   - Called within a critical section.
  *   - Never called from an interrupt handler
+ *   - Caller is the address of the function that is entering the critical
  *
  ****************************************************************************/
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state)
+void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state,
+                              FAR void *caller)
 {
   int cpu = this_cpu();
 
@@ -245,6 +251,7 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool 
state)
       /* Entering... Save the start time. */
 
       tcb->crit_start   = perf_gettime();
+      tcb->crit_caller  = caller;
       g_crit_start[cpu] = tcb->crit_start;
     }
   else
@@ -256,7 +263,8 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool 
state)
 
       if (elapsed > tcb->crit_max)
         {
-          tcb->crit_max = elapsed;
+          tcb->crit_max        = elapsed;
+          tcb->crit_max_caller = tcb->crit_caller;
           CHECK_CSECTION(tcb->pid, elapsed);
         }
 
@@ -386,7 +394,8 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
       elapsed = current - tcb->premp_start;
       if (elapsed > tcb->premp_max)
         {
-          tcb->premp_max = elapsed;
+          tcb->premp_max        = elapsed;
+          tcb->premp_max_caller = tcb->premp_caller;
           CHECK_PREEMPTION(tcb->pid, elapsed);
         }
     }
@@ -401,7 +410,8 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
       elapsed = current - tcb->crit_start;
       if (elapsed > tcb->crit_max)
         {
-          tcb->crit_max = elapsed;
+          tcb->crit_max        = elapsed;
+          tcb->crit_max_caller = tcb->crit_caller;
           CHECK_CSECTION(tcb->pid, elapsed);
         }
     }
diff --git a/sched/sched/sched_lock.c b/sched/sched/sched_lock.c
index 692eaa0d8e..0833b5746b 100644
--- a/sched/sched/sched_lock.c
+++ b/sched/sched/sched_lock.c
@@ -159,10 +159,10 @@ int sched_lock(void)
           /* Note that we have pre-emption locked */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-         nxsched_critmon_preemption(rtcb, true);
+          nxsched_critmon_preemption(rtcb, true, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
-         sched_note_premption(rtcb, true);
+          sched_note_premption(rtcb, true);
 #endif
         }
 
@@ -213,7 +213,7 @@ int sched_lock(void)
           /* Note that we have pre-emption locked */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-          nxsched_critmon_preemption(rtcb, true);
+          nxsched_critmon_preemption(rtcb, true, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
           sched_note_premption(rtcb, true);
diff --git a/sched/sched/sched_unlock.c b/sched/sched/sched_unlock.c
index 2f53774f34..0c42dd6be3 100644
--- a/sched/sched/sched_unlock.c
+++ b/sched/sched/sched_unlock.c
@@ -93,7 +93,7 @@ int sched_unlock(void)
           /* Note that we no longer have pre-emption disabled. */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-          nxsched_critmon_preemption(rtcb, false);
+          nxsched_critmon_preemption(rtcb, false, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
           sched_note_premption(rtcb, false);
@@ -250,7 +250,7 @@ int sched_unlock(void)
           /* Note that we no longer have pre-emption disabled. */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-          nxsched_critmon_preemption(rtcb, false);
+          nxsched_critmon_preemption(rtcb, false, return_address(0));
 #endif
 #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
           sched_note_premption(rtcb, false);

Reply via email to