Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.26-git1 /init/calibrate.c

Filename:/init/calibrate.c
Lines Added:32
Lines Deleted:28
Also changed in: (Previous) 2.6.25  2.6.25-rc9  2.6.25-rc8  2.6.25-rc7  2.6.25-rc6  2.6.25-rc5 
(Following) 2.6.26-git2  2.6.26-git3  2.6.26-git4  2.6.26-git5  2.6.26-git6  2.6.26-git7 

Location
[  2.6.26-git1
  [  init
     o  calibrate.c

Patch

diff --git a/init/calibrate.c b/init/calibrate.c
index ecb3822..7963e3f 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -8,7 +8,9 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/timex.h>
+#include <linux/smp.h>
 
+unsigned long lpj_fine;
 unsigned long preset_lpj;
 static int __init lpj_setup(char *str)
 {
@@ -33,9 +35,9 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
    unsigned long pre_start, start, post_start;
    unsigned long pre_end, end, post_end;
    unsigned long start_jiffies;
-   unsigned long tsc_rate_min, tsc_rate_max;
-   unsigned long good_tsc_sum = 0;
-   unsigned long good_tsc_count = 0;
+   unsigned long timer_rate_min, timer_rate_max;
+   unsigned long good_timer_sum = 0;
+   unsigned long good_timer_count = 0;
    int i;
 
    if (read_current_timer(&pre_start) < 0 )
@@ -79,22 +81,24 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
       }
       read_current_timer(&post_end);
 
-      tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
-      tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
+      timer_rate_max = (post_end - pre_start) /
+               DELAY_CALIBRATION_TICKS;
+      timer_rate_min = (pre_end - post_start) /
+               DELAY_CALIBRATION_TICKS;
 
       /*
-        * If the upper limit and lower limit of the tsc_rate is
+       * If the upper limit and lower limit of the timer_rate is
        * >= 12.5% apart, redo calibration.
        */
       if (pre_start != 0 && pre_end != 0 &&
-          (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
-         good_tsc_count++;
-         good_tsc_sum += tsc_rate_max;
+          (timer_rate_max - timer_rate_min) < (timer_rate_max >> 3)) {
+         good_timer_count++;
+         good_timer_sum += timer_rate_max;
       }
    }
 
-   if (good_tsc_count)
-      return (good_tsc_sum/good_tsc_count);
+   if (good_timer_count)
+      return (good_timer_sum/good_timer_count);
 
    printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
           "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
@@ -108,6 +112,10 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
  * This is the number of bits of precision for the loops_per_jiffy.  Each
  * bit takes on average 1.5/HZ seconds.  This (like the original) is a little
  * better than 1%
+ * For the boot cpu we can skip the delay calibration and assign it a value
+ * calculated based on the timer frequency.
+ * For the rest of the CPUs we cannot assume that the timer frequency is same as
+ * the cpu frequency, hence do the calibration for those.
  */
 #define LPS_PREC 8
 
@@ -118,20 +126,20 @@ void __cpuinit calibrate_delay(void)
 
    if (preset_lpj) {
       loops_per_jiffy = preset_lpj;
-      printk("Calibrating delay loop (skipped)... "
-         "%lu.%02lu BogoMIPS preset\n",
-         loops_per_jiffy/(500000/HZ),
-         (loops_per_jiffy/(5000/HZ)) % 100);
+      printk(KERN_INFO
+         "Calibrating delay loop (skipped) preset value.. ");
+   } else if ((smp_processor_id() == 0) && lpj_fine) {
+      loops_per_jiffy = lpj_fine;
+      printk(KERN_INFO
+         "Calibrating delay loop (skipped), "
+         "value calculated using timer frequency.. ");
    } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
-      printk("Calibrating delay using timer specific routine.. ");
-      printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
-         loops_per_jiffy/(500000/HZ),
-         (loops_per_jiffy/(5000/HZ)) % 100,
-         loops_per_jiffy);
+      printk(KERN_INFO
+         "Calibrating delay using timer specific routine.. ");
    } else {
       loops_per_jiffy = (1<<12);
 
-      printk(KERN_DEBUG "Calibrating delay loop... ");
+      printk(KERN_INFO "Calibrating delay loop... ");
       while ((loops_per_jiffy <<= 1) != 0) {
          /* wait for "start of" clock tick */
          ticks = jiffies;
@@ -161,12 +169,8 @@ void __cpuinit calibrate_delay(void)
          if (jiffies != ticks)   /* longer than 1 tick */
             loops_per_jiffy &= ~loopbit;
       }
-
-      /* Round the value and print it */
-      printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
-         loops_per_jiffy/(500000/HZ),
-         (loops_per_jiffy/(5000/HZ)) % 100,
-         loops_per_jiffy);
    }
-
+   printk(KERN_INFO "%lu.%02lu BogoMIPS (lpj=%lu)\n",
+         loops_per_jiffy/(500000/HZ),
+         (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
 }


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.