[PATCH][request for stable inclusion][3.10.x]: ARM: sched_clock: Load cycle count after epoch stabilizes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This looks applicable to stable-3.10, which load cycle count after
epoch stabilizes. The function was moved from 
arch/arm/kernel/sched_clock.c to kernel/time/sched_clock.c 
because of upgrading version. I rearrange this patch for
fixing bug in stable-3.10.
The commit id is 336ae1180df5f69b9e0fb6561bec01c5f64361cf in 3.18.
I designed a test case for recurring this bug as follows:

 CPU0                           CPU1
 ----                           ----
 g_counter = 1;
 .......
 cyc = read_sched_clock()
 cyc_to_sched_clock()
                              update_sched_clock()
                               ... 
                              cd.epoch_cyc = cyc;
			      g_counter = 2;
  epoch_cyc = cd.epoch_cyc;
  if(g_counter == 2)
	printk("error!\n");
   g_counter = 1;
  ... 
  epoch_ns + cyc_to_ns((cyc - epoch_cyc)

The bug will be proven to exist if the strings "error!" 
happen on screen. I find that "error!" happen firstly 
on screen in thirty hours.

The patch for test is as follows:
--- a/sched_clock.c    2014-11-25 08:24:15.000000000 +0000
+++ b/sched_clock.c       2014-12-01 08:46:32.000000000 +0000
@@ -15,7 +15,7 @@
 #include <linux/timer.h>
 
 #include <asm/sched_clock.h>
-
+unsigned int g_counter = 0;
 struct clock_data {
        u64 epoch_ns;
        u32 epoch_cyc;
@@ -68,11 +68,14 @@
         */  
        do {
                epoch_cyc = cd.epoch_cyc;
+               if(g_counter == 2)
+                       printk("error!\n");
+               g_counter = 1;
                smp_rmb();
                epoch_ns = cd.epoch_ns;
                smp_rmb();
        } while (epoch_cyc != cd.epoch_cyc_copy);
-
+       
        return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, cd.mult, cd.shift);
 }
 
@@ -99,6 +102,7 @@
        cd.epoch_ns = ns; 
        smp_wmb();
        cd.epoch_cyc = cyc;
+       g_counter = 2;
        raw_local_irq_restore(flags);
 }
 
@@ -168,6 +172,7 @@
 static unsigned long long notrace sched_clock_32(void)
 {
        u32 cyc = read_sched_clock();
+       g_counter = 1;
        return cyc_to_sched_clock(cyc, sched_clock_mask);
 }

xiaofeng.yan (1):
  ARM: sched_clock: Load cycle count after epoch stabilizes

 arch/arm/kernel/sched_clock.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

-- 
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]