4 * The contents of this file are subject to the terms of the
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 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <inet/common.h>
28 #include "sctp_impl.h"
29
30 /* Control whether SCTP can enter defensive mode when under memory pressure. */
31 static boolean_t sctp_do_reclaim = B_TRUE;
32
33 static void sctp_reclaim_timer(void *);
34
35 /* Diagnostic routine used to return a string associated with the sctp state. */
36 char *
37 sctp_display(sctp_t *sctp, char *sup_buf)
38 {
39 char *buf;
40 char buf1[30];
41 static char priv_buf[INET6_ADDRSTRLEN * 2 + 80];
42 char *cp;
43 conn_t *connp;
44
45 if (sctp == NULL)
46 return ("NULL_SCTP");
137
138 mutex_enter(&sctps->sctps_listener_conf_lock);
139 while ((sl = list_head(&sctps->sctps_listener_conf)) != NULL) {
140 list_remove(&sctps->sctps_listener_conf, sl);
141 kmem_free(sl, sizeof (sctp_listener_t));
142 }
143 mutex_destroy(&sctps->sctps_listener_conf_lock);
144 list_destroy(&sctps->sctps_listener_conf);
145 }
146
147
148 /*
149 * Timeout function to reset the SCTP stack variable sctps_reclaim to false.
150 */
151 static void
152 sctp_reclaim_timer(void *arg)
153 {
154 sctp_stack_t *sctps = (sctp_stack_t *)arg;
155 int64_t tot_assoc = 0;
156 int i;
157 extern pgcnt_t lotsfree, needfree;
158
159 for (i = 0; i < sctps->sctps_sc_cnt; i++)
160 tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
161
162 /*
163 * This happens only when a stack is going away. sctps_reclaim_tid
164 * should not be reset to 0 when returning in this case.
165 */
166 mutex_enter(&sctps->sctps_reclaim_lock);
167 if (!sctps->sctps_reclaim) {
168 mutex_exit(&sctps->sctps_reclaim_lock);
169 return;
170 }
171
172 if ((freemem >= lotsfree + needfree) || tot_assoc < maxusers) {
173 sctps->sctps_reclaim = B_FALSE;
174 sctps->sctps_reclaim_tid = 0;
175 } else {
176 /* Stay in defensive mode and restart the timer */
177 sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
178 sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
179 }
180 mutex_exit(&sctps->sctps_reclaim_lock);
181 }
182
183 /*
184 * Kmem reclaim call back function. When the system is under memory
185 * pressure, we set the SCTP stack variable sctps_reclaim to true. This
186 * variable is reset to false after sctps_reclaim_period msecs. During this
187 * period, SCTP will be more aggressive in aborting connections not making
188 * progress, meaning retransmitting for shorter time (sctp_pa_early_abort/
189 * sctp_pp_early_abort number of strikes).
190 */
191 /* ARGSUSED */
192 void
193 sctp_conn_reclaim(void *arg)
194 {
195 netstack_handle_t nh;
196 netstack_t *ns;
197 sctp_stack_t *sctps;
198 extern pgcnt_t lotsfree, needfree;
199
200 if (!sctp_do_reclaim)
201 return;
202
203 /*
204 * The reclaim function may be called even when the system is not
205 * really under memory pressure.
206 */
207 if (freemem >= lotsfree + needfree)
208 return;
209
210 netstack_next_init(&nh);
211 while ((ns = netstack_next(&nh)) != NULL) {
212 int i;
213 int64_t tot_assoc = 0;
214
215 /*
216 * During boot time, the first netstack_t is created and
217 * initialized before SCTP has registered with the netstack
218 * framework. If this reclaim function is called before SCTP
|
4 * The contents of this file are subject to the terms of the
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 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/vmsystm.h>
29 #include <inet/common.h>
30 #include "sctp_impl.h"
31
32 /* Control whether SCTP can enter defensive mode when under memory pressure. */
33 static boolean_t sctp_do_reclaim = B_TRUE;
34
35 static void sctp_reclaim_timer(void *);
36
37 /* Diagnostic routine used to return a string associated with the sctp state. */
38 char *
39 sctp_display(sctp_t *sctp, char *sup_buf)
40 {
41 char *buf;
42 char buf1[30];
43 static char priv_buf[INET6_ADDRSTRLEN * 2 + 80];
44 char *cp;
45 conn_t *connp;
46
47 if (sctp == NULL)
48 return ("NULL_SCTP");
139
140 mutex_enter(&sctps->sctps_listener_conf_lock);
141 while ((sl = list_head(&sctps->sctps_listener_conf)) != NULL) {
142 list_remove(&sctps->sctps_listener_conf, sl);
143 kmem_free(sl, sizeof (sctp_listener_t));
144 }
145 mutex_destroy(&sctps->sctps_listener_conf_lock);
146 list_destroy(&sctps->sctps_listener_conf);
147 }
148
149
150 /*
151 * Timeout function to reset the SCTP stack variable sctps_reclaim to false.
152 */
153 static void
154 sctp_reclaim_timer(void *arg)
155 {
156 sctp_stack_t *sctps = (sctp_stack_t *)arg;
157 int64_t tot_assoc = 0;
158 int i;
159
160 for (i = 0; i < sctps->sctps_sc_cnt; i++)
161 tot_assoc += sctps->sctps_sc[i]->sctp_sc_assoc_cnt;
162
163 /*
164 * This happens only when a stack is going away. sctps_reclaim_tid
165 * should not be reset to 0 when returning in this case.
166 */
167 mutex_enter(&sctps->sctps_reclaim_lock);
168 if (!sctps->sctps_reclaim) {
169 mutex_exit(&sctps->sctps_reclaim_lock);
170 return;
171 }
172
173 if ((freemem >= lotsfree + needfree) || tot_assoc < maxusers) {
174 sctps->sctps_reclaim = B_FALSE;
175 sctps->sctps_reclaim_tid = 0;
176 } else {
177 /* Stay in defensive mode and restart the timer */
178 sctps->sctps_reclaim_tid = timeout(sctp_reclaim_timer,
179 sctps, MSEC_TO_TICK(sctps->sctps_reclaim_period));
180 }
181 mutex_exit(&sctps->sctps_reclaim_lock);
182 }
183
184 /*
185 * Kmem reclaim call back function. When the system is under memory
186 * pressure, we set the SCTP stack variable sctps_reclaim to true. This
187 * variable is reset to false after sctps_reclaim_period msecs. During this
188 * period, SCTP will be more aggressive in aborting connections not making
189 * progress, meaning retransmitting for shorter time (sctp_pa_early_abort/
190 * sctp_pp_early_abort number of strikes).
191 */
192 /* ARGSUSED */
193 void
194 sctp_conn_reclaim(void *arg)
195 {
196 netstack_handle_t nh;
197 netstack_t *ns;
198 sctp_stack_t *sctps;
199
200 if (!sctp_do_reclaim)
201 return;
202
203 /*
204 * The reclaim function may be called even when the system is not
205 * really under memory pressure.
206 */
207 if (freemem >= lotsfree + needfree)
208 return;
209
210 netstack_next_init(&nh);
211 while ((ns = netstack_next(&nh)) != NULL) {
212 int i;
213 int64_t tot_assoc = 0;
214
215 /*
216 * During boot time, the first netstack_t is created and
217 * initialized before SCTP has registered with the netstack
218 * framework. If this reclaim function is called before SCTP
|