summaryrefslogtreecommitdiff
path: root/drivers/dahdi/dahdi-base.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2009-10-29 18:26:16 +0000
committerShaun Ruffell <sruffell@digium.com>2009-10-29 18:26:16 +0000
commitba9ca612200aaae486a8a3a640941a6bfc58c392 (patch)
treebdbf3fb259c0dba748f4dc3032ea28c76966ec9b /drivers/dahdi/dahdi-base.c
parent15e92ad14f41736a8240554c00a7f42bf82a6ec5 (diff)
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) git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@7437 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi-base.c')
-rw-r--r--drivers/dahdi/dahdi-base.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 511f9c1..2c6fc0d 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -8144,6 +8144,7 @@ static void coretimer_func(unsigned long param)
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 @@ static void coretimer_func(unsigned long param)
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();