Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/disp/thread_intr.c
          +++ new/usr/src/uts/common/disp/thread_intr.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  /*
  27   27   * Copyright 2015, Joyent, Inc.
  28   28   */
  29   29  
  30   30  #include <sys/cpuvar.h>
  31   31  #include <sys/stack.h>
  32   32  #include <vm/seg_kp.h>
  33   33  #include <sys/proc.h>
  34   34  #include <sys/pset.h>
  35   35  #include <sys/sysmacros.h>
  36   36  
  37   37  /*
  38   38   * Use a slightly larger thread stack size for interrupt threads rather than the
  39   39   * default. This is useful for cases where the networking stack may do an rx and
  40   40   * a tx in the context of a single interrupt and when combined with various
  41   41   * promisc hooks that need memory, can cause us to get dangerously close to the
  42   42   * edge of the traditional stack sizes. This is only a few pages more than a
  43   43   * traditional stack and given that we don't have that many interrupt threads,
  44   44   * the memory costs end up being more than worthwhile.
  45   45   */
  46   46  #define LL_INTR_STKSZ   (32 * 1024)
  47   47  
  48   48  /*
  49   49   * Create and initialize an interrupt thread.
  50   50   */
  51   51  static void
  52   52  thread_create_intr(cpu_t *cp)
  53   53  {
  54   54          kthread_t *tp;
  55   55  
  56   56          tp = thread_create(NULL, LL_INTR_STKSZ,
  57   57              (void (*)())thread_create_intr, NULL, 0, &p0, TS_ONPROC, 0);
  58   58  
  59   59          /*
  60   60           * Set the thread in the TS_FREE state.  The state will change
  61   61           * to TS_ONPROC only while the interrupt is active.  Think of these
  62   62           * as being on a private free list for the CPU.  Being TS_FREE keeps
  63   63           * inactive interrupt threads out of debugger thread lists.
  64   64           *
  65   65           * We cannot call thread_create with TS_FREE because of the current
  66   66           * checks there for ONPROC.  Fix this when thread_create takes flags.
  67   67           */
  68   68          THREAD_FREEINTR(tp, cp);
  69   69  
  70   70          /*
  71   71           * Nobody should ever reference the credentials of an interrupt
  72   72           * thread so make it NULL to catch any such references.
  73   73           */
  74   74          tp->t_cred = NULL;
  75   75          tp->t_flag |= T_INTR_THREAD;
  76   76          tp->t_cpu = cp;
  77   77          tp->t_bound_cpu = cp;
  78   78          tp->t_disp_queue = cp->cpu_disp;
  79   79          tp->t_affinitycnt = 1;
  80   80          tp->t_preempt = 1;
  81   81  
  82   82          /*
  83   83           * Don't make a user-requested binding on this thread so that
  84   84           * the processor can be offlined.
  85   85           */
  86   86          tp->t_bind_cpu = PBIND_NONE;    /* no USER-requested binding */
  87   87          tp->t_bind_pset = PS_NONE;
  88   88  
  89   89  #if defined(__i386) || defined(__amd64)
  90   90          tp->t_stk -= STACK_ALIGN;
  91   91          *(tp->t_stk) = 0;               /* terminate intr thread stack */
  92   92  #endif
  93   93  
  94   94          /*
  95   95           * Link onto CPU's interrupt pool.
  96   96           */
  97   97          tp->t_link = cp->cpu_intr_thread;
  98   98          cp->cpu_intr_thread = tp;
  99   99  }
 100  100  
 101  101  /*
 102  102   * Allocate a given number of interrupt threads for a given CPU.  These threads
 103  103   * will get freed by cpu_destroy_bound_threads() when CPU gets unconfigured.
 104  104   *
 105  105   * Note, high level interrupts are always serviced using cpu_intr_stack and are
 106  106   * not allowed to block. Low level interrupts or soft-interrupts use the
 107  107   * kthread_t's that we create through the calls to thread_create_intr().
 108  108   */
 109  109  void
 110  110  cpu_intr_alloc(cpu_t *cp, int n)
 111  111  {
 112  112          int i;
 113  113  
 114  114          for (i = 0; i < n; i++)
 115  115                  thread_create_intr(cp);
 116  116  
 117  117          cp->cpu_intr_stack = (caddr_t)segkp_get(segkp, INTR_STACK_SIZE,
 118  118              KPD_HASREDZONE | KPD_NO_ANON | KPD_LOCKED) +
 119  119              INTR_STACK_SIZE - SA(MINFRAME);
 120  120  }
  
    | 
      ↓ open down ↓ | 
    120 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX