[svn-commits] sruffell: linux/trunk r7437 - /linux/trunk/drivers/dahdi/dahdi-base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Oct 29 13:26:25 CDT 2009


Author: sruffell
Date: Thu Oct 29 13:26:16 2009
New Revision: 7437

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7437
Log:
dahdi-base: Do not allow jumps in system time to lock up the system w/core_timer

Since dahdi coretimer uses the number of milliseconds that has actually passed
to determine how many times to call dahdi_receive, it is possible that if the
system time shifts after dahdi is started, that the system can appear to lock
up while the core timer attempts to catch up.  This change prevents soft lock
ups under these conditions.  This is brings the dahdi_dummy changes in r6933
into dahdi-base.

(related to issue #15647)

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=7437&r1=7436&r2=7437
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Thu Oct 29 13:26:16 2009
@@ -8144,6 +8144,7 @@
 	const unsigned long MAX_INTERVAL = 100000L;
 	const unsigned long FOURMS_INTERVAL = HZ/250;
 	const unsigned long ONESEC_INTERVAL = HZ;
+	const unsigned long MS_LIMIT = 3000;
 
 	now = current_kernel_time();
 
@@ -8158,6 +8159,23 @@
 			mod_timer(&core_timer.timer, jiffies + FOURMS_INTERVAL);
 
 		ms_since_start = core_diff_ms(&core_timer.start_interval, &now);
+
+		/*
+		 * If the system time has changed, it is possible for us to be
+		 * far behind.  If we are more than MS_LIMIT milliseconds
+		 * behind, just reset our time base and continue so that we do
+		 * not hang the system here.
+		 *
+		 */
+		if (unlikely((ms_since_start - atomic_read(&core_timer.count)) > MS_LIMIT)) {
+			if (printk_ratelimit())
+				module_printk(KERN_INFO, "Detected time shift.\n");
+			atomic_set(&core_timer.count, 0);
+			atomic_set(&core_timer.last_count, 0);
+			core_timer.start_interval = now;
+			return;
+		}
+
 		while (ms_since_start > atomic_read(&core_timer.count))
 			process_masterspan();
 




More information about the svn-commits mailing list