changeset 13552:375fcb299d27

1925 stack overflow from mac code Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Michael Speer <michael.speer@pluribusnetworks.com> Reviewed by: Gordon Ross <gordon.w.ross@gmail.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Richard Lowe <richlowe@richlowe.net>
author Robert Mustacchi <rm@joyent.com>
date Fri, 23 Dec 2011 14:29:49 -0500
parents 022a137cd76d
children 3bed7426c561
files usr/src/uts/common/io/mac/mac_sched.c
diffstat 1 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/mac/mac_sched.c	Wed Dec 21 16:13:07 2011 -0500
+++ b/usr/src/uts/common/io/mac/mac_sched.c	Fri Dec 23 14:29:49 2011 -0500
@@ -22,6 +22,9 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2011 Joyent, Inc.  All rights reserved.
+ */
 
 #include <sys/types.h>
 #include <sys/callb.h>
@@ -29,6 +32,8 @@
 #include <sys/strsubr.h>
 #include <sys/strsun.h>
 #include <sys/vlan.h>
+#include <sys/stack.h>
+#include <sys/archsystm.h>
 #include <inet/ipsec_impl.h>
 #include <inet/ip_impl.h>
 #include <inet/sadb.h>
@@ -415,6 +420,28 @@
 }
 
 /*
+ * MAC_RX_SRS_TOODEEP
+ *
+ * Macro called as part of receive-side processing to determine if handling
+ * can occur in situ (in the interrupt thread) or if it should be left to a
+ * worker thread.  Note that the constant used to make this determination is
+ * not entirely made-up, and is a result of some emprical validation. That
+ * said, the constant is left as a static variable to allow it to be
+ * dynamically tuned in the field if and as needed.
+ */
+static uintptr_t mac_rx_srs_stack_needed = 10240;
+static uint_t mac_rx_srs_stack_toodeep;
+
+#ifndef STACK_GROWTH_DOWN
+#error Downward stack growth assumed.
+#endif
+
+#define	MAC_RX_SRS_TOODEEP() (STACK_BIAS + (uintptr_t)getfp() - \
+	(uintptr_t)curthread->t_stkbase < mac_rx_srs_stack_needed && \
+	++mac_rx_srs_stack_toodeep)
+
+
+/*
  * Drop the rx packet and advance to the next one in the chain.
  */
 static void
@@ -2419,11 +2446,12 @@
 
 	if (!(mac_srs->srs_state & SRS_PROC)) {
 		/*
-		 * If we are coming via loopback or if we are not
-		 * optimizing for latency, we should signal the
-		 * worker thread.
+		 * If we are coming via loopback, if we are not optimizing for
+		 * latency, or if our stack is running deep, we should signal
+		 * the worker thread.
 		 */
-		if (loopback || !(mac_srs->srs_state & SRS_LATENCY_OPT)) {
+		if (loopback || !(mac_srs->srs_state & SRS_LATENCY_OPT) ||
+		    MAC_RX_SRS_TOODEEP()) {
 			/*
 			 * For loopback, We need to let the worker take
 			 * over as we don't want to continue in the same