7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "@(#)rdma_subr.c 1.11 05/06/08 SMI"
28
29 #include <sys/systm.h>
30 #include <sys/kstat.h>
31 #include <sys/modctl.h>
32 #include <rpc/rpc_rdma.h>
33
34 #include <sys/ib/ibtl/ibti.h>
35
36 /*
37 * RDMA chunk size
38 */
39 #define RDMA_MINCHUNK 1024
40 uint_t rdma_minchunk = RDMA_MINCHUNK;
41
42 /*
43 * Globals
44 */
45 int rdma_modloaded = 0; /* flag to load RDMA plugin modules */
46 int rdma_dev_available = 0; /* if any RDMA device is loaded */
47 kmutex_t rdma_modload_lock; /* protects rdma_modloaded flag */
48 rdma_registry_t *rdma_mod_head = NULL; /* head for RDMA modules */
49 krwlock_t rdma_lock; /* protects rdma_mod_head list */
50 ldi_ident_t rpcmod_li = NULL; /* identifies us with ldi_ framework */
51
52 /*
53 * Statics
54 */
55 static ldi_handle_t rpcib_handle = NULL;
56
57 /*
58 * Externs
59 */
173 cl->c_xdroff = xdroff;
174 cl->c_len = len;
175 cl->c_saddr = (uint64_t)(uintptr_t)saddr;
176 if (shandle)
177 cl->c_smemhandle = *shandle;
178 cl->c_daddr = (uint64_t)(uintptr_t)daddr;
179 if (dhandle)
180 cl->c_dmemhandle = *dhandle;
181 cl->c_next = NULL;
182
183 *clp = cl;
184 }
185
186 int
187 clist_register(CONN *conn, struct clist *cl, bool_t src)
188 {
189 struct clist *c;
190 int status;
191
192 for (c = cl; c; c = c->c_next) {
193 if (src) {
194 status = RDMA_REGMEMSYNC(conn,
195 (caddr_t)(uintptr_t)c->c_saddr, c->c_len,
196 &c->c_smemhandle, (void **)&c->c_ssynchandle);
197 } else {
198 status = RDMA_REGMEMSYNC(conn,
199 (caddr_t)(uintptr_t)c->c_daddr, c->c_len,
200 &c->c_dmemhandle, (void **)&c->c_dsynchandle);
201 }
202 if (status != RDMA_SUCCESS) {
203 (void) clist_deregister(conn, cl, src);
204 return (status);
205 }
206 }
207
208 return (RDMA_SUCCESS);
209 }
210
211 int
212 clist_deregister(CONN *conn, struct clist *cl, bool_t src)
213 {
214 struct clist *c;
215
216 for (c = cl; c; c = c->c_next) {
217 if (src) {
218 if (c->c_smemhandle.mrc_rmr != 0) {
219 (void) RDMA_DEREGMEMSYNC(conn,
220 (caddr_t)(uintptr_t)c->c_saddr,
221 c->c_smemhandle,
222 (void *)(uintptr_t)c->c_ssynchandle);
223 c->c_smemhandle.mrc_rmr = 0;
224 c->c_ssynchandle = NULL;
225 }
226 } else {
227 if (c->c_dmemhandle.mrc_rmr != 0) {
228 (void) RDMA_DEREGMEMSYNC(conn,
229 (caddr_t)(uintptr_t)c->c_daddr,
230 c->c_dmemhandle,
231 (void *)(uintptr_t)c->c_dsynchandle);
232 c->c_dmemhandle.mrc_rmr = 0;
233 c->c_dsynchandle = NULL;
234 }
235 }
236 }
237
238 return (RDMA_SUCCESS);
239 }
240
241 /*
242 * Frees up entries in chunk list
243 */
244 void
245 clist_free(struct clist *cl)
246 {
247 struct clist *c = cl;
248
249 while (c != NULL) {
250 cl = cl->c_next;
251 kmem_free(c, sizeof (struct clist));
252 c = cl;
253 }
254 }
255
256 rdma_stat
257 rdma_clnt_postrecv(CONN *conn, uint32_t xid)
258 {
259 struct clist *cl = NULL;
260 rdma_stat retval;
261 rdma_buf_t rbuf;
262
263 rbuf.type = RECV_BUFFER;
264 if (RDMA_BUF_ALLOC(conn, &rbuf)) {
265 retval = RDMA_NORESOURCE;
266 } else {
267 clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr,
268 NULL, NULL);
269 retval = RDMA_CLNT_RECVBUF(conn, cl, xid);
270 clist_free(cl);
271 }
272 return (retval);
273 }
274
275 rdma_stat
276 rdma_svc_postrecv(CONN *conn)
277 {
278 struct clist *cl = NULL;
279 rdma_stat retval;
280 rdma_buf_t rbuf;
281
282 rbuf.type = RECV_BUFFER;
283 if (RDMA_BUF_ALLOC(conn, &rbuf)) {
284 retval = RDMA_NORESOURCE;
285 } else {
286 clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr,
287 NULL, NULL);
288 retval = RDMA_SVC_RECVBUF(conn, cl);
289 clist_free(cl);
290 }
291 return (retval);
292 }
293
294 rdma_stat
295 clist_syncmem(CONN *conn, struct clist *cl, bool_t src)
296 {
297 struct clist *c;
298 rdma_stat status;
299
300 c = cl;
301 if (src) {
302 while (c != NULL) {
303 status = RDMA_SYNCMEM(conn,
304 (void *)(uintptr_t)c->c_ssynchandle,
305 (caddr_t)(uintptr_t)c->c_saddr, c->c_len, 0);
306 if (status != RDMA_SUCCESS)
307 return (status);
308 c = c->c_next;
309 }
310 } else {
311 while (c != NULL) {
312 status = RDMA_SYNCMEM(conn,
313 (void *)(uintptr_t)c->c_dsynchandle,
314 (caddr_t)(uintptr_t)c->c_daddr, c->c_len, 1);
315 if (status != RDMA_SUCCESS)
316 return (status);
317 c = c->c_next;
318 }
319 }
320 return (RDMA_SUCCESS);
321 }
322
323 void
324 rdma_buf_free(CONN *conn, rdma_buf_t *rbuf)
325 {
326 if (!rbuf || rbuf->addr == NULL) {
327 return;
328 }
329 if (rbuf->type != CHUNK_BUFFER) {
330 /* pool buffer */
331 RDMA_BUF_FREE(conn, rbuf);
332 } else {
333 kmem_free(rbuf->addr, rbuf->len);
334 }
335 rbuf->addr = NULL;
336 rbuf->len = 0;
337 }
338
339 /*
340 * Caller is holding rdma_modload_lock mutex
341 */
342 int
343 rdma_modload()
344 {
345 int status;
346 ASSERT(MUTEX_HELD(&rdma_modload_lock));
347 /*
348 * Load all available RDMA plugins which right now is only IB plugin.
349 * If no IB hardware is present, then quit right away.
350 * ENODEV -- For no device on the system
351 * EPROTONOSUPPORT -- For module not avilable either due to failure to
352 * load or some other reason.
|
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 2006, The Ohio State University. All rights reserved.
28 *
29 * Portions of this source code is developed by the team members of
30 * The Ohio State University's Network-Based Computing Laboratory (NBCL),
31 * headed by Professor Dhabaleswar K. (DK) Panda.
32 *
33 * Acknowledgements to contributions from developors:
34 * Ranjit Noronha: noronha@cse.ohio-state.edu
35 * Lei Chai : chail@cse.ohio-state.edu
36 * Weikuan Yu : yuw@cse.ohio-state.edu
37 *
38 */
39 #pragma ident "@(#)rdma_subr.c 1.11 05/06/08 SMI"
40
41 #include <sys/systm.h>
42 #include <sys/kstat.h>
43 #include <sys/modctl.h>
44 #include <rpc/rpc_rdma.h>
45
46 #include <sys/ib/ibtl/ibti.h>
47
48 uint_t rdma_minchunk = RDMA_MINCHUNK;
49
50 /*
51 * Globals
52 */
53 int rdma_modloaded = 0; /* flag to load RDMA plugin modules */
54 int rdma_dev_available = 0; /* if any RDMA device is loaded */
55 kmutex_t rdma_modload_lock; /* protects rdma_modloaded flag */
56 rdma_registry_t *rdma_mod_head = NULL; /* head for RDMA modules */
57 krwlock_t rdma_lock; /* protects rdma_mod_head list */
58 ldi_ident_t rpcmod_li = NULL; /* identifies us with ldi_ framework */
59
60 /*
61 * Statics
62 */
63 static ldi_handle_t rpcib_handle = NULL;
64
65 /*
66 * Externs
67 */
181 cl->c_xdroff = xdroff;
182 cl->c_len = len;
183 cl->c_saddr = (uint64_t)(uintptr_t)saddr;
184 if (shandle)
185 cl->c_smemhandle = *shandle;
186 cl->c_daddr = (uint64_t)(uintptr_t)daddr;
187 if (dhandle)
188 cl->c_dmemhandle = *dhandle;
189 cl->c_next = NULL;
190
191 *clp = cl;
192 }
193
194 int
195 clist_register(CONN *conn, struct clist *cl, bool_t src)
196 {
197 struct clist *c;
198 int status;
199
200 for (c = cl; c; c = c->c_next) {
201 if(c->c_len > 0)
202 if (src) {
203 status = RDMA_REGMEMSYNC(conn, (caddr_t)(struct as *)cl->c_adspc,
204 (caddr_t)(uintptr_t)c->c_saddr, c->c_len,
205 #ifdef SERVER_REG_CACHE
206 &c->c_smemhandle, (void **)&c->c_ssynchandle, (void *)c->long_reply_buf);
207 #else
208 &c->c_smemhandle, (void **)&c->c_ssynchandle);
209 #endif
210 } else {
211 status = RDMA_REGMEMSYNC(conn, (caddr_t)(struct as *)cl->c_adspc,
212 (caddr_t)(uintptr_t)c->c_daddr, c->c_len,
213 #ifdef SERVER_REG_CACHE
214 &c->c_dmemhandle, (void **)&c->c_dsynchandle,(void *)c->long_reply_buf);
215 #else
216 &c->c_dmemhandle, (void **)&c->c_dsynchandle);
217 #endif
218 }
219 if (status != RDMA_SUCCESS) {
220 (void) clist_deregister(conn, cl, src);
221 return (status);
222 }
223 }
224
225 return (RDMA_SUCCESS);
226 }
227
228 int
229 clist_deregister(CONN *conn, struct clist *cl, bool_t src)
230 {
231 struct clist *c;
232
233 for (c = cl; c; c = c->c_next) {
234 if (src) {
235 if (c->c_smemhandle.mrc_rmr != 0) {
236 (void) RDMA_DEREGMEMSYNC(conn,
237 (caddr_t)(uintptr_t)c->c_saddr,
238 c->c_smemhandle,
239 #ifdef SERVER_REG_CACHE
240 (void *)(uintptr_t)c->c_ssynchandle, (void *)c->long_reply_buf);
241 #else
242 (void *)(uintptr_t)c->c_ssynchandle);
243 #endif
244 c->c_smemhandle.mrc_rmr = 0;
245 c->c_ssynchandle = NULL;
246 }
247 } else {
248 if (c->c_dmemhandle.mrc_rmr != 0) {
249 (void) RDMA_DEREGMEMSYNC(conn,
250 (caddr_t)(uintptr_t)c->c_daddr,
251 c->c_dmemhandle,
252 #ifdef SERVER_REG_CACHE
253 (void *)(uintptr_t)c->c_dsynchandle, (void *)c->long_reply_buf);
254 #else
255 (void *)(uintptr_t)c->c_dsynchandle);
256 #endif
257 c->c_dmemhandle.mrc_rmr = 0;
258 c->c_dsynchandle = NULL;
259 }
260 }
261 }
262
263 return (RDMA_SUCCESS);
264 }
265
266 /*
267 * Frees up entries in chunk list
268 */
269 void
270 clist_free(struct clist *cl)
271 {
272 struct clist *c = cl;
273
274 while (c != NULL) {
275 cl = cl->c_next;
276 kmem_free(c, sizeof (struct clist));
277 c = cl;
278 }
279 }
280
281 rdma_stat
282 rdma_clnt_postrecv(CONN *conn, uint32_t xid)
283 {
284 struct clist *cl = NULL;
285 rdma_stat retval;
286 rdma_buf_t rbuf = {0};
287
288 rbuf.type = RECV_BUFFER;
289 if (RDMA_BUF_ALLOC(conn, &rbuf)) {
290 retval = RDMA_NORESOURCE;
291 } else {
292 clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr,
293 NULL, NULL);
294 retval = RDMA_CLNT_RECVBUF(conn, cl, xid);
295 clist_free(cl);
296 }
297 return (retval);
298 }
299
300 rdma_stat
301 rdma_svc_postrecv(CONN *conn)
302 {
303 struct clist *cl = NULL;
304 rdma_stat retval;
305 rdma_buf_t rbuf = {0};
306
307 rbuf.type = RECV_BUFFER;
308 if (RDMA_BUF_ALLOC(conn, &rbuf)) {
309 retval = RDMA_NORESOURCE;
310 } else {
311 clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr,
312 NULL, NULL);
313 retval = RDMA_SVC_RECVBUF(conn, cl);
314 clist_free(cl);
315 }
316 return (retval);
317 }
318
319 rdma_stat
320 clist_syncmem(CONN *conn, struct clist *cl, bool_t src)
321 {
322 struct clist *c;
323 rdma_stat status;
324
325 c = cl;
326 if (src) {
327 while (c != NULL) {
328 if(c->c_ssynchandle){
329 status = RDMA_SYNCMEM(conn,
330 (void *)(uintptr_t)c->c_ssynchandle,
331 (caddr_t)(uintptr_t)c->c_saddr, c->c_len, 0);
332 if (status != RDMA_SUCCESS)
333 return (status);
334 }
335 c = c->c_next;
336 }
337 } else {
338 while (c != NULL) {
339 if(c->c_ssynchandle){
340 status = RDMA_SYNCMEM(conn,
341 (void *)(uintptr_t)c->c_dsynchandle,
342 (caddr_t)(uintptr_t)c->c_daddr, c->c_len, 1);
343 if (status != RDMA_SUCCESS)
344 return (status);
345 }
346 c = c->c_next;
347 }
348 }
349 return (RDMA_SUCCESS);
350 }
351
352 void
353 rdma_buf_free(CONN *conn, rdma_buf_t *rbuf)
354 {
355 if (!rbuf || rbuf->addr == NULL) {
356 return;
357 }
358 if (rbuf->type != CHUNK_BUFFER) {
359 /* pool buffer */
360 RDMA_BUF_FREE(conn, rbuf);
361 } else {
362 #ifdef SERVER_REG_CACHE
363 if(rbuf->long_reply_buf)
364 RDMA_FREE_SERVER_CACHE_BUF(conn, (rib_lrc_entry_t *)rbuf->long_reply_buf);
365 else
366 #endif
367 kmem_free(rbuf->addr, rbuf->len);
368 }
369 rbuf->addr = NULL;
370 rbuf->len = 0;
371 }
372
373 /*
374 * Caller is holding rdma_modload_lock mutex
375 */
376 int
377 rdma_modload()
378 {
379 int status;
380 ASSERT(MUTEX_HELD(&rdma_modload_lock));
381 /*
382 * Load all available RDMA plugins which right now is only IB plugin.
383 * If no IB hardware is present, then quit right away.
384 * ENODEV -- For no device on the system
385 * EPROTONOSUPPORT -- For module not avilable either due to failure to
386 * load or some other reason.
|