Print this page
5255 uts shouldn't open-code ISP2
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/clients/rds/rdssubr.c
+++ new/usr/src/uts/common/io/ib/clients/rds/rdssubr.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
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 +#include <sys/sysmacros.h>
26 27 #include <sys/ib/clients/rds/rds.h>
27 28 #include <sys/ib/clients/rds/rds_kstat.h>
28 29
29 30 #include <inet/ipclassifier.h>
30 31
31 32 struct rds_kstat_s rds_kstat = {
32 33 {"rds_nports", KSTAT_DATA_ULONG},
33 34 {"rds_nsessions", KSTAT_DATA_ULONG},
34 35 {"rds_tx_bytes", KSTAT_DATA_ULONG},
35 36 {"rds_tx_pkts", KSTAT_DATA_ULONG},
36 37 {"rds_tx_errors", KSTAT_DATA_ULONG},
37 38 {"rds_rx_bytes", KSTAT_DATA_ULONG},
38 39 {"rds_rx_pkts", KSTAT_DATA_ULONG},
39 40 {"rds_rx_pkts_pending", KSTAT_DATA_ULONG},
40 41 {"rds_rx_errors", KSTAT_DATA_ULONG},
41 42 {"rds_tx_acks", KSTAT_DATA_ULONG},
42 43 {"rds_post_recv_buf_called", KSTAT_DATA_ULONG},
43 44 {"rds_stalls_triggered", KSTAT_DATA_ULONG},
44 45 {"rds_stalls_sent", KSTAT_DATA_ULONG},
45 46 {"rds_unstalls_triggered", KSTAT_DATA_ULONG},
46 47 {"rds_unstalls_sent", KSTAT_DATA_ULONG},
47 48 {"rds_stalls_recvd", KSTAT_DATA_ULONG},
48 49 {"rds_unstalls_recvd", KSTAT_DATA_ULONG},
49 50 {"rds_stalls_ignored", KSTAT_DATA_ULONG},
50 51 {"rds_enobufs", KSTAT_DATA_ULONG},
51 52 {"rds_ewouldblocks", KSTAT_DATA_ULONG},
52 53 {"rds_failovers", KSTAT_DATA_ULONG},
53 54 {"rds_port_quota", KSTAT_DATA_ULONG},
54 55 {"rds_port_quota_adjusted", KSTAT_DATA_ULONG},
55 56 };
56 57
57 58 kstat_t *rds_kstatsp;
58 59 static kmutex_t rds_kstat_mutex;
59 60
60 61
61 62 struct kmem_cache *rds_alloc_cache;
62 63
63 64 uint_t rds_bind_fanout_size = RDS_BIND_FANOUT_SIZE;
64 65 rds_bf_t *rds_bind_fanout;
65 66
66 67 void
67 68 rds_increment_kstat(kstat_named_t *ksnp, boolean_t lock, uint_t num)
68 69 {
69 70 if (lock)
70 71 mutex_enter(&rds_kstat_mutex);
71 72 ksnp->value.ul += num;
72 73 if (lock)
73 74 mutex_exit(&rds_kstat_mutex);
74 75 }
75 76
76 77 void
77 78 rds_decrement_kstat(kstat_named_t *ksnp, boolean_t lock, uint_t num)
78 79 {
79 80 if (lock)
80 81 mutex_enter(&rds_kstat_mutex);
81 82 ksnp->value.ul -= num;
82 83 if (lock)
83 84 mutex_exit(&rds_kstat_mutex);
84 85 }
85 86
86 87 void
87 88 rds_set_kstat(kstat_named_t *ksnp, boolean_t lock, ulong_t num)
88 89 {
89 90 if (lock)
90 91 mutex_enter(&rds_kstat_mutex);
91 92 ksnp->value.ul = num;
92 93 if (lock)
93 94 mutex_exit(&rds_kstat_mutex);
94 95 }
95 96
96 97 ulong_t
97 98 rds_get_kstat(kstat_named_t *ksnp, boolean_t lock)
98 99 {
99 100 ulong_t value;
100 101
101 102 if (lock)
102 103 mutex_enter(&rds_kstat_mutex);
103 104 value = ksnp->value.ul;
104 105 if (lock)
105 106 mutex_exit(&rds_kstat_mutex);
106 107
107 108 return (value);
108 109 }
109 110
110 111
111 112 void
112 113 rds_fini()
113 114 {
114 115 int i;
115 116
116 117 for (i = 0; i < rds_bind_fanout_size; i++) {
117 118 mutex_destroy(&rds_bind_fanout[i].rds_bf_lock);
118 119 }
119 120 kmem_free(rds_bind_fanout, rds_bind_fanout_size * sizeof (rds_bf_t));
120 121
121 122 kmem_cache_destroy(rds_alloc_cache);
122 123 kstat_delete(rds_kstatsp);
123 124 }
124 125
125 126
126 127 void
127 128 rds_init()
128 129 {
129 130 rds_alloc_cache = kmem_cache_create("rds_alloc_cache",
130 131 sizeof (rds_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
131 132 rds_hash_init();
132 133 /*
133 134 * kstats
134 135 */
135 136 rds_kstatsp = kstat_create("rds", 0,
136 137 "rds_kstat", "misc", KSTAT_TYPE_NAMED,
137 138 sizeof (rds_kstat) / sizeof (kstat_named_t),
138 139 KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE);
139 140 if (rds_kstatsp != NULL) {
140 141 rds_kstatsp->ks_lock = &rds_kstat_mutex;
141 142 rds_kstatsp->ks_data = (void *)&rds_kstat;
↓ open down ↓ |
106 lines elided |
↑ open up ↑ |
142 143 kstat_install(rds_kstatsp);
143 144 }
144 145 }
145 146
146 147 #define UINT_32_BITS 31
147 148 void
148 149 rds_hash_init()
149 150 {
150 151 int i;
151 152
152 - if (rds_bind_fanout_size & (rds_bind_fanout_size - 1)) {
153 + if (!ISP2(rds_bind_fanout_size)) {
153 154 /* Not a power of two. Round up to nearest power of two */
154 155 for (i = 0; i < UINT_32_BITS; i++) {
155 156 if (rds_bind_fanout_size < (1 << i))
156 157 break;
157 158 }
158 159 rds_bind_fanout_size = 1 << i;
159 160 }
160 161 rds_bind_fanout = kmem_zalloc(rds_bind_fanout_size *
161 162 sizeof (rds_bf_t), KM_SLEEP);
162 163 for (i = 0; i < rds_bind_fanout_size; i++) {
163 164 mutex_init(&rds_bind_fanout[i].rds_bf_lock, NULL, MUTEX_DEFAULT,
164 165 NULL);
165 166 }
166 167 }
167 168
168 169 void
169 170 rds_free(rds_t *rds)
170 171 {
171 172 ASSERT(rds->rds_refcnt == 0);
172 173 ASSERT(MUTEX_HELD(&rds->rds_lock));
173 174 crfree(rds->rds_cred);
174 175 kmem_cache_free(rds_alloc_cache, rds);
175 176 }
176 177
177 178 rds_t *
178 179 rds_create(void *rds_ulpd, cred_t *credp)
179 180 {
180 181 rds_t *rds;
181 182
182 183 /* User must supply a credential. */
183 184 if (credp == NULL)
184 185 return (NULL);
185 186 rds = kmem_cache_alloc(rds_alloc_cache, KM_SLEEP);
186 187 if (rds == NULL) {
187 188 return (NULL);
188 189 }
189 190
190 191 bzero(rds, sizeof (rds_t));
191 192 mutex_init(&rds->rds_lock, NULL, MUTEX_DEFAULT, NULL);
192 193 cv_init(&rds->rds_refcv, NULL, CV_DEFAULT, NULL);
193 194 rds->rds_cred = credp;
194 195 rds->rds_ulpd = rds_ulpd;
195 196 rds->rds_zoneid = getzoneid();
196 197 crhold(credp);
197 198 rds->rds_refcnt++;
198 199 return (rds);
199 200 }
200 201
201 202
202 203 /*
203 204 * Hash list removal routine for rds_t structures.
204 205 */
205 206 void
206 207 rds_bind_hash_remove(rds_t *rds, boolean_t caller_holds_lock)
207 208 {
208 209 rds_t *rdsnext;
209 210 kmutex_t *lockp;
210 211
211 212 if (rds->rds_ptpbhn == NULL)
212 213 return;
213 214
214 215 /*
215 216 * Extract the lock pointer in case there are concurrent
216 217 * hash_remove's for this instance.
217 218 */
218 219 ASSERT(rds->rds_port != 0);
219 220 if (!caller_holds_lock) {
220 221 lockp = &rds_bind_fanout[RDS_BIND_HASH(rds->rds_port)].
221 222 rds_bf_lock;
222 223 ASSERT(lockp != NULL);
223 224 mutex_enter(lockp);
224 225 }
225 226
226 227 if (rds->rds_ptpbhn != NULL) {
227 228 rdsnext = rds->rds_bind_hash;
228 229 if (rdsnext != NULL) {
229 230 rdsnext->rds_ptpbhn = rds->rds_ptpbhn;
230 231 rds->rds_bind_hash = NULL;
231 232 }
232 233 *rds->rds_ptpbhn = rdsnext;
233 234 rds->rds_ptpbhn = NULL;
234 235 }
235 236
236 237 RDS_DEC_REF_CNT(rds);
237 238
238 239 if (!caller_holds_lock) {
239 240 mutex_exit(lockp);
240 241 }
241 242 }
242 243
243 244 void
244 245 rds_bind_hash_insert(rds_bf_t *rdsbf, rds_t *rds)
245 246 {
246 247 rds_t **rdsp;
247 248 rds_t *rdsnext;
248 249
249 250 ASSERT(MUTEX_HELD(&rdsbf->rds_bf_lock));
250 251 if (rds->rds_ptpbhn != NULL) {
251 252 rds_bind_hash_remove(rds, B_TRUE);
252 253 }
253 254
254 255 rdsp = &rdsbf->rds_bf_rds;
255 256 rdsnext = rdsp[0];
256 257
257 258 if (rdsnext != NULL) {
258 259 rdsnext->rds_ptpbhn = &rds->rds_bind_hash;
259 260 }
260 261 rds->rds_bind_hash = rdsnext;
261 262 rds->rds_ptpbhn = rdsp;
262 263 rdsp[0] = rds;
263 264 RDS_INCR_REF_CNT(rds);
264 265
265 266 }
266 267
267 268 /*
268 269 * Everything is in network byte order
269 270 */
270 271 /* ARGSUSED */
271 272 rds_t *
272 273 rds_fanout(ipaddr_t local_addr, ipaddr_t rem_addr,
273 274 in_port_t local_port, in_port_t rem_port, zoneid_t zoneid)
274 275 {
275 276 rds_t *rds;
276 277 rds_bf_t *rdsbf;
277 278
278 279 rdsbf = &rds_bind_fanout[RDS_BIND_HASH(local_port)];
279 280 mutex_enter(&rdsbf->rds_bf_lock);
280 281 rds = rdsbf->rds_bf_rds;
281 282 while (rds != NULL) {
282 283 if (!(rds->rds_flags & RDS_CLOSING)) {
283 284 if ((RDS_MATCH(rds, local_port, local_addr)) &&
284 285 ((local_addr != INADDR_LOOPBACK) ||
285 286 (rds->rds_zoneid == zoneid))) {
286 287 RDS_INCR_REF_CNT(rds);
287 288 break;
288 289 }
289 290 }
290 291 rds = rds->rds_bind_hash;
291 292 }
292 293 mutex_exit(&rdsbf->rds_bf_lock);
293 294 return (rds);
294 295 }
295 296
296 297 boolean_t
297 298 rds_islocal(ipaddr_t addr)
298 299 {
299 300 ip_stack_t *ipst;
300 301
301 302 ipst = netstack_find_by_zoneid(GLOBAL_ZONEID)->netstack_ip;
302 303 ASSERT(ipst != NULL);
303 304 if (ip_laddr_verify_v4(addr, ALL_ZONES, ipst, B_FALSE) == IPVL_BAD) {
304 305 netstack_rele(ipst->ips_netstack);
305 306 return (B_FALSE);
306 307 }
307 308 netstack_rele(ipst->ips_netstack);
308 309 return (B_TRUE);
309 310 }
↓ open down ↓ |
147 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX