svn commit: r185132 - head/sys/boot/common

Luigi Rizzo luigi at FreeBSD.org
Thu Nov 20 06:57:10 PST 2008


Author: luigi
Date: Thu Nov 20 14:57:09 2008
New Revision: 185132
URL: http://svn.freebsd.org/changeset/base/185132

Log:
  As reported in kern/118222, pxeboot in RELENG7 (and presumably
  above) exhibits some misbehaviours on machines with AMD64 CPUs,
  which at least in some cases I have tracked down to a heap overflow.
  
  It is unclear whether it depends on the CPU or on the pxe bios
  itself which may use more memory on AMD machines.
  
  Noticeably a pxeboot compiled from 6.x sources works fine on all
  machines I have tried so far, while a pxeboot compiled from 7.x
  sources does not.
  
  This patch is a first step in reducing the amount of memory used
  while processing the configuration files read by the loader at boot
  (some of them are quite large, 1700+ lines), and it does so by:
  + moving a buffer to static memory instead of allocating in the heap;
  + skipping empty lines;
  + reducing the amount of memory used for line descriptors;
  
  Unfortunately there are several changes between 6.x and above,
  affecting the compiler, the loader code itself, and libstand,
  and it is not so straightforward to
  These changes fix the behaviour on one motherboard with a
  single-core AMD cpu, but are still not enough e.g on an Asus
  M2N-VM (with a dual-core CPU).
  
  I need to investigate the problem a bit more before figuring
  out what should be committed to RELENG_7
  
  PR:		kern/118222

Modified:
  head/sys/boot/common/interp.c

Modified: head/sys/boot/common/interp.c
==============================================================================
--- head/sys/boot/common/interp.c	Thu Nov 20 13:39:14 2008	(r185131)
+++ head/sys/boot/common/interp.c	Thu Nov 20 14:57:09 2008	(r185132)
@@ -92,7 +92,7 @@ perform(int argc, char *argv[])
 void
 interact(void)
 {
-    char	input[256];			/* big enough? */
+    static char	input[256];			/* big enough? */
 #ifndef BOOT_FORTH
     int		argc;
     char	**argv;
@@ -178,14 +178,21 @@ command_include(int argc, char *argv[])
     return(res);
 }
 
+/*
+ * Header prepended to each line. The text immediately follows the header.
+ * We try to make this short in order to save memory -- the loader has
+ * limited memory available, and some of the forth files are very long.
+ */
 struct includeline 
 {
-    char		*text;
+    struct includeline	*next;
+#ifndef BOOT_FORTH
     int			flags;
     int			line;
 #define SL_QUIET	(1<<0)
 #define SL_IGNOREERR	(1<<1)
-    struct includeline	*next;
+#endif
+    char		text[0];
 };
 
 int
@@ -236,13 +243,14 @@ include(const char *filename)
 	}
 #endif
 	/* Allocate script line structure and copy line, flags */
+	if (*cp == '\0')
+		continue;	/* ignore empty line, save memory */
 	sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
-	sp->text = (char *)sp + sizeof(struct includeline);
 	strcpy(sp->text, cp);
 #ifndef BOOT_FORTH
 	sp->flags = flags;
-#endif
 	sp->line = line;
+#endif
 	sp->next = NULL;
 	    
 	if (script == NULL) {


More information about the svn-src-head mailing list