Print this page
re #13613 rb4516 Tunables needs volatile keyword
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/inet/sctp/sctp_misc.c
+++ new/usr/src/uts/common/inet/sctp/sctp_misc.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
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 25 */
25 26
26 27 #include <sys/types.h>
28 +#include <sys/vmsystm.h>
27 29 #include <inet/common.h>
28 30 #include "sctp_impl.h"
29 31
30 32 /* Control whether SCTP can enter defensive mode when under memory pressure. */
31 33 static boolean_t sctp_do_reclaim = B_TRUE;
32 34
33 35 static void sctp_reclaim_timer(void *);
34 36
35 37 /* Diagnostic routine used to return a string associated with the sctp state. */
36 38 char *
37 39 sctp_display(sctp_t *sctp, char *sup_buf)
38 40 {
39 41 char *buf;
40 42 char buf1[30];
41 43 static char priv_buf[INET6_ADDRSTRLEN * 2 + 80];
42 44 char *cp;
43 45 conn_t *connp;
44 46
45 47 if (sctp == NULL)
46 48 return ("NULL_SCTP");
47 49
48 50 connp = sctp->sctp_connp;
49 51 buf = (sup_buf != NULL) ? sup_buf : priv_buf;
50 52
51 53 switch (sctp->sctp_state) {
52 54 case SCTPS_IDLE:
53 55 cp = "SCTP_IDLE";
54 56 break;
55 57 case SCTPS_BOUND:
56 58 cp = "SCTP_BOUND";
57 59 break;
58 60 case SCTPS_LISTEN:
59 61 cp = "SCTP_LISTEN";
60 62 break;
61 63 case SCTPS_COOKIE_WAIT:
62 64 cp = "SCTP_COOKIE_WAIT";
63 65 break;
64 66 case SCTPS_COOKIE_ECHOED:
65 67 cp = "SCTP_COOKIE_ECHOED";
66 68 break;
67 69 case SCTPS_ESTABLISHED:
68 70 cp = "SCTP_ESTABLISHED";
69 71 break;
70 72 case SCTPS_SHUTDOWN_PENDING:
71 73 cp = "SCTP_SHUTDOWN_PENDING";
72 74 break;
73 75 case SCTPS_SHUTDOWN_SENT:
74 76 cp = "SCTPS_SHUTDOWN_SENT";
75 77 break;
76 78 case SCTPS_SHUTDOWN_RECEIVED:
77 79 cp = "SCTPS_SHUTDOWN_RECEIVED";
78 80 break;
79 81 case SCTPS_SHUTDOWN_ACK_SENT:
80 82 cp = "SCTPS_SHUTDOWN_ACK_SENT";
81 83 break;
82 84 default:
83 85 (void) mi_sprintf(buf1, "SCTPUnkState(%d)", sctp->sctp_state);
84 86 cp = buf1;
85 87 break;
86 88 }
87 89 (void) mi_sprintf(buf, "[%u, %u] %s",
88 90 ntohs(connp->conn_lport), ntohs(connp->conn_fport), cp);
89 91
90 92 return (buf);
91 93 }
92 94
93 95 void
94 96 sctp_display_all(sctp_stack_t *sctps)
95 97 {
96 98 sctp_t *sctp_walker;
97 99
98 100 mutex_enter(&sctps->sctps_g_lock);
99 101 for (sctp_walker = list_head(&sctps->sctps_g_list);
100 102 sctp_walker != NULL;
101 103 sctp_walker = (sctp_t *)list_next(&sctps->sctps_g_list,
102 104 sctp_walker)) {
103 105 (void) sctp_display(sctp_walker, NULL);
104 106 }
105 107 mutex_exit(&sctps->sctps_g_lock);
106 108 }
107 109
108 110 /*
109 111 * Given a sctp_stack_t and a port (in host byte order), find a listener
110 112 * configuration for that port and return the ratio.
111 113 */
112 114 uint32_t
113 115 sctp_find_listener_conf(sctp_stack_t *sctps, in_port_t port)
114 116 {
115 117 sctp_listener_t *sl;
116 118 uint32_t ratio = 0;
117 119
118 120 mutex_enter(&sctps->sctps_listener_conf_lock);
119 121 for (sl = list_head(&sctps->sctps_listener_conf); sl != NULL;
120 122 sl = list_next(&sctps->sctps_listener_conf, sl)) {
121 123 if (sl->sl_port == port) {
122 124 ratio = sl->sl_ratio;
123 125 break;
124 126 }
125 127 }
126 128 mutex_exit(&sctps->sctps_listener_conf_lock);
127 129 return (ratio);
128 130 }
129 131
130 132 /*
131 133 * To remove all listener limit configuration in a sctp_stack_t.
132 134 */
133 135 void
134 136 sctp_listener_conf_cleanup(sctp_stack_t *sctps)
135 137 {
136 138 sctp_listener_t *sl;
137 139
138 140 mutex_enter(&sctps->sctps_listener_conf_lock);
139 141 while ((sl = list_head(&sctps->sctps_listener_conf)) != NULL) {
140 142 list_remove(&sctps->sctps_listener_conf, sl);
141 143 kmem_free(sl, sizeof (sctp_listener_t));
142 144 }
143 145 mutex_destroy(&sctps->sctps_listener_conf_lock);
144 146 list_destroy(&sctps->sctps_listener_conf);
145 147 }
146 148
|
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
147 149
148 150 /*
149 151 * Timeout function to reset the SCTP stack variable sctps_reclaim to false.
150 152 */
151 153 static void
152 154 sctp_reclaim_timer(void *arg)
153 155 {
154 156 sctp_stack_t *sctps = (sctp_stack_t *)arg;
155 157 int64_t tot_assoc = 0;
156 158 int i;
157 - extern pgcnt_t lotsfree, needfree;
158 159
159 160 for (i = 0; i < sctps->sctps_sc_cnt; i++)
160 161 tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
161 162
162 163 /*
163 164 * This happens only when a stack is going away. sctps_reclaim_tid
164 165 * should not be reset to 0 when returning in this case.
165 166 */
166 167 mutex_enter(&sctps->sctps_reclaim_lock);
167 168 if (!sctps->sctps_reclaim) {
168 169 mutex_exit(&sctps->sctps_reclaim_lock);
169 170 return;
170 171 }
171 172
172 173 if ((freemem >= lotsfree + needfree) || tot_assoc < maxusers) {
173 174 sctps->sctps_reclaim = B_FALSE;
174 175 sctps->sctps_reclaim_tid = 0;
175 176 } else {
176 177 /* Stay in defensive mode and restart the timer */
177 178 sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
178 179 sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
179 180 }
180 181 mutex_exit(&sctps->sctps_reclaim_lock);
181 182 }
182 183
183 184 /*
184 185 * Kmem reclaim call back function. When the system is under memory
185 186 * pressure, we set the SCTP stack variable sctps_reclaim to true. This
186 187 * variable is reset to false after sctps_reclaim_period msecs. During this
187 188 * period, SCTP will be more aggressive in aborting connections not making
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
188 189 * progress, meaning retransmitting for shorter time (sctp_pa_early_abort/
189 190 * sctp_pp_early_abort number of strikes).
190 191 */
191 192 /* ARGSUSED */
192 193 void
193 194 sctp_conn_reclaim(void *arg)
194 195 {
195 196 netstack_handle_t nh;
196 197 netstack_t *ns;
197 198 sctp_stack_t *sctps;
198 - extern pgcnt_t lotsfree, needfree;
199 199
200 200 if (!sctp_do_reclaim)
201 201 return;
202 202
203 203 /*
204 204 * The reclaim function may be called even when the system is not
205 205 * really under memory pressure.
206 206 */
207 207 if (freemem >= lotsfree + needfree)
208 208 return;
209 209
210 210 netstack_next_init(&nh);
211 211 while ((ns = netstack_next(&nh)) != NULL) {
212 212 int i;
213 213 int64_t tot_assoc = 0;
214 214
215 215 /*
216 216 * During boot time, the first netstack_t is created and
217 217 * initialized before SCTP has registered with the netstack
218 218 * framework. If this reclaim function is called before SCTP
219 219 * has finished its initialization, netstack_next() will
220 220 * return the first netstack_t (since its netstack_flags is
221 221 * not NSF_UNINIT). And its netstack_sctp will be NULL. We
222 222 * need to catch it.
223 223 *
224 224 * All subsequent netstack_t creation will not have this
225 225 * problem since the initialization is not finished until SCTP
226 226 * has finished its own sctp_stack_t initialization. Hence
227 227 * netstack_next() will not return one with NULL netstack_sctp.
228 228 */
229 229 if ((sctps = ns->netstack_sctp) == NULL) {
230 230 netstack_rele(ns);
231 231 continue;
232 232 }
233 233
234 234 /*
235 235 * Even if the system is under memory pressure, the reason may
236 236 * not be because of SCTP activity. Check the number of
237 237 * associations in each stack. If the number exceeds the
238 238 * threshold (maxusers), turn on defensive mode.
239 239 */
240 240 for (i = 0; i < sctps->sctps_sc_cnt; i++)
241 241 tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
242 242 if (tot_assoc < maxusers) {
243 243 netstack_rele(ns);
244 244 continue;
245 245 }
246 246
247 247 mutex_enter(&sctps->sctps_reclaim_lock);
248 248 if (!sctps->sctps_reclaim) {
249 249 sctps->sctps_reclaim = B_TRUE;
250 250 sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
251 251 sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
252 252 SCTP_KSTAT(sctps, sctp_reclaim_cnt);
253 253 }
254 254 mutex_exit(&sctps->sctps_reclaim_lock);
255 255 netstack_rele(ns);
256 256 }
257 257 netstack_next_fini(&nh);
258 258 }
259 259
260 260 /*
261 261 * When a CPU is added, we need to allocate the per CPU stats struct.
262 262 */
263 263 void
264 264 sctp_stack_cpu_add(sctp_stack_t *sctps, processorid_t cpu_seqid)
265 265 {
266 266 int i;
267 267
268 268 if (cpu_seqid < sctps->sctps_sc_cnt)
269 269 return;
270 270 for (i = sctps->sctps_sc_cnt; i <= cpu_seqid; i++) {
271 271 ASSERT(sctps->sctps_sc[i] == NULL);
272 272 sctps->sctps_sc[i] = kmem_zalloc(sizeof (sctp_stats_cpu_t),
273 273 KM_SLEEP);
274 274 }
275 275 membar_producer();
276 276 sctps->sctps_sc_cnt = cpu_seqid + 1;
277 277 }
|
↓ open down ↓ |
69 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX