public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] preset loops_per_jiffy for faster booting
@ 2004-07-09 19:25 Tim Bird
  2004-07-09 22:24 ` Adam Kropelin
  2004-07-09 23:35 ` Adam Kropelin
  0 siblings, 2 replies; 29+ messages in thread
From: Tim Bird @ 2004-07-09 19:25 UTC (permalink / raw)
  To: linux kernel

Here is a patch which allows developers or users to preset the
value for loops per jiffy.  This avoids the overhead of
performing the calibration at boot time.  This saves about
250 milliseconds on many non-x86 architectures, and about
25 milliseconds on x86.  (The amount of time saved depends
on the value of HZ, and NOT on the processor speed.)

Besides allowing a value to be compiled in, the patch also allows
the value to be specified on the kernel command line with
the syntax: "lpj=xxx"  This is available whether the code
is configured with the option or not.

Finally, this code adds a new FASTBOOT menu to the kernel
config system, where we (CE Linux Forum developers) would like
to add this and other config options which can be used to
reduce kernel bootup time.

This technique (of disabling calibration for loops_per_jiffy)
is used by many embedded developers for reducing bootup time.

More commentary on this issue is available at:
http://tree.celinuxforum.org/pubwiki/moin.cgi/PresetLPJ

Comments are welcome.

Thanks.

=============================
Tim Bird
Bootup Time Working Group Chair, CE Linux Forum
Senior Staff Engineer, Sony Electronics
E-mail: tim.bird@am.sony.com
=============================

preset-lpj.patch:


Signed-off-by: Tim Bird <tim.bird@am.sony.com> for CELF
---

  Kconfig |   35 ++++++++++++++++++++++++++++
  main.c  |   78 +++++++++++++++++++++++++++++++++++++++++-----------------------
  2 files changed, 86 insertions(+), 27 deletions(-)


diff -ruN -x CVS -x '.#*' -X dontdiff tag_LINUX_2_6_7/init/Kconfig branch_PRESET_LPJ/init/Kconfig
--- tag_LINUX_2_6_7/init/Kconfig	2004-06-18 17:13:03.000000000 -0700
+++ branch_PRESET_LPJ/init/Kconfig	2004-06-22 13:16:05.000000000 -0700
@@ -218,6 +218,41 @@
  	  This option enables access to kernel configuration file and build
  	  information through /proc/config.gz.

+menuconfig FASTBOOT
+	bool "Fast boot options"
+	help
+	  Say Y here to enable faster booting of the Linux kernel.  If you
+	  say Y here, you may be asked to provide hardcoded values for some
+	  parameters that the kernel usually determines automatically.
+
+	  If unsure, say N.
+
+config USE_PRESET_LPJ
+	bool "Use preset loops_per_jiffy" if FASTBOOT
+	help
+	  Say Y here to use a preset value for loops_per_jiffy.  This
+	  is a value used internally in the kernel for busywait delays.
+	  Calculating this value at boot time can take up to 250 ms.
+	  Saying Y here, and specifying the value (next) will save
+	  this time during boot up.
+
+	  If unsure, say N.
+
+config PRESET_LPJ
+	int "Preset loops_per_jiffy" if USE_PRESET_LPJ
+	help
+	  This is the number of loops used by delay() to achieve a single
+	  jiffy of delay inside the kernel.  It is roughly BogoMips * 5000.
+	  To determine the correct value for your kernel, first turn off
+	  the fast booting option, compile and boot the kernel on your
+	  target hardware, then see what value is printed during the
+	  kernel boot.  Use that value here.
+
+	  If unsure, don't enable the "Use preset loops_per_jiffy" option.
+	  An incorrect value will cause delays in the kernel to be
+	  incorrect.  Although unlikely, in the extreme case this might
+	  damage your hardware.
+

  menuconfig EMBEDDED
  	bool "Configure standard kernel features (for small systems)"
diff -ruN -x CVS -x '.#*' -X dontdiff tag_LINUX_2_6_7/init/main.c branch_PRESET_LPJ/init/main.c
--- tag_LINUX_2_6_7/init/main.c	2004-06-18 17:13:02.000000000 -0700
+++ branch_PRESET_LPJ/init/main.c	2004-06-22 13:16:05.000000000 -0700
@@ -167,6 +167,15 @@
  	return 0;
  }

+static int __init lpj_setup(char *str)
+{
+	/* low bit indicates a value provided at boot time */
+	loops_per_jiffy = simple_strtoul(str,NULL,10) | 1;
+	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);
@@ -183,40 +192,55 @@
  	unsigned long ticks, loopbit;
  	int lps_precision = LPS_PREC;

-	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;
+#ifdef CONFIG_USE_PRESET_LPJ
+	/* if lpj is not provided on command line, use preset value */
+	if ((loops_per_jiffy & 1) == 0) {
+		loops_per_jiffy = CONFIG_PRESET_LPJ | 1;
  	}
+#endif /* CONFIG_USE_PRESET_LPJ */

-/* 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;
+	if (loops_per_jiffy & 1) {
+		printk("Calibrating delay loop (skipped)... ");
+	} else {
+
+		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);
+			ticks = jiffies;
+			__delay(loops_per_jiffy);
+			if (jiffies != ticks)	/* longer than 1 tick */
+				loops_per_jiffy &= ~loopbit;
+		}
  	}

-/* Round the value and print it */	
+/* Round the value and print it */
  	printk("%lu.%02lu BogoMIPS\n",
  		loops_per_jiffy/(500000/HZ),
  		(loops_per_jiffy/(5000/HZ)) % 100);
+
+#ifndef CONFIG_USE_PRESET_LPJ
+	printk("Set 'Preset loops_per_jiffy'=%lu for preset lpj.\n",
+		loops_per_jiffy);
+#endif /* CONFIG_USE_PRESET_LPJ */
  }

  static int __init debug_kernel(char *str)

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2004-07-13 19:18 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-09 19:25 [PATCH] preset loops_per_jiffy for faster booting Tim Bird
2004-07-09 22:24 ` Adam Kropelin
2004-07-09 23:35 ` Adam Kropelin
2004-07-10  0:20   ` Tim Bird
2004-07-10  2:01     ` Adam Kropelin
2004-07-10  2:01       ` Todd Poynor
2004-07-10 15:42         ` Adam Kropelin
2004-07-10 14:41       ` [Celinux-dev] " Geert Uytterhoeven
2004-07-10 15:22         ` Adam Kropelin
2004-07-10 15:54     ` Adam Kropelin
2004-07-10 18:28       ` Adam Kropelin
2004-07-10 18:19         ` Dmitry Torokhov
2004-07-10 20:14           ` Adam Kropelin
2004-07-11  1:25             ` Andrew Morton
2004-07-11  3:44               ` Adam Kropelin
2004-07-11  4:38                 ` Andrew Morton
2004-07-12 17:31                   ` Tim Bird
2004-07-11  4:51                 ` Dmitry Torokhov
2004-07-11  4:58                   ` Karim Yaghmour
2004-07-11  5:19                     ` Dmitry Torokhov
2004-07-11  5:27                       ` Andrew Morton
2004-07-11  7:46                         ` Geert Uytterhoeven
2004-07-11  7:51                           ` Andrew Morton
2004-07-11 13:41                             ` Adam Kropelin
2004-07-12 18:52                               ` Tim Bird
2004-07-12 19:32                                 ` Adam Kropelin
2004-07-12 22:41                                   ` Tim Bird
2004-07-13 19:24                                     ` Bartlomiej Zolnierkiewicz
2004-07-12 17:50               ` Tim Bird

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox