current hung_task_check_interval_secs and hung_task_timeout_secs
only supports seconds.in some cases,the TASK_UNINTERRUPTIBLE state
takes less than 1 second.The task of the graphical interface,
the unterruptible state lasts for hundreds of milliseconds
will cause the interface to freeze

echo 1 > /proc/sys/kernel/hung_task_milliseconds
value of hung_task_check_interval_secs and hung_task_timeout_secs whill
to milliseconds

Signed-off-by: yang che <[email protected]>
---
 include/linux/sched/sysctl.h |  1 +
 kernel/hung_task.c           | 33 +++++++++++++++++++++++++++------
 kernel/sysctl.c              |  9 +++++++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 660ac49..e5e5de2 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -16,6 +16,7 @@ extern unsigned int sysctl_hung_task_all_cpu_backtrace;
 
 extern int          sysctl_hung_task_check_count;
 extern unsigned int  sysctl_hung_task_panic;
+extern unsigned int  sysctl_hung_task_millisecond;
 extern unsigned long sysctl_hung_task_timeout_secs;
 extern unsigned long sysctl_hung_task_check_interval_secs;
 extern int sysctl_hung_task_warnings;
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index ce76f49..7f34912 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -44,6 +44,14 @@ int __read_mostly sysctl_hung_task_check_count = 
PID_MAX_LIMIT;
 unsigned long __read_mostly sysctl_hung_task_timeout_secs = 
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT;
 
 /*
+ * sysctl_hung_task_milliseconds is enable milliseconds
+ *
+ * if is 1 , hung_task_timeout_secs and hung_task_check_interval_secs will
+ * means set to millisecondsuse. as hung_task_timeout_secs is 5, will 5 
milliseconds
+ */
+unsigned int __read_mostly sysctl_hung_task_millisecond;
+
+/*
  * Zero (default value) means use sysctl_hung_task_timeout_secs:
  */
 unsigned long __read_mostly sysctl_hung_task_check_interval_secs;
@@ -108,8 +116,13 @@ static void check_hung_task(struct task_struct *t, 
unsigned long timeout)
                t->last_switch_time = jiffies;
                return;
        }
-       if (time_is_after_jiffies(t->last_switch_time + timeout * HZ))
-               return;
+       if (sysctl_hung_task_millisecond) {
+               if (time_is_after_jiffies(t->last_switch_time + (timeout * HZ) 
/ 1000))
+                       return;
+       } else {
+               if (time_is_after_jiffies(t->last_switch_time + timeout * HZ))
+                       return;
+       }
 
        trace_sched_process_hang(t);
 
@@ -126,8 +139,12 @@ static void check_hung_task(struct task_struct *t, 
unsigned long timeout)
        if (sysctl_hung_task_warnings) {
                if (sysctl_hung_task_warnings > 0)
                        sysctl_hung_task_warnings--;
-               pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n",
-                      t->comm, t->pid, (jiffies - t->last_switch_time) / HZ);
+               if (sysctl_hung_task_millisecond)
+                       pr_err("INFO: task %s:%d blocked for more than %ld 
milliiseconds.\n",
+                               t->comm, t->pid, (jiffies - 
t->last_switch_time) / HZ * 1000);
+               else
+                       pr_err("INFO: task %s:%d blocked for more than %ld 
seconds.\n",
+                               t->comm, t->pid, (jiffies - 
t->last_switch_time) / HZ);
                pr_err("      %s %s %.*s\n",
                        print_tainted(), init_utsname()->release,
                        (int)strcspn(init_utsname()->version, " "),
@@ -217,8 +234,12 @@ static long hung_timeout_jiffies(unsigned long 
last_checked,
                                 unsigned long timeout)
 {
        /* timeout of 0 will disable the watchdog */
-       return timeout ? last_checked - jiffies + timeout * HZ :
-               MAX_SCHEDULE_TIMEOUT;
+       if (sysctl_hung_task_millisecond)
+               return timeout ? last_checked - jiffies + (timeout * HZ) / 1000 
:
+                       MAX_SCHEDULE_TIMEOUT;
+       else
+               return timeout ? last_checked - jiffies + timeout * HZ :
+                       MAX_SCHEDULE_TIMEOUT;
 }
 
 /*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index db1ce7a..0bdcd66 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2476,6 +2476,15 @@ static struct ctl_table kern_table[] = {
                .extra1         = SYSCTL_ZERO,
        },
        {
+               .procname       = "hung_task_milliseconds",
+               .data           = &sysctl_hung_task_millisecond,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = SYSCTL_ONE,
+       },
+       {
                .procname       = "hung_task_timeout_secs",
                .data           = &sysctl_hung_task_timeout_secs,
                .maxlen         = sizeof(unsigned long),
-- 
2.7.4

Reply via email to