preset-lpj-04.09.02.patch: This patch adds support for a preset value for loops_per_jiffy. Signed-off-by: Geoff Levand for CELF --- Documentation/kernel-parameters.txt | 14 +++++ init/Kconfig | 39 ++++++++++++++ init/main.c | 96 ++++++++++++++++++++++-------------- 3 files changed, 114 insertions(+), 35 deletions(-) diff -ruN -X ./dontdiff tag_LINUX_2_6_8_1/Documentation/kernel-parameters.txt branch_PRESET_LPJ/Documentation/kernel-parameters.txt --- tag_LINUX_2_6_8_1/Documentation/kernel-parameters.txt 2004-09-02 15:25:53.000000000 -0700 +++ branch_PRESET_LPJ/Documentation/kernel-parameters.txt 2004-09-02 16:18:03.000000000 -0700 @@ -574,6 +574,20 @@ so, the driver will manage that printer. See also header of drivers/char/lp.c. + lpj=n [KNL] + Sets loops_per_jiffy to given constant, thus avoiding + time-consuming boot-time autodetection (up to 250 ms per + CPU). 0 enables autodetection (default). To determine + the correct value for your kernel, boot with normal + autodetection and see what value is printed. Note that + on SMP systems the preset will be applied to all CPUs, + which is likely to cause problems if your CPUs need + significantly divergent settings. An incorrect value + will cause delays in the kernel to be wrong, leading to + unpredictable I/O errors and other breakage. Although + unlikely, in the extreme case this might damage your + hardware. + ltpc= [NET] Format: ,, diff -ruN -X ./dontdiff tag_LINUX_2_6_8_1/init/Kconfig branch_PRESET_LPJ/init/Kconfig --- tag_LINUX_2_6_8_1/init/Kconfig 2004-09-02 15:27:15.000000000 -0700 +++ branch_PRESET_LPJ/init/Kconfig 2004-09-02 16:19:29.000000000 -0700 @@ -216,6 +216,45 @@ This option enables access to the kernel configuration file through /proc/config.gz. +menuconfig FASTBOOT + bool "Fast boot options" + help + Say Y here to select among various options that can decrease + kernel boot time. These options commonly involve providing + hardcoded values for some parameters that the kernel usually + determines automatically. + + This option is useful primarily on embedded systems. + + If unsure, say N. + +config PRESET_LPJ + int "Preset loops_per_jiffy" if FASTBOOT + default 0 + help + This is the number of loops used by delay() to achieve a single + jiffy of delay inside the kernel. It is normally calculated at + boot time, but that calculation can take up to 250 ms per CPU. + Specifying a constant value here will eliminate that delay. + + A value of 0 results in the normal autodetect behavior. + + To determine the correct value for your kernel, first set this + option to 0, compile and boot the kernel on your target hardware, + then see what value is printed during the kernel boot. Use that + value here. + + The kernel command line parameter "lpj=" can be used to override + the value configured here. + + Note that on SMP systems the preset will be applied to all CPUs + which will cause problems if for some reason your CPUs need + significantly divergent settings. + + If unsure, set this to 0. An incorrect value will cause delays in + the kernel to be wrong, leading to unpredictable I/O errors and + other breakage. Although unlikely, in the extreme case this might + damage your hardware. menuconfig EMBEDDED bool "Configure standard kernel features (for small systems)" diff -ruN -X ./dontdiff tag_LINUX_2_6_8_1/init/main.c branch_PRESET_LPJ/init/main.c --- tag_LINUX_2_6_8_1/init/main.c 2004-09-02 15:27:15.000000000 -0700 +++ branch_PRESET_LPJ/init/main.c 2004-09-02 16:19:29.000000000 -0700 @@ -178,15 +178,28 @@ return 0; } -/* this should be approx 2 Bo*oMips to start (note initial shift), and will - still work even if initially too large, it will just take slightly longer */ +static unsigned long preset_lpj = CONFIG_PRESET_LPJ; +static int __init lpj_setup(char *str) +{ + preset_lpj = simple_strtoul(str,NULL,0); + return 1; +} + +__setup("lpj=", lpj_setup); + +/* + * This should be approx 2 Bo*oMips to start (note initial shift), and will + * still work even if initially too large, it will just take slightly longer + */ unsigned long loops_per_jiffy = (1<<12); EXPORT_SYMBOL(loops_per_jiffy); -/* 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% */ +/* + * 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% + */ #define LPS_PREC 8 void __devinit calibrate_delay(void) @@ -194,40 +207,53 @@ unsigned long ticks, loopbit; int lps_precision = LPS_PREC; - loops_per_jiffy = (1<<12); + 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); + } else { + loops_per_jiffy = (1<<12); - printk("Calibrating delay loop... "); - while ((loops_per_jiffy <<= 1) != 0) { - /* wait for "start of" clock tick */ - ticks = jiffies; - while (ticks == jiffies) - /* nothing */; - /* Go .. */ - ticks = jiffies; - __delay(loops_per_jiffy); - ticks = jiffies - ticks; - if (ticks) - break; - } + printk("Calibrating delay loop... "); + while ((loops_per_jiffy <<= 1) != 0) { + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + /* Go .. */ + ticks = jiffies; + __delay(loops_per_jiffy); + ticks = jiffies - ticks; + if (ticks) + break; + } + + /* + * Do a binary approximation to get loops_per_jiffy set to + * equal one clock (up to lps_precision bits) + */ + loops_per_jiffy >>= 1; + loopbit = loops_per_jiffy; + while (lps_precision-- && (loopbit >>= 1)) { + loops_per_jiffy |= loopbit; + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + ticks = jiffies; + __delay(loops_per_jiffy); + if (jiffies != ticks) /* longer than 1 tick */ + loops_per_jiffy &= ~loopbit; + } -/* Do a binary approximation to get loops_per_jiffy set to equal one clock - (up to lps_precision bits) */ - loops_per_jiffy >>= 1; - loopbit = loops_per_jiffy; - while ( lps_precision-- && (loopbit >>= 1) ) { - loops_per_jiffy |= loopbit; - ticks = jiffies; - while (ticks == jiffies); - ticks = jiffies; - __delay(loops_per_jiffy); - 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); } -/* Round the value and print it */ - printk("%lu.%02lu BogoMIPS\n", - loops_per_jiffy/(500000/HZ), - (loops_per_jiffy/(5000/HZ)) % 100); } static int __init debug_kernel(char *str)