Kernel/Compiler bug

Larry Baird lab at gta.com
Fri Oct 3 01:54:59 UTC 2014


> The easiest thing to do is to record the stack depth for kernel mode
> on entry into interrupt.  Interrupt handlers are usually well written
> and do not consume a lot of stack.
> 
> Look at the intr_event_handle(), which is the entry point. The mode can
> be deduced from trapframe passed. The kernel stack for the thread is
> described by td->td_kstack (base, i.e. bottom) and td->td_kstack_pages
> (size), so the top of the stack is at td_kstack + td_kstack_size [*].
> The current stack consumption could be taken from reading %rsp register,
> or you may take the address of any local variable as well.
> 
> * - there are pcb and usermode fpu save area at the top of the stack, and
> actual kernel stack top is right below fpu save area.  This should not
> be important for your measurements, since you are looking at how close
> the %rsp gets to the bottom.

This idea worked very well.  Booting a GENERIC 10.1-BETA3 kernel I get a
maximum stack used of 5247 bytes. This was with a minimal virtual box
configuration. It would be interesting to hear about users with more exotic
hardware and or configurations. Not sure if I have the KASSERT correct.



Index: kern_intr.c
===================================================================
--- kern_intr.c	(revision 44897)
+++ kern_intr.c	(working copy)
@@ -1386,6 +1386,12 @@
 	}
 }
 
+static int max_kern_thread_stack;
+
+SYSCTL_INT(_kern, OID_AUTO, max_kern_thread_stack, CTLFLAG_RD,
+    &max_kern_thread_stack, 0,
+    "Maxiumum stack used by a kernel thread");
+
 /*
  * Main interrupt handling body.
  *
@@ -1407,6 +1413,22 @@
 
 	td = curthread;
 
+	/*
+	 * Check for maximum stack used bya kernel thread.
+	 */
+	if (!TRAPF_USERMODE(frame)) {
+	    char *top = (char *)(td->td_kstack + td->td_kstack_pages *
+		PAGE_SIZE - 1);
+	    char *current = (char *)&ih;
+	    int used = top - current;
+
+	    if (used > max_kern_thread_stack) {
+		max_kern_thread_stack = used;
+		KASSERT(max_kern_thread_stack < KSTACK_PAGES * PAGE_SIZE,
+		    "Maximum kernel thread stack exxceeded");
+	    }
+	}
+
 	/* An interrupt with no event or handlers is a stray interrupt. */
 	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers))
 		return (EINVAL);

-- 
------------------------------------------------------------------------
Larry Baird
Global Technology Associates, Inc. 1992-2012 	| http://www.gta.com
Celebrating Twenty Years of Software Innovation | Orlando, FL
Email: lab at gta.com                 		| TEL 407-380-0220


More information about the freebsd-hackers mailing list