5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * IP interface to squeues.
  28  *
  29  * IP uses squeues to force serialization of packets, both incoming and
  30  * outgoing. Each squeue is associated with a connection instance (conn_t)
  31  * above, and a soft ring (if enabled) below. Each CPU will have a default
  32  * squeue for outbound connections, and each soft ring of an interface will
  33  * have an squeue to which it sends incoming packets. squeues are never
  34  * destroyed, and if they become unused they are kept around against future
  35  * needs.
  36  *
  37  * IP organizes its squeues using squeue sets (squeue_set_t). For each CPU
  38  * in the system there will be one squeue set, all of whose squeues will be
  39  * bound to that CPU, plus one additional set known as the unbound set. Sets
  40  * associated with CPUs will have one default squeue, for outbound
  41  * connections, and a linked list of squeues used by various NICs for inbound
  42  * packets. The unbound set also has a linked list of squeues, but no default
  43  * squeue.
  44  *
 
 
 130 #include <sys/strsubr.h>
 131 #include <sys/zone.h>
 132 #include <sys/dld.h>
 133 #include <sys/atomic.h>
 134 
 135 /*
 136  * List of all created squeue sets. The list and its size are protected by
 137  * sqset_lock.
 138  */
 139 static squeue_set_t     **sqset_global_list; /* list 0 is the unbound list */
 140 static uint_t           sqset_global_size;
 141 kmutex_t                sqset_lock;
 142 
 143 static void (*ip_squeue_create_callback)(squeue_t *) = NULL;
 144 
 145 /*
 146  * ip_squeue_worker_wait: global value for the sq_wait field for all squeues
 147  *      created. This is the time squeue code waits before waking up the worker
 148  *      thread after queuing a request.
 149  */
 150 uint_t ip_squeue_worker_wait = 10;
 151 
 152 static squeue_t *ip_squeue_create(pri_t);
 153 static squeue_set_t *ip_squeue_set_create(processorid_t);
 154 static int ip_squeue_cpu_setup(cpu_setup_t, int, void *);
 155 static void ip_squeue_set_move(squeue_t *, squeue_set_t *);
 156 static void ip_squeue_set_destroy(cpu_t *);
 157 static void ip_squeue_clean(void *, mblk_t *, void *);
 158 
 159 #define CPU_ISON(c) (c != NULL && CPU_ACTIVE(c) && (c->cpu_flags & CPU_EXISTS))
 160 
 161 static squeue_t *
 162 ip_squeue_create(pri_t pri)
 163 {
 164         squeue_t *sqp;
 165 
 166         sqp = squeue_create(ip_squeue_worker_wait, pri);
 167         ASSERT(sqp != NULL);
 168         if (ip_squeue_create_callback != NULL)
 169                 ip_squeue_create_callback(sqp);
 170         return (sqp);
 
 | 
 
 
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * IP interface to squeues.
  31  *
  32  * IP uses squeues to force serialization of packets, both incoming and
  33  * outgoing. Each squeue is associated with a connection instance (conn_t)
  34  * above, and a soft ring (if enabled) below. Each CPU will have a default
  35  * squeue for outbound connections, and each soft ring of an interface will
  36  * have an squeue to which it sends incoming packets. squeues are never
  37  * destroyed, and if they become unused they are kept around against future
  38  * needs.
  39  *
  40  * IP organizes its squeues using squeue sets (squeue_set_t). For each CPU
  41  * in the system there will be one squeue set, all of whose squeues will be
  42  * bound to that CPU, plus one additional set known as the unbound set. Sets
  43  * associated with CPUs will have one default squeue, for outbound
  44  * connections, and a linked list of squeues used by various NICs for inbound
  45  * packets. The unbound set also has a linked list of squeues, but no default
  46  * squeue.
  47  *
 
 
 133 #include <sys/strsubr.h>
 134 #include <sys/zone.h>
 135 #include <sys/dld.h>
 136 #include <sys/atomic.h>
 137 
 138 /*
 139  * List of all created squeue sets. The list and its size are protected by
 140  * sqset_lock.
 141  */
 142 static squeue_set_t     **sqset_global_list; /* list 0 is the unbound list */
 143 static uint_t           sqset_global_size;
 144 kmutex_t                sqset_lock;
 145 
 146 static void (*ip_squeue_create_callback)(squeue_t *) = NULL;
 147 
 148 /*
 149  * ip_squeue_worker_wait: global value for the sq_wait field for all squeues
 150  *      created. This is the time squeue code waits before waking up the worker
 151  *      thread after queuing a request.
 152  */
 153 volatile uint_t ip_squeue_worker_wait = 10;
 154 
 155 static squeue_t *ip_squeue_create(pri_t);
 156 static squeue_set_t *ip_squeue_set_create(processorid_t);
 157 static int ip_squeue_cpu_setup(cpu_setup_t, int, void *);
 158 static void ip_squeue_set_move(squeue_t *, squeue_set_t *);
 159 static void ip_squeue_set_destroy(cpu_t *);
 160 static void ip_squeue_clean(void *, mblk_t *, void *);
 161 
 162 #define CPU_ISON(c) (c != NULL && CPU_ACTIVE(c) && (c->cpu_flags & CPU_EXISTS))
 163 
 164 static squeue_t *
 165 ip_squeue_create(pri_t pri)
 166 {
 167         squeue_t *sqp;
 168 
 169         sqp = squeue_create(ip_squeue_worker_wait, pri);
 170         ASSERT(sqp != NULL);
 171         if (ip_squeue_create_callback != NULL)
 172                 ip_squeue_create_callback(sqp);
 173         return (sqp);
 
 |