How to debug a double fault? (Re: Could MSGBUF_SIZE be made a loader tunable?)

perryh at pluto.rain.com perryh at pluto.rain.com
Wed Dec 15 10:40:40 UTC 2010


Andriy Gapon <avg at freebsd.org> wrote:
> on 06/12/2010 07:20 perryh at pluto.rain.com said the following:
> > Would there be some fundamental problem in changing MSGBUF_SIZE
> > from a compiled-in constant to a tunable that could be set at the
> > loader prompt?
> > I didn't see any obvious downside from examining the 8.1-RELEASE
> > code ...
> I also don't immediately see why that wouldn't work.
> Can you try to come up with a patch?

I came up with what I think is a start, but it has led to:
How do I go about debugging a "Fatal double fault"?

A kernel in which I changed only the name built and booted fine,
so it seems I can in fact build a working kernel.

The next iteration (patch1), where I think I added a tunable
(msgbufsize) to the infrastructure but didn't attempt to use
it anywhere, also seemed to work.

However, when I replaced the various uses of MSGBUF_SIZE with
msgbufsize (patch2), it built OK but died very early:

OK unload
OK boot T_MSGB_SZ
/boot/T_MSGB_SZ/kernel text=0x7bdea5 data=0xe7334+0xa3fb0 syms=[0x4+0xa64b0+0x4+0xdc392]
/
Fatal double fault:
eip = 0xc07feb98
esp = 0xc101e000
ebp = 0xc101e004
cpuid = 0; apic id = 00
panic: double fault
cpuid = 0

How do I go about tracking this down?
-------------- next part --------------
--- boot/common/loader.8-81R	Sun Jun 13 19:09:06 2010
+++ boot/common/loader.8	Mon Dec 13 21:34:49 2010
@@ -615,6 +615,14 @@
 the NBUF parameter will override this limit.
 Modifies
 .Dv VM_BCACHE_SIZE_MAX .
+.It Va kern.msgbufsize
+Sets the size of the kernel message buffer.
+The default of 64KB is usually sufficient unless
+large amounts of trace data need to be collected
+between opportunities to examine the buffer or
+dump it to a file.
+Modifies kernel option
+.Dv MSGBUF_SIZE 
 .It Va machdep.disable_mtrrs
 Disable the use of i686 MTRRs (x86 only).
 .It Va net.inet.tcp.tcbhashsize
--- boot/forth/loader.conf-81R	Sun Jun 13 19:09:06 2010
+++ boot/forth/loader.conf	Mon Dec 13 21:50:16 2010
@@ -99,6 +99,7 @@
 #kern.maxswzone=""		# Set the max swmeta KVA storage
 #kern.maxtsiz=""		# Set the max text size
 #kern.maxusers="32"		# Set size of various static tables
+#kern.msgbufsize=""		# Set size of kernel message buffer
 #kern.nbuf=""			# Set the number of buffer headers
 #kern.ncallout=""		# Set the maximum # of timer events
 #kern.ngroups="1023"		# Set the maximum # of supplemental groups
--- kern/subr_param.c-81R	Sun Jun 13 19:09:06 2010
+++ kern/subr_param.c	Mon Dec 13 21:46:40 2010
@@ -89,6 +89,7 @@
 int	nswbuf;
 long	maxswzone;			/* max swmeta KVA storage */
 long	maxbcache;			/* max buffer cache KVA storage */
+long	msgbufsize;			/* size of kernel message buffer */
 long	maxpipekva;			/* Limit on pipe KVA */
 int 	vm_guest;			/* Running as virtual machine guest? */
 u_long	maxtsiz;			/* max text size */
@@ -110,6 +111,8 @@
     "Maximum memory for swap metadata");
 SYSCTL_LONG(_kern, OID_AUTO, maxbcache, CTLFLAG_RDTUN, &maxbcache, 0,
     "Maximum value of vfs.maxbufspace");
+SYSCTL_LONG(_kern, OID_AUTO, msgbufsize, CTLFLAG_RDTUN, &msgbufsize, 0,
+    "Size of the kernel message buffer");
 SYSCTL_ULONG(_kern, OID_AUTO, maxtsiz, CTLFLAG_RDTUN, &maxtsiz, 0,
     "Maximum text size");
 SYSCTL_ULONG(_kern, OID_AUTO, dfldsiz, CTLFLAG_RDTUN, &dfldsiz, 0,
@@ -217,6 +220,10 @@
 	maxbcache = VM_BCACHE_SIZE_MAX;
 #endif
 	TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
+#ifdef MSGBUF_SIZE
+	msgbufsize = MSGBUF_SIZE;
+#endif
+	TUNABLE_LONG_FETCH("kern.msgbufsize", &msgbufsize);
 
 	maxtsiz = MAXTSIZ;
 	TUNABLE_ULONG_FETCH("kern.maxtsiz", &maxtsiz);
--- sys/buf.h-81R	Sun Jun 13 19:09:06 2010
+++ sys/buf.h	Mon Dec 13 21:38:26 2010
@@ -449,6 +449,7 @@
 extern int	nbuf;			/* The number of buffer headers */
 extern long	maxswzone;		/* Max KVA for swap structures */
 extern long	maxbcache;		/* Max KVA for buffer cache */
+extern long	msgbufsize;		/* size of kernel message buffer */
 extern long	runningbufspace;
 extern long	hibufspace;
 extern int	dirtybufthresh;
-------------- next part --------------
--- i386/i386/machdep.c-81R	Sun Jun 13 19:09:06 2010
+++ i386/i386/machdep.c	Tue Dec 14 20:38:13 2010
@@ -2059,7 +2059,7 @@
 	physmem = Maxmem;
 	basemem = 0;
 	physmap[0] = init_first << PAGE_SHIFT;
-	physmap[1] = ptoa(Maxmem) - round_page(MSGBUF_SIZE);
+	physmap[1] = ptoa(Maxmem) - round_page(msgbufsize);
 	physmap_idx = 0;
 	goto physmap_done;
 #endif	
@@ -2445,7 +2445,7 @@
 	 * calculation, etc.).
 	 */
 	while (phys_avail[pa_indx - 1] + PAGE_SIZE +
-	    round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) {
+	    round_page(msgbufsize) >= phys_avail[pa_indx]) {
 		physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]);
 		phys_avail[pa_indx--] = 0;
 		phys_avail[pa_indx--] = 0;
@@ -2454,10 +2454,10 @@
 	Maxmem = atop(phys_avail[pa_indx]);
 
 	/* Trim off space for the message buffer. */
-	phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
+	phys_avail[pa_indx] -= round_page(msgbufsize);
 
 	/* Map the message buffer. */
-	for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
+	for (off = 0; off < round_page(msgbufsize); off += PAGE_SIZE)
 		pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
 		    off);
 
@@ -2666,7 +2666,7 @@
 
 	/* now running on new page tables, configured,and u/iom is accessible */
 
-	msgbufinit(msgbufp, MSGBUF_SIZE);
+	msgbufinit(msgbufp, msgbufsize);
 	/* transfer to user mode */
 
 	_ucodesel = GSEL(GUCODE_SEL, SEL_UPL);
@@ -2921,7 +2921,7 @@
 
 	/* now running on new page tables, configured,and u/iom is accessible */
 
-	msgbufinit(msgbufp, MSGBUF_SIZE);
+	msgbufinit(msgbufp, msgbufsize);
 
 	/* make a call gate to reenter kernel with */
 	gdp = &ldt[LSYS5CALLS_SEL].gd;
--- i386/i386/pmap.c-81R	Sun Jun 13 19:09:06 2010
+++ i386/i386/pmap.c	Tue Dec 14 20:38:17 2010
@@ -448,7 +448,7 @@
 	/*
 	 * msgbufp is used to map the system message buffer.
 	 */
-	SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(MSGBUF_SIZE)))
+	SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(msgbufsize)))
 
 	/*
 	 * KPTmap is used by pmap_kextract().
--- i386/xen/pmap.c-81R	Sun Jun 13 19:09:06 2010
+++ i386/xen/pmap.c	Tue Dec 14 20:38:09 2010
@@ -465,7 +465,7 @@
 	/*
 	 * msgbufp is used to map the system message buffer.
 	 */
-	SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(MSGBUF_SIZE)))
+	SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(msgbufsize)))
 
 	/*
 	 * ptemap is used for pmap_pte_quick
--- sys/msgbuf.h-81R	Sun Jun 13 19:09:06 2010
+++ sys/msgbuf.h	Tue Dec 14 20:38:03 2010
@@ -54,6 +54,7 @@
 #ifdef _KERNEL
 extern int	msgbuftrigger;
 extern struct	msgbuf *msgbufp;
+extern long	msgbufsize;
 
 void	msgbufinit(void *ptr, int size);
 void	msgbuf_addchar(struct msgbuf *mbp, int c);


More information about the freebsd-stable mailing list