Check if the Hangcheck-timer TSC source is stable
RFC PATCH 1/1 Check if the Hangcheck-timer TSC source is stable
Check if the TSC source is stable otherwise fail registration.
Signed-off-by Michael Trimarchi <[email protected]>
---
drivers/char/hangcheck-timer.c +30 -18
@@ -10,12 +10,12 @@* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. -* +* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. -* +* * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -64,14 +64,18 @@ static int hangcheck_dump_tasks; /* Defaults to not dumping SysRQ T */module_param (hangcheck_tick, int,0 );MODULE_PARM_DESC (hangcheck_tick,"Timer delay." );module_param (hangcheck_margin, int,0 ); -MODULE_PARM_DESC (hangcheck_margin,"If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire." ); +MODULE_PARM_DESC (hangcheck_margin,"If the hangcheck timer has been delayed" +" more than hangcheck_margin seconds, the driver will fire." );module_param (hangcheck_reboot, int,0 ); -MODULE_PARM_DESC (hangcheck_reboot,"If nonzero, the machine will reboot when the timer margin is exceeded." ); +MODULE_PARM_DESC (hangcheck_reboot,"If nonzero, the machine will reboot" +" when the timer margin is exceeded." );module_param (hangcheck_dump_tasks, int,0 ); -MODULE_PARM_DESC (hangcheck_dump_tasks,"If nonzero, the machine will dump the system task state when the timer margin is exceeded." ); +MODULE_PARM_DESC (hangcheck_dump_tasks,"If nonzero, the machine will dump" +" the system task state when the timer margin is exceeded." );MODULE_AUTHOR ("Oracle" ); -MODULE_DESCRIPTION ("Hangcheck-timer detects when the system has gone out to lunch past a certain margin." ); +MODULE_DESCRIPTION ("Hangcheck-timer detects when the system has gone" +" out to lunch past a certain margin." );MODULE_LICENSE ("GPL" );MODULE_VERSION (VERSION_STR );
@@ -81,7 +85,7 @@ MODULE_VERSION(VERSION_STR);static int __init hangcheck_parse_tick (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_tick = par;return 1 ; }
@@ -89,7 +93,7 @@ static int __init hangcheck_parse_tick(char *str)static int __init hangcheck_parse_margin (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_margin = par;return 1 ; }
@@ -97,7 +101,7 @@ static int __init hangcheck_parse_margin(char *str)static int __init hangcheck_parse_reboot (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_reboot = par;return 1 ; }
@@ -105,7 +109,7 @@ static int __init hangcheck_parse_reboot(char *str)static int __init hangcheck_parse_dump_tasks (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_dump_tasks = par;return 1 ; }
@@ -151,8 +155,10 @@ static void hangcheck_fire(unsigned long data)if (cur_tsc > hangcheck_tsc) tsc_diff = cur_tsc - hangcheck_tsc; -else - tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc));/* or something */ +else { +/* or samenthing */ + tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); + }if (tsc_diff > hangcheck_tsc_margin) {if (hangcheck_dump_tasks) {
@@ -172,15 +178,21 @@ static void hangcheck_fire(unsigned long data) hangcheck_tsc =monotonic_clock (); } -static int __init hangcheck_init (void ) { -printk ("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n" , +printk (KERN_INFO "Hangcheck: starting hangcheck timer %s" +" (tick is %d seconds, margin is %d seconds).\n" ,VERSION_STR , hangcheck_tick, hangcheck_margin); -#if defined (HAVE_MONOTONIC ) -printk ("Hangcheck: Using monotonic_clock().\n" ); +#if defined(HAVE_MONOTONIC ) +printk (KERN_INFO "Hangcheck: Using monotonic_clock().\n" );#else -printk ("Hangcheck: Using get_cycles().\n" ); +if (!check_tsc_unstable ()) +printk (KERN_INFO "Hangcheck: Using get_cycles().\n" ); +else { +printk (KERN_ERR "Handcheck: Failed to register" +" (Unstable TSC).\n" ); +return -ENODEV ; + }#endif /* HAVE_MONOTONIC */ hangcheck_tsc_margin = (unsigned long long )(hangcheck_margin + hangcheck_tick);
@@ -196,7 +208,7 @@ static int __init hangcheck_init(void) static void __exit hangcheck_exit(void) {del_timer_sync (&hangcheck_ticktock); -printk ("Hangcheck: Stopped hangcheck timer.\n" ); +printk (KERN_INFO "Hangcheck: Stopped hangcheck timer.\n" ); }module_init (hangcheck_init);
Quoted 1 line · Michael Trimarchi
Check if the TSC source is stable otherwise fail registration.
Good idea.
drivers/char/hangcheck-timer.c static void hangcheck_fire(unsigned long data) · line 161
Quoted 10 lines
drivers/char/hangcheck-timer.c +4
-2@@ -151,8 +155,10 @@ static void hangcheck_fire(unsigned long data)if (cur_tsc > hangcheck_tsc) tsc_diff = cur_tsc - hangcheck_tsc; -else - tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc));/* or something */ +else { +/* or samenthing */ + tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); + }
This hunk isn't any good. The comment spelling is messed up,
and really you can just remove the "or something".
Joel
Signature · 8 lines
"There is no sincerer love than the love of food."
- George Bernard Shaw
Joel Becker
Principal Software Developer
Oracle
E-mail: [email protected]
Phone: (650) 506-8127Check if the TSC source is stable otherwise fail registration.
Signed-off-by Michael Trimarchi <[email protected]>
---
drivers/char/hangcheck-timer.c +27 -17
@@ -10,12 +10,12 @@* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. -* +* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. -* +* * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -64,14 +64,18 @@ static int hangcheck_dump_tasks; /* Defaults to not dumping SysRQ T */module_param (hangcheck_tick, int,0 );MODULE_PARM_DESC (hangcheck_tick,"Timer delay." );module_param (hangcheck_margin, int,0 ); -MODULE_PARM_DESC (hangcheck_margin,"If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire." ); +MODULE_PARM_DESC (hangcheck_margin,"If the hangcheck timer has been delayed" +" more than hangcheck_margin seconds, the driver will fire." );module_param (hangcheck_reboot, int,0 ); -MODULE_PARM_DESC (hangcheck_reboot,"If nonzero, the machine will reboot when the timer margin is exceeded." ); +MODULE_PARM_DESC (hangcheck_reboot,"If nonzero, the machine will reboot" +" when the timer margin is exceeded." );module_param (hangcheck_dump_tasks, int,0 ); -MODULE_PARM_DESC (hangcheck_dump_tasks,"If nonzero, the machine will dump the system task state when the timer margin is exceeded." ); +MODULE_PARM_DESC (hangcheck_dump_tasks,"If nonzero, the machine will dump" +" the system task state when the timer margin is exceeded." );MODULE_AUTHOR ("Oracle" ); -MODULE_DESCRIPTION ("Hangcheck-timer detects when the system has gone out to lunch past a certain margin." ); +MODULE_DESCRIPTION ("Hangcheck-timer detects when the system has gone" +" out to lunch past a certain margin." );MODULE_LICENSE ("GPL" );MODULE_VERSION (VERSION_STR );
@@ -81,7 +85,7 @@ MODULE_VERSION(VERSION_STR);static int __init hangcheck_parse_tick (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_tick = par;return 1 ; }
@@ -89,7 +93,7 @@ static int __init hangcheck_parse_tick(char *str)static int __init hangcheck_parse_margin (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_margin = par;return 1 ; }
@@ -97,7 +101,7 @@ static int __init hangcheck_parse_margin(char *str)static int __init hangcheck_parse_reboot (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_reboot = par;return 1 ; }
@@ -105,7 +109,7 @@ static int __init hangcheck_parse_reboot(char *str)static int __init hangcheck_parse_dump_tasks (char *str) {int par; -if (get_option (&str,&par)) +if (get_option (&str, &par)) hangcheck_dump_tasks = par;return 1 ; }
@@ -152,7 +156,7 @@ static void hangcheck_fire(unsigned long data)if (cur_tsc > hangcheck_tsc) tsc_diff = cur_tsc - hangcheck_tsc;else - tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc));/* or something */ + tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc));if (tsc_diff > hangcheck_tsc_margin) {if (hangcheck_dump_tasks) {
@@ -172,15 +176,21 @@ static void hangcheck_fire(unsigned long data) hangcheck_tsc =monotonic_clock (); } -static int __init hangcheck_init (void ) { -printk ("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n" , +printk (KERN_INFO "Hangcheck: starting hangcheck timer %s" +" (tick is %d seconds, margin is %d seconds).\n" ,VERSION_STR , hangcheck_tick, hangcheck_margin); -#if defined (HAVE_MONOTONIC ) -printk ("Hangcheck: Using monotonic_clock().\n" ); +#if defined(HAVE_MONOTONIC ) +printk (KERN_INFO "Hangcheck: Using monotonic_clock().\n" );#else -printk ("Hangcheck: Using get_cycles().\n" ); +if (!check_tsc_unstable ()) +printk (KERN_INFO "Hangcheck: Using get_cycles().\n" ); +else { +printk (KERN_ERR "Handcheck: Failed to register" +" (Unstable TSC).\n" ); +return -ENODEV ; + }#endif /* HAVE_MONOTONIC */ hangcheck_tsc_margin = (unsigned long long )(hangcheck_margin + hangcheck_tick);
@@ -196,7 +206,7 @@ static int __init hangcheck_init(void) static void __exit hangcheck_exit(void) {del_timer_sync (&hangcheck_ticktock); -printk ("Hangcheck: Stopped hangcheck timer.\n" ); +printk (KERN_INFO "Hangcheck: Stopped hangcheck timer.\n" ); }module_init (hangcheck_init);