[PATCH v3][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]

 



commit 336ae1180df5f69b9e0fb6561bec01c5f64361cf
ARM: sched_clock: Load cycle count after epoch stabilizes

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.
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);
 }

Stephen Boyd (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.7.9.5

--
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]