From 3846b99eb536ed9231f1de76050738dc3a9e90cc Mon Sep 17 00:00:00 2001 From: "don.hong" Date: Wed, 2 Nov 2011 17:24:56 +0900 Subject: [PATCH] [Title] Fixed a bug related with extremely slow CopyOnWrite of QCOW2 image [Type] BugFix [Module] kernel/time [Priority] [CQ#] [Redmine#] [Problem] QEMU goes 50 times slower when CopyOnWrite of QCOW2 image [Cause] [Solution] Modified sytem time to approximate to realtime even though QEMU timer works very slowly [TestCase] --- kernel/time/tick-common.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index b973c7d36eb5..295866e89969 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -69,34 +69,47 @@ void tick_periodic(int cpu) #ifdef UNDER_HYPERVISOR { /* Compensate slow timer tick under hypervisor */ static __kernel_time_t rt_sec; - static unsigned long rt_jiffies_sec = HZ; - static unsigned long rt_ticks_sec = HZ; - static unsigned long rt_tick = 0; - static unsigned long rt_current = 0; - static unsigned long rt_count = 1; - - unsigned long tick = rt_jiffies_sec * ++rt_tick / rt_ticks_sec - rt_current; - rt_current += tick; + static unsigned short rt_jiffies_sec = HZ; + static unsigned short rt_ticks_sec = HZ; + static unsigned short rt_jiffies = 0; + static unsigned short rt_ticks = 0; + static unsigned short rt_count = 1; + static unsigned short rt_log[11] = {0}; + + unsigned long tick = rt_jiffies_sec * ++rt_ticks / rt_ticks_sec - rt_jiffies; + if (rt_jiffies + tick > rt_jiffies_sec + (HZ/4) ) + tick = (rt_jiffies + tick > rt_jiffies_sec + HZ) ? 0 : 1; + + rt_jiffies += tick; do_timer(tick); - if( 0 == --rt_count ) { + if (0 == --rt_count) { static int first = 2; struct timespec ts; read_persistent_clock(&ts); if (rt_sec != ts.tv_sec) { + rt_log[++rt_log[0]] = rt_ticks; + if (rt_log[0] == 10) { + rt_log[0] = 0; + printk(KERN_ERR "tick_count : %d %d %d %d %d %d %d %d %d %d\n", + rt_log[1], rt_log[2], rt_log[3], rt_log[4], rt_log[5], + rt_log[6], rt_log[7], rt_log[8], rt_log[9], rt_log[10]); + } + if (!first) { - rt_jiffies_sec = HZ + rt_jiffies_sec - rt_current; - rt_ticks_sec = rt_tick; + rt_jiffies_sec = HZ + rt_jiffies_sec - rt_jiffies; + rt_ticks_sec = rt_ticks ; } else { first--; } + rt_sec = ts.tv_sec; - rt_tick = rt_current = 0; + rt_ticks = rt_jiffies = 0; } - rt_count = (!first && rt_ticks_sec > rt_tick + 3) ? (rt_ticks_sec - rt_tick) >> 2 : 1; + rt_count = (!first && rt_ticks_sec > rt_ticks + 3) ? (rt_ticks_sec - rt_ticks) >> 2 : 1; } } #else -- 2.34.1