Print this page
OS-4112 stack overflow from promisc callbacks
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
        
*** 21,59 ****
  
  /*
   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
- 
  /*
!  * FILE NOTICE BEGIN
!  *
!  * This file should not be modified.  If you wish to modify it or have it
!  * modified, please contact Sun Microsystems at <LFI149367@-sun-.-com->
!  * (without anti-spam dashes)
!  *
!  * FILE NOTICE END
   */
  
- #pragma ident   "%Z%%M% %I%     %E% SMI"
- 
  #include <sys/cpuvar.h>
  #include <sys/stack.h>
  #include <vm/seg_kp.h>
  #include <sys/proc.h>
  #include <sys/pset.h>
  #include <sys/sysmacros.h>
  
  /*
   * Create and initialize an interrupt thread.
   */
  static void
  thread_create_intr(cpu_t *cp)
  {
          kthread_t *tp;
  
!         tp = thread_create(NULL, 0,
              (void (*)())thread_create_intr, NULL, 0, &p0, TS_ONPROC, 0);
  
          /*
           * Set the thread in the TS_FREE state.  The state will change
           * to TS_ONPROC only while the interrupt is active.  Think of these
--- 21,61 ----
  
  /*
   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  /*
!  * Copyright 2015, Joyent, Inc.
   */
  
  #include <sys/cpuvar.h>
  #include <sys/stack.h>
  #include <vm/seg_kp.h>
  #include <sys/proc.h>
  #include <sys/pset.h>
  #include <sys/sysmacros.h>
  
  /*
+  * Use a slightly larger thread stack size for interrupt threads rather than the
+  * default. This is useful for cases where the networking stack may do an rx and
+  * a tx in the context of a single interrupt and when combined with various
+  * promisc hooks that need memory, can cause us to get dangerously close to the
+  * edge of the traditional stack sizes. This is only a few pages more than a
+  * traditional stack and given that we don't have that many interrupt threads,
+  * the memory costs end up being more than worthwhile.
+  */
+ #define LL_INTR_STKSZ   (32 * 1024)
+ 
+ /*
   * Create and initialize an interrupt thread.
   */
  static void
  thread_create_intr(cpu_t *cp)
  {
          kthread_t *tp;
  
!         tp = thread_create(NULL, LL_INTR_STKSZ,
              (void (*)())thread_create_intr, NULL, 0, &p0, TS_ONPROC, 0);
  
          /*
           * Set the thread in the TS_FREE state.  The state will change
           * to TS_ONPROC only while the interrupt is active.  Think of these
*** 95,107 ****
          tp->t_link = cp->cpu_intr_thread;
          cp->cpu_intr_thread = tp;
  }
  
  /*
!  * Allocate a given number of interrupt threads for a given CPU.
!  * These threads will get freed by cpu_destroy_bound_threads()
!  * when CPU gets unconfigured.
   */
  void
  cpu_intr_alloc(cpu_t *cp, int n)
  {
          int i;
--- 97,112 ----
          tp->t_link = cp->cpu_intr_thread;
          cp->cpu_intr_thread = tp;
  }
  
  /*
!  * Allocate a given number of interrupt threads for a given CPU.  These threads
!  * will get freed by cpu_destroy_bound_threads() when CPU gets unconfigured.
!  *
!  * Note, high level interrupts are always serviced using cpu_intr_stack and are
!  * not allowed to block. Low level interrupts or soft-interrupts use the
!  * kthread_t's that we create through the calls to thread_create_intr().
   */
  void
  cpu_intr_alloc(cpu_t *cp, int n)
  {
          int i;