aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/calibrate.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/init/calibrate.c b/init/calibrate.c
index f9000dfbe227..76ac9194cbc4 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -122,7 +122,7 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
122static unsigned long __cpuinit calibrate_delay_converge(void) 122static unsigned long __cpuinit calibrate_delay_converge(void)
123{ 123{
124 /* First stage - slowly accelerate to find initial bounds */ 124 /* First stage - slowly accelerate to find initial bounds */
125 unsigned long lpj, ticks, loopadd, chop_limit; 125 unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit;
126 int trials = 0, band = 0, trial_in_band = 0; 126 int trials = 0, band = 0, trial_in_band = 0;
127 127
128 lpj = (1<<12); 128 lpj = (1<<12);
@@ -146,14 +146,18 @@ static unsigned long __cpuinit calibrate_delay_converge(void)
146 * the largest likely undershoot. This defines our chop bounds. 146 * the largest likely undershoot. This defines our chop bounds.
147 */ 147 */
148 trials -= band; 148 trials -= band;
149 loopadd = lpj * band; 149 loopadd_base = lpj * band;
150 lpj *= trials; 150 lpj_base = lpj * trials;
151 chop_limit = lpj >> (LPS_PREC + 1); 151
152recalibrate:
153 lpj = lpj_base;
154 loopadd = loopadd_base;
152 155
153 /* 156 /*
154 * Do a binary approximation to get lpj set to 157 * Do a binary approximation to get lpj set to
155 * equal one clock (up to LPS_PREC bits) 158 * equal one clock (up to LPS_PREC bits)
156 */ 159 */
160 chop_limit = lpj >> LPS_PREC;
157 while (loopadd > chop_limit) { 161 while (loopadd > chop_limit) {
158 lpj += loopadd; 162 lpj += loopadd;
159 ticks = jiffies; 163 ticks = jiffies;
@@ -165,6 +169,16 @@ static unsigned long __cpuinit calibrate_delay_converge(void)
165 lpj -= loopadd; 169 lpj -= loopadd;
166 loopadd >>= 1; 170 loopadd >>= 1;
167 } 171 }
172 /*
173 * If we incremented every single time possible, presume we've
174 * massively underestimated initially, and retry with a higher
175 * start, and larger range. (Only seen on x86_64, due to SMIs)
176 */
177 if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) {
178 lpj_base = lpj;
179 loopadd_base <<= 2;
180 goto recalibrate;
181 }
168 182
169 return lpj; 183 return lpj;
170} 184}