You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/07/02 13:25:08 UTC

[incubator-nuttx] branch master updated (b86bcff -> adfaa14)

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

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


    from b86bcff  serial: add ioctl TIOCNOTTY
     new 2c775bb  fs/procfs: fix heap overflow when snprintf meet long string
     new dbdb24e  procfs: fix cat status error when meet long thread name
     new 2d32a52  sched_critmon: add thread run time to critmonitor
     new adfaa14  sched: add CONFIG_SCHED_CRITMONITOR_XX for debugging system lantency

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 fs/procfs/fs_procfs.c           |   2 +-
 fs/procfs/fs_procfscpuload.c    |   6 +-
 fs/procfs/fs_procfscritmon.c    |  12 +--
 fs/procfs/fs_procfsiobinfo.c    |  24 +++---
 fs/procfs/fs_procfsmeminfo.c    |  43 +++++-----
 fs/procfs/fs_procfsproc.c       | 180 +++++++++++++++++++++++++---------------
 fs/procfs/fs_procfsuptime.c     |  11 +--
 fs/procfs/fs_procfsutil.c       |  29 +++++++
 fs/procfs/fs_procfsversion.c    |   5 +-
 include/nuttx/fs/procfs.h       |  20 +++++
 include/nuttx/sched.h           |   2 +
 sched/Kconfig                   |  52 ++++++++++++
 sched/irq/irq_dispatch.c        |  10 +++
 sched/sched/sched_critmonitor.c | 100 ++++++++++++++++++++--
 sched/wdog/wd_start.c           |  26 +++++-
 sched/wqueue/kwork_process.c    |  27 +++++-
 16 files changed, 419 insertions(+), 130 deletions(-)

[incubator-nuttx] 03/04: sched_critmon: add thread run time to critmonitor

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit 2d32a52353c2adbab9487b1f88a6be3212c996d8
Author: ligd <li...@xiaomi.com>
AuthorDate: Fri May 7 17:55:24 2021 +0800

    sched_critmon: add thread run time to critmonitor
    
    Change-Id: Ib44e45f0f9a1b249b4067db324c9dbdf0cf3f288
    Signed-off-by: ligd <li...@xiaomi.com>
---
 fs/procfs/fs_procfsproc.c       | 37 +++++++++++++++++++++++++++++++++++--
 include/nuttx/sched.h           |  2 ++
 sched/sched/sched_critmonitor.c | 29 ++++++++++++++++++++---------
 3 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index f823543..fd532db 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -802,7 +802,7 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
   linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,",
                              (unsigned long)maxtime.tv_sec,
                              (unsigned long)maxtime.tv_nsec);
-  copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
+  copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                            &offset);
 
   totalsize += copysize;
@@ -832,10 +832,43 @@ 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,",
+                             (unsigned long)maxtime.tv_sec,
+                             (unsigned long)maxtime.tv_nsec);
+  copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                           &offset);
+
+  totalsize += copysize;
+  buffer    += copysize;
+  remaining -= copysize;
+
+  if (totalsize >= buflen)
+    {
+      return totalsize;
+    }
+
+  /* Convert and generate output for maximum time thread running */
+
+  if (tcb->run_max > 0)
+    {
+      up_critmon_convert(tcb->run_max, &maxtime);
+    }
+  else
+    {
+      maxtime.tv_sec = 0;
+      maxtime.tv_nsec = 0;
+    }
+
+  /* Reset the maximum */
+
+  tcb->run_max = 0;
+
+  /* Generate output for maximum time thread running */
+
   linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu\n",
                              (unsigned long)maxtime.tv_sec,
                              (unsigned long)maxtime.tv_nsec);
-  copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
+  copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                            &offset);
 
   totalsize += copysize;
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index d54e04f..e5577bb 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -707,6 +707,8 @@ struct tcb_s
   uint32_t premp_max;                    /* Max time preemption disabled        */
   uint32_t crit_start;                   /* Time critical section entered       */
   uint32_t crit_max;                     /* Max time in critical section        */
+  uint32_t run_start;                    /* Time when thread begin run          */
+  uint32_t run_max;                      /* Max time thread run                 */
 #endif
 
   /* State save areas *******************************************************/
diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c
index 55611c1..97862b7 100644
--- a/sched/sched/sched_critmonitor.c
+++ b/sched/sched/sched_critmonitor.c
@@ -208,10 +208,14 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state)
 
 void nxsched_resume_critmon(FAR struct tcb_s *tcb)
 {
-  uint32_t elapsed;
+  uint32_t current = up_critmon_gettime();
   int cpu = this_cpu();
+  uint32_t elapsed;
+
+  DEBUGASSERT(tcb->premp_start == 0 && tcb->crit_start == 0 &&
+              tcb->run_start == 0);
 
-  DEBUGASSERT(tcb->premp_start == 0 && tcb->crit_start == 0);
+  tcb->run_start = current;
 
   /* Did this task disable pre-emption? */
 
@@ -219,7 +223,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
     {
       /* Yes.. Save the start time */
 
-      tcb->premp_start = up_critmon_gettime();
+      tcb->premp_start = current;
       DEBUGASSERT(tcb->premp_start != 0);
 
       /* Zero means that the timer is not ready */
@@ -233,7 +237,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
     {
       /* Check for the global max elapsed time */
 
-      elapsed            = up_critmon_gettime() - g_premp_start[cpu];
+      elapsed            = current - g_premp_start[cpu];
       g_premp_start[cpu] = 0;
 
       if (elapsed > g_premp_max[cpu])
@@ -248,7 +252,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
     {
       /* Yes.. Save the start time */
 
-      tcb->crit_start = up_critmon_gettime();
+      tcb->crit_start = current;
       DEBUGASSERT(tcb->crit_start != 0);
 
       if (g_crit_start[cpu] == 0)
@@ -260,7 +264,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
     {
       /* Check for the global max elapsed time */
 
-      elapsed      = up_critmon_gettime() - g_crit_start[cpu];
+      elapsed      = current - g_crit_start[cpu];
       g_crit_start[cpu] = 0;
 
       if (elapsed > g_crit_max[cpu])
@@ -285,7 +289,14 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
 
 void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
 {
-  uint32_t elapsed;
+  uint32_t current = up_critmon_gettime();
+  uint32_t elapsed = current - tcb->run_start;
+
+  tcb->run_start = 0;
+  if (elapsed > tcb->run_max)
+    {
+      tcb->run_max = elapsed;
+    }
 
   /* Did this task disable preemption? */
 
@@ -293,7 +304,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
     {
       /* Possibly re-enabling.. Check for the max elapsed time */
 
-      elapsed = up_critmon_gettime() - tcb->premp_start;
+      elapsed = current - tcb->premp_start;
 
       tcb->premp_start = 0;
       if (elapsed > tcb->premp_max)
@@ -308,7 +319,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
     {
       /* Possibly leaving .. Check for the max elapsed time */
 
-      elapsed = up_critmon_gettime() - tcb->crit_start;
+      elapsed = current - tcb->crit_start;
 
       tcb->crit_start = 0;
       if (elapsed > tcb->crit_max)

[incubator-nuttx] 01/04: fs/procfs: fix heap overflow when snprintf meet long string

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit 2c775bb0c9e0ebdbdac4af717c49a55525cc2e1f
Author: ligd <li...@xiaomi.com>
AuthorDate: Wed Apr 14 22:37:52 2021 +0800

    fs/procfs: fix heap overflow when snprintf meet long string
    
    Change-Id: I90f2d9fab55b6e69f159855af3d6dbcb81142eb8
    Signed-off-by: ligd <li...@xiaomi.com>
---
 fs/procfs/fs_procfs.c        |   2 +-
 fs/procfs/fs_procfscpuload.c |   6 +-
 fs/procfs/fs_procfscritmon.c |  12 ++--
 fs/procfs/fs_procfsiobinfo.c |  24 ++++----
 fs/procfs/fs_procfsmeminfo.c |  43 ++++++-------
 fs/procfs/fs_procfsproc.c    | 143 +++++++++++++++++++++++--------------------
 fs/procfs/fs_procfsuptime.c  |  11 ++--
 fs/procfs/fs_procfsutil.c    |  29 +++++++++
 fs/procfs/fs_procfsversion.c |   5 +-
 include/nuttx/fs/procfs.h    |  20 ++++++
 10 files changed, 178 insertions(+), 117 deletions(-)

diff --git a/fs/procfs/fs_procfs.c b/fs/procfs/fs_procfs.c
index 0c227b5..3376a24 100644
--- a/fs/procfs/fs_procfs.c
+++ b/fs/procfs/fs_procfs.c
@@ -830,7 +830,7 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
           /* Save the filename=pid and file type=directory */
 
           dir->fd_dir.d_type = DTYPE_DIRECTORY;
-          snprintf(dir->fd_dir.d_name, NAME_MAX + 1, "%d", (int)pid);
+          procfs_snprintf(dir->fd_dir.d_name, NAME_MAX + 1, "%d", (int)pid);
 
           /* Set up the next directory entry offset.  NOTE that we could use
            * the standard f_pos instead of our own private index.
diff --git a/fs/procfs/fs_procfscpuload.c b/fs/procfs/fs_procfscpuload.c
index 6cf8af3..5602c95 100644
--- a/fs/procfs/fs_procfscpuload.c
+++ b/fs/procfs/fs_procfscpuload.c
@@ -238,9 +238,9 @@ static ssize_t cpuload_read(FAR struct file *filep, FAR char *buffer,
           fracpart = 0;
         }
 
-      linesize = snprintf(attr->line, CPULOAD_LINELEN,
-                          "%3" PRId32 ".%01" PRId32 "%%\n",
-                          intpart, fracpart);
+      linesize = procfs_snprintf(attr->line, CPULOAD_LINELEN,
+                                 "%3" PRId32 ".%01" PRId32 "%%\n",
+                                 intpart, fracpart);
 
       /* Save the linesize in case we are re-entered with f_pos > 0 */
 
diff --git a/fs/procfs/fs_procfscritmon.c b/fs/procfs/fs_procfscritmon.c
index cb65bbf..3050248 100644
--- a/fs/procfs/fs_procfscritmon.c
+++ b/fs/procfs/fs_procfscritmon.c
@@ -215,9 +215,9 @@ static ssize_t critmon_read_cpu(FAR struct critmon_file_s *attr,
 
   /* Generate output for maximum time pre-emption disabled */
 
-  linesize = snprintf(attr->line, CRITMON_LINELEN, "%d,%lu.%09lu,",
-                     cpu, (unsigned long)maxtime.tv_sec,
-                     (unsigned long)maxtime.tv_nsec);
+  linesize = procfs_snprintf(attr->line, CRITMON_LINELEN, "%d,%lu.%09lu,",
+                             cpu, (unsigned long)maxtime.tv_sec,
+                             (unsigned long)maxtime.tv_nsec);
   copysize = procfs_memcpy(attr->line, linesize, buffer, buflen, offset);
 
   totalsize += copysize;
@@ -247,9 +247,9 @@ static ssize_t critmon_read_cpu(FAR struct critmon_file_s *attr,
 
   /* Generate output for maximum time in a critical section */
 
-  linesize = snprintf(attr->line, CRITMON_LINELEN, "%lu.%09lu\n",
-                     (unsigned long)maxtime.tv_sec,
-                     (unsigned long)maxtime.tv_nsec);
+  linesize = procfs_snprintf(attr->line, CRITMON_LINELEN, "%lu.%09lu\n",
+                             (unsigned long)maxtime.tv_sec,
+                             (unsigned long)maxtime.tv_nsec);
   copysize = procfs_memcpy(attr->line, linesize, buffer, buflen, offset);
 
   totalsize += copysize;
diff --git a/fs/procfs/fs_procfsiobinfo.c b/fs/procfs/fs_procfsiobinfo.c
index b7da24a..48d7902 100644
--- a/fs/procfs/fs_procfsiobinfo.c
+++ b/fs/procfs/fs_procfsiobinfo.c
@@ -280,7 +280,7 @@ static ssize_t iobinfo_read(FAR struct file *filep, FAR char *buffer,
 
   /* The first line is the headers */
 
-  linesize  = snprintf(iobfile->line, IOBINFO_LINELEN,
+  linesize  = procfs_snprintf(iobfile->line, IOBINFO_LINELEN,
                        "                           TOTAL           TOTAL\n");
 
   copysize  = procfs_memcpy(iobfile->line, linesize, buffer, buflen,
@@ -292,7 +292,7 @@ static ssize_t iobinfo_read(FAR struct file *filep, FAR char *buffer,
       buffer    += copysize;
       buflen    -= copysize;
 
-      linesize  = snprintf(iobfile->line, IOBINFO_LINELEN,
+      linesize  = procfs_snprintf(iobfile->line, IOBINFO_LINELEN,
                            "        USER            CONSUMED        "
                            "PRODUCED\n");
 
@@ -311,11 +311,11 @@ static ssize_t iobinfo_read(FAR struct file *filep, FAR char *buffer,
           buflen    -= copysize;
 
           userstats  = iob_getuserstats(i);
-          linesize   = snprintf(iobfile->line, IOBINFO_LINELEN,
-                                "%-16s%16lu%16lu\n",
-                                g_iob_user_names[i],
-                                (unsigned long)userstats->totalconsumed,
-                                (unsigned long)userstats->totalproduced);
+          linesize   = procfs_snprintf(iobfile->line, IOBINFO_LINELEN,
+                                    "%-16s%16lu%16lu\n",
+                                    g_iob_user_names[i],
+                                    (unsigned long)userstats->totalconsumed,
+                                    (unsigned long)userstats->totalproduced);
 
           copysize   = procfs_memcpy(iobfile->line, linesize, buffer, buflen,
                                      &offset);
@@ -329,11 +329,11 @@ static ssize_t iobinfo_read(FAR struct file *filep, FAR char *buffer,
       buflen    -= copysize;
 
       userstats  = iob_getuserstats(IOBUSER_GLOBAL);
-      linesize   = snprintf(iobfile->line, IOBINFO_LINELEN,
-                            "\n%-16s%16lu%16lu\n",
-                            g_iob_user_names[IOBUSER_GLOBAL],
-                            (unsigned long)userstats->totalconsumed,
-                            (unsigned long)userstats->totalproduced);
+      linesize   = procfs_snprintf(iobfile->line, IOBINFO_LINELEN,
+                                   "\n%-16s%16lu%16lu\n",
+                                   g_iob_user_names[IOBUSER_GLOBAL],
+                                   (unsigned long)userstats->totalconsumed,
+                                   (unsigned long)userstats->totalproduced);
 
       copysize   = procfs_memcpy(iobfile->line, linesize, buffer, buflen,
                                  &offset);
diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c
index ebef16a..3f2d1a4 100644
--- a/fs/procfs/fs_procfsmeminfo.c
+++ b/fs/procfs/fs_procfsmeminfo.c
@@ -287,7 +287,7 @@ static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
   /* The first line is the headers */
 
   linesize  =
-    snprintf(procfile->line, MEMINFO_LINELEN,
+    procfs_snprintf(procfile->line, MEMINFO_LINELEN,
              "                     "
              "total       used       free    largest  nused  nfree\n");
 
@@ -311,15 +311,16 @@ static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
           /* Show heap information */
 
           entry->mallinfo(entry->user_data, &minfo);
-          linesize   = snprintf(procfile->line, MEMINFO_LINELEN,
-                                "%12s:  %11lu%11lu%11lu%11lu%7lu%7lu\n",
-                                entry->name,
-                                (unsigned long)minfo.arena,
-                                (unsigned long)minfo.uordblks,
-                                (unsigned long)minfo.fordblks,
-                                (unsigned long)minfo.mxordblk,
-                                (unsigned long)minfo.aordblks,
-                                (unsigned long)minfo.ordblks);
+          linesize   = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
+                                       "%12s:  "
+                                       "%11lu%11lu%11lu%11lu%7lu%7lu\n",
+                                       entry->name,
+                                       (unsigned long)minfo.arena,
+                                       (unsigned long)minfo.uordblks,
+                                       (unsigned long)minfo.fordblks,
+                                       (unsigned long)minfo.mxordblk,
+                                       (unsigned long)minfo.aordblks,
+                                       (unsigned long)minfo.ordblks);
           copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                                      buflen, &offset);
           totalsize += copysize;
@@ -347,9 +348,9 @@ static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
       allocated  = total - available;
       max        = (unsigned long)pginfo.mxfree << MM_PGSHIFT;
 
-      linesize   = snprintf(procfile->line, MEMINFO_LINELEN,
-                            "Page:  %11lu%11lu%11lu%11lu\n",
-                            total, allocated, available, max);
+      linesize   = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
+                                   "Page:  %11lu%11lu%11lu%11lu\n",
+                                   total, allocated, available, max);
 
       copysize   = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                                  &offset);
@@ -369,14 +370,14 @@ static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
 
       meminfo_progmem(&progmem);
 
-      linesize   = snprintf(procfile->line, MEMINFO_LINELEN,
-                            "Prog:  %11lu%11lu%11lu%11lu%7lu%7lu\n",
-                            (unsigned long)progmem.arena,
-                            (unsigned long)progmem.uordblks,
-                            (unsigned long)progmem.fordblks,
-                            (unsigned long)progmem.mxordblk,
-                            (unsigned long)progmem.aordblks,
-                            (unsigned long)progmem.ordblks);
+      linesize   = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
+                                   "Prog:  %11lu%11lu%11lu%11lu%7lu%7lu\n",
+                                   (unsigned long)progmem.arena,
+                                   (unsigned long)progmem.uordblks,
+                                   (unsigned long)progmem.fordblks,
+                                   (unsigned long)progmem.mxordblk,
+                                   (unsigned long)progmem.aordblks,
+                                   (unsigned long)progmem.ordblks);
       copysize   = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                                  &offset);
       totalsize += copysize;
diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index c6d0d45..47d062a 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -459,8 +459,8 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 #else
   name       = "<noname>";
 #endif
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
-                        "Name:", name);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
+                               "Name:", name);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -475,11 +475,12 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 
   /* Show the thread type */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n", "Type:",
-                        g_ttypenames[(tcb->flags & TCB_FLAG_TTYPE_MASK) >>
-                        TCB_FLAG_TTYPE_SHIFT]);
-  copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
-                             &offset);
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
+                             "Type:",
+                             g_ttypenames[(tcb->flags & TCB_FLAG_TTYPE_MASK)
+                             >>  TCB_FLAG_TTYPE_SHIFT]);
+  copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                           &offset);
 
   totalsize += copysize;
   buffer    += copysize;
@@ -493,8 +494,9 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
   group = tcb->group;
   DEBUGASSERT(group != NULL);
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n", "PPID:",
-                        group->tg_ppid);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d\n", "PPID:",
+                               group->tg_ppid);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -511,13 +513,13 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
   if (tcb->task_state >= FIRST_ASSIGNED_STATE &&
       tcb->task_state <= LAST_ASSIGNED_STATE)
     {
-      linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
-                            "CPU:", tcb->cpu);
+      linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                                   "%-12s%d\n", "CPU:", tcb->cpu);
     }
   else
     {
-      linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s---\n",
-                            "CPU:");
+      linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                                   "%-12s---\n", "CPU:");
     }
 
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
@@ -535,8 +537,9 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 
   /* Show the thread state */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
-                        "State:", g_statenames[tcb->task_state]);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%s\n", "State:",
+                               g_statenames[tcb->task_state]);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -551,11 +554,11 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 
   /* Show task flags */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN,
-                        "%-12s%c%c%c\n", "Flags:",
-                        tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : '-',
-                        tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : '-',
-                        tcb->flags & TCB_FLAG_EXIT_PROCESSING ? 'P' : '-');
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                          "%-12s%c%c%c\n", "Flags:",
+                          tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : '-',
+                          tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : '-',
+                          tcb->flags & TCB_FLAG_EXIT_PROCESSING ? 'P' : '-');
 
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
@@ -572,12 +575,12 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
   /* Show the thread priority */
 
 #ifdef CONFIG_PRIORITY_INHERITANCE
-  linesize   = snprintf(procfile->line, STATUS_LINELEN,
-                        "%-12s%d (%d)\n", "Priority:",
-                        tcb->sched_priority, tcb->base_priority);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d (%d)\n", "Priority:",
+                               tcb->sched_priority, tcb->base_priority);
 #else
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
-                        "Priority:", tcb->sched_priority);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
+                               "Priority:", tcb->sched_priority);
 #endif
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
@@ -595,8 +598,8 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 
   policy     = g_policy[(tcb->flags & TCB_FLAG_POLICY_MASK) >>
                         TCB_FLAG_POLICY_SHIFT];
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
-                        "Scheduler:", policy);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
+                               "Scheduler:", policy);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -611,8 +614,9 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 
   /* Show the signal mask. Note: sigset_t is uint32_t on NuttX. */
 
-  linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%08" PRIx32 "\n",
-                      "SigMask:", tcb->sigprocmask);
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                             "%-12s%08" PRIx32 "\n",
+                             "SigMask:", tcb->sigprocmask);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                            &offset);
 
@@ -667,8 +671,8 @@ static ssize_t proc_cmdline(FAR struct proc_file_s *procfile,
     {
       FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s *)tcb;
 
-      linesize   = snprintf(procfile->line, STATUS_LINELEN, " %p\n",
-                            ptcb->arg);
+      linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, " %p\n",
+                                   ptcb->arg);
       copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                                  remaining, &offset);
 
@@ -686,7 +690,8 @@ static ssize_t proc_cmdline(FAR struct proc_file_s *procfile,
 
   for (argv = ttcb->argv + 1; *argv; argv++)
     {
-      linesize   = snprintf(procfile->line, STATUS_LINELEN, " %s", *argv);
+      linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                                   " %s", *argv);
       copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                                  remaining, &offset);
 
@@ -700,7 +705,7 @@ static ssize_t proc_cmdline(FAR struct proc_file_s *procfile,
         }
     }
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "\n");
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "\n");
   copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                              remaining, &offset);
 
@@ -748,9 +753,9 @@ static ssize_t proc_loadavg(FAR struct proc_file_s *procfile,
       fracpart = 0;
     }
 
-  linesize = snprintf(procfile->line, STATUS_LINELEN,
-                      "%3" PRId32 ".%01" PRId32 "%%",
-                      intpart, fracpart);
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                             "%3" PRId32 ".%01" PRId32 "%%",
+                             intpart, fracpart);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                            &offset);
 
@@ -794,9 +799,9 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
 
   /* Generate output for maximum time pre-emption disabled */
 
-  linesize = snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,",
-                     (unsigned long)maxtime.tv_sec,
-                     (unsigned long)maxtime.tv_nsec);
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu,",
+                             (unsigned long)maxtime.tv_sec,
+                             (unsigned long)maxtime.tv_nsec);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                            &offset);
 
@@ -827,9 +832,9 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
 
   /* Generate output for maximum time in a critical section */
 
-  linesize = snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu\n",
-                     (unsigned long)maxtime.tv_sec,
-                     (unsigned long)maxtime.tv_nsec);
+  linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%lu.%09lu\n",
+                             (unsigned long)maxtime.tv_sec,
+                             (unsigned long)maxtime.tv_nsec);
   copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                            &offset);
 
@@ -872,8 +877,8 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
 
   /* Show the stack base address */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%p\n",
-                        "StackBase:", tcb->stack_base_ptr);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%p\n",
+                               "StackBase:", tcb->stack_base_ptr);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -888,8 +893,8 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
 
   /* Show the stack size */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
-                        "StackSize:", (long)tcb->adj_stack_size);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
+                               "StackSize:", (long)tcb->adj_stack_size);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -905,8 +910,8 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
 
   /* Show the stack size */
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
-                        "StackUsed:", (long)up_check_tcbstack(tcb));
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
+                               "StackUsed:", (long)up_check_tcbstack(tcb));
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -940,8 +945,8 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
   remaining = buflen;
   totalsize = 0;
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
-                        "Main task:", group->tg_pid);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
+                               "Main task:", group->tg_pid);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                              remaining, &offset);
 
@@ -954,8 +959,9 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
       return totalsize;
     }
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s0x%02x\n",
-                        "Flags:", group->tg_flags);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s0x%02x\n",
+                               "Flags:", group->tg_flags);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                              remaining, &offset);
 
@@ -968,8 +974,8 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
       return totalsize;
     }
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
-                        "Members:", group->tg_nmembers);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
+                               "Members:", group->tg_nmembers);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                             remaining, &offset);
 
@@ -983,7 +989,8 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
       return totalsize;
     }
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "Member IDs:");
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "Member IDs:");
   copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                              remaining, &offset);
 
@@ -998,8 +1005,8 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
 
   for (i = 0; i < group->tg_nmembers; i++)
     {
-      linesize   = snprintf(procfile->line, STATUS_LINELEN, " %d",
-                            group->tg_members[i]);
+      linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, " %d",
+                                   group->tg_members[i]);
       copysize   = procfs_memcpy(procfile->line, linesize, buffer,
                                  remaining, &offset);
 
@@ -1013,7 +1020,7 @@ static ssize_t proc_groupstatus(FAR struct proc_file_s *procfile,
         }
     }
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "\n");
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "\n");
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -1047,8 +1054,9 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
   remaining = buflen;
   totalsize = 0;
 
-  linesize   = snprintf(procfile->line, STATUS_LINELEN, "\n%-3s %-8s %s\n",
-                        "FD", "POS", "OFLAGS");
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "\n%-3s %-8s %s\n",
+                               "FD", "POS", "OFLAGS");
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -1073,7 +1081,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
 
           if (file->f_inode && !INODE_IS_SOCKET(file->f_inode))
             {
-              linesize   = snprintf(procfile->line, STATUS_LINELEN,
+              linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
                                     "%3d %8ld %04x\n",
                                     i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK +
                                     j, (long)file->f_pos,
@@ -1094,9 +1102,9 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
     }
 
 #ifdef CONFIG_NET
-  linesize   = snprintf(procfile->line, STATUS_LINELEN,
-                        "\n%-3s %-2s %-3s %s\n",
-                        "SD", "RF", "TYP", "FLAGS");
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "\n%-3s %-2s %-3s %s\n",
+                               "SD", "RF", "TYP", "FLAGS");
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
@@ -1122,7 +1130,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
           if (file->f_inode && INODE_IS_SOCKET(file->f_inode))
             {
               FAR struct socket *socket = file->f_priv;
-              linesize   = snprintf(procfile->line, STATUS_LINELEN,
+              linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
                                     "%3d %3d %02x",
                                     i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK +
                                     j, socket->s_type,
@@ -1195,8 +1203,9 @@ static int proc_groupenv_callback(FAR void *arg, FAR const char *pair)
 
   /* Output the header */
 
-  linesize        = snprintf(info->procfile->line, STATUS_LINELEN, "%s=%s\n",
-                             name, value);
+  linesize        = procfs_snprintf(info->procfile->line,
+                                    STATUS_LINELEN, "%s=%s\n",
+                                    name, value);
   copysize        = procfs_memcpy(info->procfile->line, linesize,
                                   info->buffer, info->remaining,
                                   &info->offset);
diff --git a/fs/procfs/fs_procfsuptime.c b/fs/procfs/fs_procfsuptime.c
index c17a95a..c7181d1 100644
--- a/fs/procfs/fs_procfsuptime.c
+++ b/fs/procfs/fs_procfsuptime.c
@@ -231,7 +231,8 @@ static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
       /* Convert the up time to a seconds + hundredths of seconds string */
 
       now       = (double)ticktime / (double)CLOCKS_PER_SEC;
-      linesize  = snprintf(attr->line, UPTIME_LINELEN, "%10.2f\n", now);
+      linesize  = procfs_snprintf(attr->line, UPTIME_LINELEN,
+                                  "%10.2f\n", now);
 
 #else
       /* Convert the system up time to seconds + hundredths of seconds */
@@ -253,11 +254,11 @@ static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
       /* Convert the seconds + hundredths of seconds to a string */
 
 #ifdef CONFIG_SYSTEM_TIME64
-      linesize = snprintf(attr->line, UPTIME_LINELEN, "%7" PRIu64 ".%02u\n",
-                          sec, csec);
+      linesize = procfs_snprintf(attr->line, UPTIME_LINELEN,
+                                 "%7" PRIu64 ".%02u\n", sec, csec);
 #else
-      linesize = snprintf(attr->line, UPTIME_LINELEN, "%7lu.%02u\n",
-                         (unsigned long)sec, csec);
+      linesize = procfs_snprintf(attr->line, UPTIME_LINELEN,
+                                 "%7lu.%02u\n", (unsigned long)sec, csec);
 #endif
 
 #endif
diff --git a/fs/procfs/fs_procfsutil.c b/fs/procfs/fs_procfsutil.c
index 0dd52a7..87c91d2 100644
--- a/fs/procfs/fs_procfsutil.c
+++ b/fs/procfs/fs_procfsutil.c
@@ -25,6 +25,7 @@
 #include <nuttx/config.h>
 
 #include <sys/types.h>
+#include <stdio.h>
 #include <string.h>
 
 #include <nuttx/fs/procfs.h>
@@ -116,4 +117,32 @@ size_t procfs_memcpy(FAR const char *src, size_t srclen,
   return copysize;
 }
 
+/****************************************************************************
+ * Name: procfs_snprintf
+ *
+ * Description:
+ *   This function is same with snprintf, except return values.
+ *   If buf has no enough space and output was truncated due to size limit,
+ *   snprintf:        return formated string len.
+ *   procfs_snprintf: return string len which has written to buf.
+ *
+ * Input Parameters:
+ *   Same with snprintf
+ *
+ * Returned Value:
+ *   See Description.
+ *
+ ****************************************************************************/
+
+int procfs_snprintf(FAR char *buf, size_t size,
+                    FAR const IPTR char *format, ...)
+{
+  va_list ap;
+  int n;
+  va_start(ap, format);
+  n = vsnprintf(buf, size, format, ap);
+  va_end(ap);
+  return n < size - 1 ? n : size - 1;
+}
+
 #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */
diff --git a/fs/procfs/fs_procfsversion.c b/fs/procfs/fs_procfsversion.c
index 5b1dae4..a3ad225 100644
--- a/fs/procfs/fs_procfsversion.c
+++ b/fs/procfs/fs_procfsversion.c
@@ -207,8 +207,9 @@ static ssize_t version_read(FAR struct file *filep, FAR char *buffer,
   if (filep->f_pos == 0)
     {
       uname(&name);
-      linesize = snprintf(attr->line, VERSION_LINELEN, "%s version %s %s\n",
-                          name.sysname, name.release, name.version);
+      linesize = procfs_snprintf(attr->line, VERSION_LINELEN,
+                                 "%s version %s %s\n",
+                                 name.sysname, name.release, name.version);
 
       /* Save the linesize in case we are re-entered with f_pos > 0 */
 
diff --git a/include/nuttx/fs/procfs.h b/include/nuttx/fs/procfs.h
index dbedab4..b826560 100644
--- a/include/nuttx/fs/procfs.h
+++ b/include/nuttx/fs/procfs.h
@@ -195,6 +195,26 @@ size_t procfs_memcpy(FAR const char *src, size_t srclen,
                      off_t *offset);
 
 /****************************************************************************
+ * Name: procfs_snprintf
+ *
+ * Description:
+ *   This function is same with snprintf, except return values.
+ *   If buf has no enough space and output was truncated due to size limit,
+ *   snprintf:        return formated string len.
+ *   procfs_snprintf: return string len which has written to buf.
+ *
+ * Input Parameters:
+ *   Same with snprintf
+ *
+ * Returned Value:
+ *   See Description.
+ *
+ ****************************************************************************/
+
+int procfs_snprintf(FAR char *buf, size_t size,
+                    FAR const IPTR char *format, ...);
+
+/****************************************************************************
  * Name: procfs_register
  *
  * Description:

[incubator-nuttx] 02/04: procfs: fix cat status error when meet long thread name

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit dbdb24e2e0edded3294c6fbd0ef7c374639200dd
Author: ligd <li...@xiaomi.com>
AuthorDate: Wed Apr 28 17:44:58 2021 +0800

    procfs: fix cat status error when meet long thread name
    
    nsh> cat /proc/3/status
    Name:       init123456789987654Type:       Task
    Group:      3
    State:      Running
    
    Change-Id: Iddef8fa1fe3a02d407244f46fa05e3f35dd7c84e
    Signed-off-by: ligd <li...@xiaomi.com>
---
 fs/procfs/fs_procfsproc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index 47d062a..f823543 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -459,8 +459,8 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
 #else
   name       = "<noname>";
 #endif
-  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n",
-                               "Name:", name);
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%.18s\n", "Name:", name);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 

[incubator-nuttx] 04/04: sched: add CONFIG_SCHED_CRITMONITOR_XX for debugging system lantency

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit adfaa140cc1a845d6f402b1d1569f12cfd8d4b57
Author: ligd <li...@xiaomi.com>
AuthorDate: Thu Apr 29 19:41:27 2021 +0800

    sched: add CONFIG_SCHED_CRITMONITOR_XX for debugging system lantency
    
    Change-Id: Id2a75db28caf1a89552e33391bd90f85cde08dbd
    Signed-off-by: ligd <li...@xiaomi.com>
---
 sched/Kconfig                   | 52 ++++++++++++++++++++++++++++++
 sched/irq/irq_dispatch.c        | 10 ++++++
 sched/sched/sched_critmonitor.c | 71 +++++++++++++++++++++++++++++++++++++++++
 sched/wdog/wd_start.c           | 26 ++++++++++++++-
 sched/wqueue/kwork_process.c    | 27 +++++++++++++++-
 5 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/sched/Kconfig b/sched/Kconfig
index ba0246e..644f0cb 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -736,6 +736,58 @@ config SCHED_CRITMONITOR
 		The second interface simply converts an elapsed time into well known
 		units for presentation by the ProcFS file system.
 
+if SCHED_CRITMONITOR
+
+config SCHED_CRITMONITOR_MAXTIME_THREAD
+	int "THREAD max execution time"
+	default 0
+	---help---
+		Thread execution time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_THREAD, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+config SCHED_CRITMONITOR_MAXTIME_WQUEUE
+	int "WORK queue max execution time"
+	default SCHED_CRITMONITOR_MAXTIME_THREAD
+	---help---
+		Worker execution time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_WQUEUE, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+config SCHED_CRITMONITOR_MAXTIME_PREEMPTION
+	int "Pre-emption (sched_lock) max holding time"
+	default SCHED_CRITMONITOR_MAXTIME_WQUEUE
+	---help---
+		Pre-emption holding time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_PREEMPTION, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+config SCHED_CRITMONITOR_MAXTIME_CSECTION
+	int "Csection (enter_critical_section) max holding time"
+	default SCHED_CRITMONITOR_MAXTIME_PREEMPTION
+	---help---
+		Csection holding time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_CSECTION, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+config SCHED_CRITMONITOR_MAXTIME_IRQ
+	int "IRQ max execution time"
+	default SCHED_CRITMONITOR_MAXTIME_CSECTION
+	---help---
+		IRQ handler execution time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_IRQ, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+config SCHED_CRITMONITOR_MAXTIME_WDOG
+	int "WDOG callback max execution time"
+	default SCHED_CRITMONITOR_MAXTIME_IRQ
+	---help---
+		Wdog callback execution time should be smaller than
+		SCHED_CRITMONITOR_MAXTIME_WDOG, or system will give a warnning.
+		For debugging system lantency, 0 means disabled.
+
+endif # SCHED_CRITMONITOR
+
 config SCHED_CPULOAD
 	bool "Enable CPU load monitoring"
 	default n
diff --git a/sched/irq/irq_dispatch.c b/sched/irq/irq_dispatch.c
index 489de37..ab984a0 100644
--- a/sched/irq/irq_dispatch.c
+++ b/sched/irq/irq_dispatch.c
@@ -65,6 +65,10 @@
  * interrupt request
  */
 
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ 0
+#endif
+
 #ifndef CONFIG_SCHED_IRQMONITOR
 #  define CALL_VECTOR(ndx, vector, irq, context, arg) \
      vector(irq, context, arg)
@@ -83,6 +87,12 @@
            { \
              g_irqvector[ndx].time = delta.tv_nsec; \
            } \
+         if (CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ > 0 && \
+             elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ) \
+           { \
+             serr("IRQ %d(%p), execute time too long %"PRIu32"\n", \
+                  irq, vector, elapsed); \
+           } \
        } \
      while (0)
 #else
diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c
index 97862b7..76a1656 100644
--- a/sched/sched/sched_critmonitor.c
+++ b/sched/sched/sched_critmonitor.c
@@ -33,6 +33,70 @@
 #ifdef CONFIG_SCHED_CRITMONITOR
 
 /****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION 0
+#endif
+
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION 0
+#endif
+
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD 0
+#endif
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION > 0
+#  define CHECK_PREEMPTION(pid, elapsed) \
+     do \
+       { \
+         if (pid > 0 && \
+             elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION) \
+           { \
+             serr("PID %d hold sched lock too long %"PRIu32"\n", \
+                   pid, elapsed); \
+           } \
+       } \
+     while (0)
+#else
+#  define CHECK_PREEMPTION(pid, elapsed)
+#endif
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION > 0
+#  define CHECK_CSECTION(pid, elapsed) \
+     do \
+       { \
+         if (pid > 0 && \
+             elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION) \
+           { \
+             serr("PID %d hold critical section too long %"PRIu32"\n", \
+                   pid, elapsed); \
+           } \
+       } \
+     while (0)
+#else
+#  define CHECK_CSECTION(pid, elapsed)
+#endif
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD > 0
+#  define CHECK_THREAD(pid, elapsed) \
+     do \
+       { \
+         if (pid > 0 && \
+             elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD) \
+           { \
+             serr("PID %d execute too long %"PRIu32"\n", \
+                   pid, elapsed); \
+           } \
+       } \
+     while (0)
+#else
+#  define CHECK_THREAD(pid, elapsed)
+#endif
+
+/****************************************************************************
  * Private Data
  ****************************************************************************/
 
@@ -112,6 +176,7 @@ void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
       if (elapsed > tcb->premp_max)
         {
           tcb->premp_max = elapsed;
+          CHECK_PREEMPTION(tcb->pid, elapsed);
         }
 
       /* Check for the global max elapsed time */
@@ -176,6 +241,7 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool state)
       if (elapsed > tcb->crit_max)
         {
           tcb->crit_max = elapsed;
+          CHECK_CSECTION(tcb->pid, elapsed);
         }
 
       /* Check for the global max elapsed time */
@@ -243,6 +309,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
       if (elapsed > g_premp_max[cpu])
         {
           g_premp_max[cpu] = elapsed;
+          CHECK_PREEMPTION(tcb->pid, elapsed);
         }
     }
 
@@ -270,6 +337,7 @@ void nxsched_resume_critmon(FAR struct tcb_s *tcb)
       if (elapsed > g_crit_max[cpu])
         {
           g_crit_max[cpu] = elapsed;
+          CHECK_CSECTION(tcb->pid, elapsed);
         }
     }
 }
@@ -296,6 +364,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
   if (elapsed > tcb->run_max)
     {
       tcb->run_max = elapsed;
+      CHECK_THREAD(tcb->pid, elapsed);
     }
 
   /* Did this task disable preemption? */
@@ -310,6 +379,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
       if (elapsed > tcb->premp_max)
         {
           tcb->premp_max = elapsed;
+          CHECK_PREEMPTION(tcb->pid, elapsed);
         }
     }
 
@@ -325,6 +395,7 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
       if (elapsed > tcb->crit_max)
         {
           tcb->crit_max = elapsed;
+          CHECK_CSECTION(tcb->pid, elapsed);
         }
     }
 }
diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c
index 531ec3a..d285fc7 100644
--- a/sched/wdog/wd_start.c
+++ b/sched/wdog/wd_start.c
@@ -50,6 +50,30 @@
 #  define MAX(a,b) (((a) > (b)) ? (a) : (b))
 #endif
 
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG 0
+#endif
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG > 0
+#  define CALL_FUNC(func, arg) \
+     do \
+       { \
+         uint32_t start; \
+         uint32_t elapsed; \
+         start = up_critmon_gettime(); \
+         func(arg); \
+         elapsed = up_critmon_gettime() - start; \
+         if (elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG) \
+           { \
+             serr("WDOG %p, %s IRQ, execute too long %"PRIu32"\n", \
+                   func, up_interrupt_context() ? "IN" : "NOT", elapsed); \
+           } \
+       } \
+     while (0)
+#else
+#  define CALL_FUNC(func, arg) func(arg)
+#endif
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -106,7 +130,7 @@ static inline void wd_expiration(void)
           /* Execute the watchdog function */
 
           up_setpicbase(wdog->picbase);
-          func(wdog->arg);
+          CALL_FUNC(func, wdog->arg);
         }
     }
 }
diff --git a/sched/wqueue/kwork_process.c b/sched/wqueue/kwork_process.c
index 22352bc..9bec97e 100644
--- a/sched/wqueue/kwork_process.c
+++ b/sched/wqueue/kwork_process.c
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 
+#include <debug.h>
 #include <stdint.h>
 #include <unistd.h>
 #include <signal.h>
@@ -63,6 +64,30 @@
 #  define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
+#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE
+#  define CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE 0
+#endif
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE > 0
+#  define CALL_WORKER(worker, arg) \
+     do \
+       { \
+         uint32_t start; \
+         uint32_t elapsed; \
+         start = up_critmon_gettime(); \
+         worker(arg); \
+         elapsed = up_critmon_gettime() - start; \
+         if (elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_WQUEUE) \
+           { \
+             serr("WORKER %p execute too long %"PRIu32"\n", \
+                   worker, elapsed); \
+           } \
+       } \
+     while (0)
+#else
+#  define CALL_WORKER(worker, arg) worker(arg)
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -154,7 +179,7 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, int wndx)
                */
 
               leave_critical_section(flags);
-              worker(arg);
+              CALL_WORKER(worker, arg);
 
               /* Now, unfortunately, since we re-enabled interrupts we don't
                * know the state of the work list and we will have to start