10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7387SRobert.Gordon@Sun.COM * Common Development and Distribution License (the "License"). 6*7387SRobert.Gordon@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*7387SRobert.Gordon@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 26*7387SRobert.Gordon@Sun.COM /* 27*7387SRobert.Gordon@Sun.COM * Copyright (c) 2007, The Ohio State University. All rights reserved. 28*7387SRobert.Gordon@Sun.COM * 29*7387SRobert.Gordon@Sun.COM * Portions of this source code is developed by the team members of 30*7387SRobert.Gordon@Sun.COM * The Ohio State University's Network-Based Computing Laboratory (NBCL), 31*7387SRobert.Gordon@Sun.COM * headed by Professor Dhabaleswar K. (DK) Panda. 32*7387SRobert.Gordon@Sun.COM * 33*7387SRobert.Gordon@Sun.COM * Acknowledgements to contributions from developors: 34*7387SRobert.Gordon@Sun.COM * Ranjit Noronha: noronha@cse.ohio-state.edu 35*7387SRobert.Gordon@Sun.COM * Lei Chai : chail@cse.ohio-state.edu 36*7387SRobert.Gordon@Sun.COM * Weikuan Yu : yuw@cse.ohio-state.edu 37*7387SRobert.Gordon@Sun.COM * 38*7387SRobert.Gordon@Sun.COM */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate #include <sys/systm.h> 410Sstevel@tonic-gate #include <sys/kstat.h> 420Sstevel@tonic-gate #include <sys/modctl.h> 43*7387SRobert.Gordon@Sun.COM #include <sys/sdt.h> 440Sstevel@tonic-gate #include <rpc/rpc_rdma.h> 450Sstevel@tonic-gate 460Sstevel@tonic-gate #include <sys/ib/ibtl/ibti.h> 470Sstevel@tonic-gate 480Sstevel@tonic-gate uint_t rdma_minchunk = RDMA_MINCHUNK; 490Sstevel@tonic-gate 500Sstevel@tonic-gate /* 510Sstevel@tonic-gate * Globals 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate int rdma_modloaded = 0; /* flag to load RDMA plugin modules */ 540Sstevel@tonic-gate int rdma_dev_available = 0; /* if any RDMA device is loaded */ 550Sstevel@tonic-gate kmutex_t rdma_modload_lock; /* protects rdma_modloaded flag */ 560Sstevel@tonic-gate rdma_registry_t *rdma_mod_head = NULL; /* head for RDMA modules */ 570Sstevel@tonic-gate krwlock_t rdma_lock; /* protects rdma_mod_head list */ 580Sstevel@tonic-gate ldi_ident_t rpcmod_li = NULL; /* identifies us with ldi_ framework */ 590Sstevel@tonic-gate 60*7387SRobert.Gordon@Sun.COM kmem_cache_t *clist_cache = NULL; 61*7387SRobert.Gordon@Sun.COM 620Sstevel@tonic-gate /* 630Sstevel@tonic-gate * Statics 640Sstevel@tonic-gate */ 650Sstevel@tonic-gate static ldi_handle_t rpcib_handle = NULL; 660Sstevel@tonic-gate 670Sstevel@tonic-gate /* 680Sstevel@tonic-gate * Externs 690Sstevel@tonic-gate */ 700Sstevel@tonic-gate extern kstat_named_t *rdmarcstat_ptr; 710Sstevel@tonic-gate extern uint_t rdmarcstat_ndata; 720Sstevel@tonic-gate extern kstat_named_t *rdmarsstat_ptr; 730Sstevel@tonic-gate extern uint_t rdmarsstat_ndata; 740Sstevel@tonic-gate 750Sstevel@tonic-gate void rdma_kstat_init(); 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* 780Sstevel@tonic-gate * RDMATF module registration routine. 790Sstevel@tonic-gate * This routine is expected to be called by the init routine in 800Sstevel@tonic-gate * the plugin modules. 810Sstevel@tonic-gate */ 820Sstevel@tonic-gate rdma_stat 830Sstevel@tonic-gate rdma_register_mod(rdma_mod_t *mod) 840Sstevel@tonic-gate { 850Sstevel@tonic-gate rdma_registry_t **mp, *m; 860Sstevel@tonic-gate 870Sstevel@tonic-gate if (mod->rdma_version != RDMATF_VERS) { 880Sstevel@tonic-gate return (RDMA_BADVERS); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate rw_enter(&rdma_lock, RW_WRITER); 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * Ensure not already registered 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate mp = &rdma_mod_head; 960Sstevel@tonic-gate while (*mp != NULL) { 970Sstevel@tonic-gate if (strncmp((*mp)->r_mod->rdma_api, mod->rdma_api, 980Sstevel@tonic-gate KNC_STRSIZE) == 0) { 990Sstevel@tonic-gate rw_exit(&rdma_lock); 1000Sstevel@tonic-gate return (RDMA_REG_EXIST); 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate mp = &((*mp)->r_next); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* 1060Sstevel@tonic-gate * New one, create and add to registry 1070Sstevel@tonic-gate */ 1080Sstevel@tonic-gate m = kmem_alloc(sizeof (rdma_registry_t), KM_SLEEP); 1090Sstevel@tonic-gate m->r_mod = kmem_alloc(sizeof (rdma_mod_t), KM_SLEEP); 1100Sstevel@tonic-gate *m->r_mod = *mod; 1110Sstevel@tonic-gate m->r_next = NULL; 1120Sstevel@tonic-gate m->r_mod->rdma_api = kmem_zalloc(KNC_STRSIZE, KM_SLEEP); 1130Sstevel@tonic-gate (void) strncpy(m->r_mod->rdma_api, mod->rdma_api, KNC_STRSIZE); 1140Sstevel@tonic-gate m->r_mod->rdma_api[KNC_STRSIZE - 1] = '\0'; 1150Sstevel@tonic-gate *mp = m; 1160Sstevel@tonic-gate rw_exit(&rdma_lock); 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate return (RDMA_SUCCESS); 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate /* 1220Sstevel@tonic-gate * RDMATF module unregistration routine. 1230Sstevel@tonic-gate * This routine is expected to be called by the fini routine in 1240Sstevel@tonic-gate * the plugin modules. 1250Sstevel@tonic-gate */ 1260Sstevel@tonic-gate rdma_stat 1270Sstevel@tonic-gate rdma_unregister_mod(rdma_mod_t *mod) 1280Sstevel@tonic-gate { 1290Sstevel@tonic-gate rdma_registry_t **m, *mmod = NULL; 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate rw_enter(&rdma_lock, RW_WRITER); 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate m = &rdma_mod_head; 1340Sstevel@tonic-gate while (*m != NULL) { 1350Sstevel@tonic-gate if (strncmp((*m)->r_mod->rdma_api, mod->rdma_api, 1360Sstevel@tonic-gate KNC_STRSIZE) != 0) { 1370Sstevel@tonic-gate m = &((*m)->r_next); 1380Sstevel@tonic-gate continue; 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate /* 1410Sstevel@tonic-gate * Check if any device attached, if so return error 1420Sstevel@tonic-gate */ 1430Sstevel@tonic-gate if ((*m)->r_mod->rdma_count != 0) { 1440Sstevel@tonic-gate rw_exit(&rdma_lock); 1450Sstevel@tonic-gate return (RDMA_FAILED); 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate /* 1480Sstevel@tonic-gate * Found entry. Now remove it. 1490Sstevel@tonic-gate */ 1500Sstevel@tonic-gate mmod = *m; 1510Sstevel@tonic-gate *m = (*m)->r_next; 1520Sstevel@tonic-gate kmem_free(mmod->r_mod->rdma_api, KNC_STRSIZE); 1530Sstevel@tonic-gate kmem_free(mmod->r_mod, sizeof (rdma_mod_t)); 1540Sstevel@tonic-gate kmem_free(mmod, sizeof (rdma_registry_t)); 1550Sstevel@tonic-gate rw_exit(&rdma_lock); 1560Sstevel@tonic-gate return (RDMA_SUCCESS); 1570Sstevel@tonic-gate } 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate /* 1600Sstevel@tonic-gate * Not found. 1610Sstevel@tonic-gate */ 1620Sstevel@tonic-gate rw_exit(&rdma_lock); 1630Sstevel@tonic-gate return (RDMA_FAILED); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate 166*7387SRobert.Gordon@Sun.COM struct clist * 167*7387SRobert.Gordon@Sun.COM clist_alloc(void) 168*7387SRobert.Gordon@Sun.COM { 169*7387SRobert.Gordon@Sun.COM struct clist *clp; 170*7387SRobert.Gordon@Sun.COM 171*7387SRobert.Gordon@Sun.COM clp = kmem_cache_alloc(clist_cache, KM_SLEEP); 172*7387SRobert.Gordon@Sun.COM 173*7387SRobert.Gordon@Sun.COM bzero(clp, sizeof (*clp)); 174*7387SRobert.Gordon@Sun.COM 175*7387SRobert.Gordon@Sun.COM return (clp); 176*7387SRobert.Gordon@Sun.COM } 177*7387SRobert.Gordon@Sun.COM 1780Sstevel@tonic-gate /* 1790Sstevel@tonic-gate * Creates a new chunk list entry, and 1800Sstevel@tonic-gate * adds it to the end of a chunk list. 1810Sstevel@tonic-gate */ 1820Sstevel@tonic-gate void 1830Sstevel@tonic-gate clist_add(struct clist **clp, uint32_t xdroff, int len, 1840Sstevel@tonic-gate struct mrc *shandle, caddr_t saddr, 1850Sstevel@tonic-gate struct mrc *dhandle, caddr_t daddr) 1860Sstevel@tonic-gate { 1870Sstevel@tonic-gate struct clist *cl; 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate /* Find the end of the list */ 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate while (*clp != NULL) 1920Sstevel@tonic-gate clp = &((*clp)->c_next); 1930Sstevel@tonic-gate 194*7387SRobert.Gordon@Sun.COM cl = clist_alloc(); 1950Sstevel@tonic-gate cl->c_xdroff = xdroff; 1960Sstevel@tonic-gate cl->c_len = len; 197*7387SRobert.Gordon@Sun.COM cl->w.c_saddr = (uint64_t)(uintptr_t)saddr; 1980Sstevel@tonic-gate if (shandle) 1990Sstevel@tonic-gate cl->c_smemhandle = *shandle; 200*7387SRobert.Gordon@Sun.COM cl->u.c_daddr = (uint64_t)(uintptr_t)daddr; 2010Sstevel@tonic-gate if (dhandle) 2020Sstevel@tonic-gate cl->c_dmemhandle = *dhandle; 2030Sstevel@tonic-gate cl->c_next = NULL; 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate *clp = cl; 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate 208*7387SRobert.Gordon@Sun.COM rdma_stat 209*7387SRobert.Gordon@Sun.COM clist_register(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 2100Sstevel@tonic-gate { 2110Sstevel@tonic-gate struct clist *c; 2120Sstevel@tonic-gate int status; 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate for (c = cl; c; c = c->c_next) { 215*7387SRobert.Gordon@Sun.COM if (c->c_len <= 0) 216*7387SRobert.Gordon@Sun.COM continue; 217*7387SRobert.Gordon@Sun.COM switch (dstsrc) { 218*7387SRobert.Gordon@Sun.COM case CLIST_REG_SOURCE: 2190Sstevel@tonic-gate status = RDMA_REGMEMSYNC(conn, 220*7387SRobert.Gordon@Sun.COM (caddr_t)(struct as *)cl->c_adspc, 221*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->w.c_saddr3, c->c_len, 222*7387SRobert.Gordon@Sun.COM &c->c_smemhandle, (void **)&c->c_ssynchandle, 223*7387SRobert.Gordon@Sun.COM (void *)c->rb_longbuf.rb_private); 224*7387SRobert.Gordon@Sun.COM break; 225*7387SRobert.Gordon@Sun.COM case CLIST_REG_DST: 2260Sstevel@tonic-gate status = RDMA_REGMEMSYNC(conn, 227*7387SRobert.Gordon@Sun.COM (caddr_t)(struct as *)cl->c_adspc, 228*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->u.c_daddr3, c->c_len, 229*7387SRobert.Gordon@Sun.COM &c->c_dmemhandle, (void **)&c->c_dsynchandle, 230*7387SRobert.Gordon@Sun.COM (void *)c->rb_longbuf.rb_private); 231*7387SRobert.Gordon@Sun.COM break; 232*7387SRobert.Gordon@Sun.COM default: 233*7387SRobert.Gordon@Sun.COM return (RDMA_INVAL); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate if (status != RDMA_SUCCESS) { 236*7387SRobert.Gordon@Sun.COM (void) clist_deregister(conn, cl, dstsrc); 2370Sstevel@tonic-gate return (status); 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate return (RDMA_SUCCESS); 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate 244*7387SRobert.Gordon@Sun.COM rdma_stat 245*7387SRobert.Gordon@Sun.COM clist_deregister(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 2460Sstevel@tonic-gate { 2470Sstevel@tonic-gate struct clist *c; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate for (c = cl; c; c = c->c_next) { 250*7387SRobert.Gordon@Sun.COM switch (dstsrc) { 251*7387SRobert.Gordon@Sun.COM case CLIST_REG_SOURCE: 2520Sstevel@tonic-gate if (c->c_smemhandle.mrc_rmr != 0) { 2530Sstevel@tonic-gate (void) RDMA_DEREGMEMSYNC(conn, 254*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->w.c_saddr3, 2550Sstevel@tonic-gate c->c_smemhandle, 256*7387SRobert.Gordon@Sun.COM (void *)(uintptr_t)c->c_ssynchandle, 257*7387SRobert.Gordon@Sun.COM (void *)c->rb_longbuf.rb_private); 2580Sstevel@tonic-gate c->c_smemhandle.mrc_rmr = 0; 2590Sstevel@tonic-gate c->c_ssynchandle = NULL; 2600Sstevel@tonic-gate } 261*7387SRobert.Gordon@Sun.COM break; 262*7387SRobert.Gordon@Sun.COM case CLIST_REG_DST: 2630Sstevel@tonic-gate if (c->c_dmemhandle.mrc_rmr != 0) { 2640Sstevel@tonic-gate (void) RDMA_DEREGMEMSYNC(conn, 265*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->u.c_daddr3, 2660Sstevel@tonic-gate c->c_dmemhandle, 267*7387SRobert.Gordon@Sun.COM (void *)(uintptr_t)c->c_dsynchandle, 268*7387SRobert.Gordon@Sun.COM (void *)c->rb_longbuf.rb_private); 2690Sstevel@tonic-gate c->c_dmemhandle.mrc_rmr = 0; 2700Sstevel@tonic-gate c->c_dsynchandle = NULL; 2710Sstevel@tonic-gate } 272*7387SRobert.Gordon@Sun.COM break; 273*7387SRobert.Gordon@Sun.COM default: 274*7387SRobert.Gordon@Sun.COM return (RDMA_INVAL); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate return (RDMA_SUCCESS); 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate 281*7387SRobert.Gordon@Sun.COM rdma_stat 282*7387SRobert.Gordon@Sun.COM clist_syncmem(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 283*7387SRobert.Gordon@Sun.COM { 284*7387SRobert.Gordon@Sun.COM struct clist *c; 285*7387SRobert.Gordon@Sun.COM rdma_stat status; 286*7387SRobert.Gordon@Sun.COM 287*7387SRobert.Gordon@Sun.COM c = cl; 288*7387SRobert.Gordon@Sun.COM switch (dstsrc) { 289*7387SRobert.Gordon@Sun.COM case CLIST_REG_SOURCE: 290*7387SRobert.Gordon@Sun.COM while (c != NULL) { 291*7387SRobert.Gordon@Sun.COM if (c->c_ssynchandle) { 292*7387SRobert.Gordon@Sun.COM status = RDMA_SYNCMEM(conn, 293*7387SRobert.Gordon@Sun.COM (void *)(uintptr_t)c->c_ssynchandle, 294*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->w.c_saddr3, 295*7387SRobert.Gordon@Sun.COM c->c_len, 0); 296*7387SRobert.Gordon@Sun.COM if (status != RDMA_SUCCESS) 297*7387SRobert.Gordon@Sun.COM return (status); 298*7387SRobert.Gordon@Sun.COM } 299*7387SRobert.Gordon@Sun.COM c = c->c_next; 300*7387SRobert.Gordon@Sun.COM } 301*7387SRobert.Gordon@Sun.COM break; 302*7387SRobert.Gordon@Sun.COM case CLIST_REG_DST: 303*7387SRobert.Gordon@Sun.COM while (c != NULL) { 304*7387SRobert.Gordon@Sun.COM if (c->c_ssynchandle) { 305*7387SRobert.Gordon@Sun.COM status = RDMA_SYNCMEM(conn, 306*7387SRobert.Gordon@Sun.COM (void *)(uintptr_t)c->c_dsynchandle, 307*7387SRobert.Gordon@Sun.COM (caddr_t)(uintptr_t)c->u.c_daddr3, 308*7387SRobert.Gordon@Sun.COM c->c_len, 1); 309*7387SRobert.Gordon@Sun.COM if (status != RDMA_SUCCESS) 310*7387SRobert.Gordon@Sun.COM return (status); 311*7387SRobert.Gordon@Sun.COM } 312*7387SRobert.Gordon@Sun.COM c = c->c_next; 313*7387SRobert.Gordon@Sun.COM } 314*7387SRobert.Gordon@Sun.COM break; 315*7387SRobert.Gordon@Sun.COM default: 316*7387SRobert.Gordon@Sun.COM return (RDMA_INVAL); 317*7387SRobert.Gordon@Sun.COM } 318*7387SRobert.Gordon@Sun.COM 319*7387SRobert.Gordon@Sun.COM return (RDMA_SUCCESS); 320*7387SRobert.Gordon@Sun.COM } 321*7387SRobert.Gordon@Sun.COM 3220Sstevel@tonic-gate /* 3230Sstevel@tonic-gate * Frees up entries in chunk list 3240Sstevel@tonic-gate */ 3250Sstevel@tonic-gate void 3260Sstevel@tonic-gate clist_free(struct clist *cl) 3270Sstevel@tonic-gate { 3280Sstevel@tonic-gate struct clist *c = cl; 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate while (c != NULL) { 3310Sstevel@tonic-gate cl = cl->c_next; 332*7387SRobert.Gordon@Sun.COM kmem_cache_free(clist_cache, c); 3330Sstevel@tonic-gate c = cl; 3340Sstevel@tonic-gate } 3350Sstevel@tonic-gate } 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate rdma_stat 3380Sstevel@tonic-gate rdma_clnt_postrecv(CONN *conn, uint32_t xid) 3390Sstevel@tonic-gate { 3400Sstevel@tonic-gate struct clist *cl = NULL; 3410Sstevel@tonic-gate rdma_stat retval; 342*7387SRobert.Gordon@Sun.COM rdma_buf_t rbuf = {0}; 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate rbuf.type = RECV_BUFFER; 3450Sstevel@tonic-gate if (RDMA_BUF_ALLOC(conn, &rbuf)) { 346*7387SRobert.Gordon@Sun.COM return (RDMA_NORESOURCE); 3470Sstevel@tonic-gate } 348*7387SRobert.Gordon@Sun.COM 349*7387SRobert.Gordon@Sun.COM clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr, 350*7387SRobert.Gordon@Sun.COM NULL, NULL); 351*7387SRobert.Gordon@Sun.COM retval = RDMA_CLNT_RECVBUF(conn, cl, xid); 352*7387SRobert.Gordon@Sun.COM clist_free(cl); 353*7387SRobert.Gordon@Sun.COM 3540Sstevel@tonic-gate return (retval); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate rdma_stat 358*7387SRobert.Gordon@Sun.COM rdma_clnt_postrecv_remove(CONN *conn, uint32_t xid) 359*7387SRobert.Gordon@Sun.COM { 360*7387SRobert.Gordon@Sun.COM return (RDMA_CLNT_RECVBUF_REMOVE(conn, xid)); 361*7387SRobert.Gordon@Sun.COM } 362*7387SRobert.Gordon@Sun.COM 363*7387SRobert.Gordon@Sun.COM rdma_stat 3640Sstevel@tonic-gate rdma_svc_postrecv(CONN *conn) 3650Sstevel@tonic-gate { 3660Sstevel@tonic-gate struct clist *cl = NULL; 3670Sstevel@tonic-gate rdma_stat retval; 368*7387SRobert.Gordon@Sun.COM rdma_buf_t rbuf = {0}; 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate rbuf.type = RECV_BUFFER; 3710Sstevel@tonic-gate if (RDMA_BUF_ALLOC(conn, &rbuf)) { 3720Sstevel@tonic-gate retval = RDMA_NORESOURCE; 3730Sstevel@tonic-gate } else { 3740Sstevel@tonic-gate clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr, 375*7387SRobert.Gordon@Sun.COM NULL, NULL); 3760Sstevel@tonic-gate retval = RDMA_SVC_RECVBUF(conn, cl); 3770Sstevel@tonic-gate clist_free(cl); 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate return (retval); 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate rdma_stat 383*7387SRobert.Gordon@Sun.COM rdma_buf_alloc(CONN *conn, rdma_buf_t *rbuf) 3840Sstevel@tonic-gate { 385*7387SRobert.Gordon@Sun.COM return (RDMA_BUF_ALLOC(conn, rbuf)); 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate void 3890Sstevel@tonic-gate rdma_buf_free(CONN *conn, rdma_buf_t *rbuf) 3900Sstevel@tonic-gate { 3910Sstevel@tonic-gate if (!rbuf || rbuf->addr == NULL) { 3920Sstevel@tonic-gate return; 3930Sstevel@tonic-gate } 394*7387SRobert.Gordon@Sun.COM RDMA_BUF_FREE(conn, rbuf); 395*7387SRobert.Gordon@Sun.COM bzero(rbuf, sizeof (rdma_buf_t)); 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate /* 3990Sstevel@tonic-gate * Caller is holding rdma_modload_lock mutex 4000Sstevel@tonic-gate */ 4010Sstevel@tonic-gate int 4020Sstevel@tonic-gate rdma_modload() 4030Sstevel@tonic-gate { 4040Sstevel@tonic-gate int status; 4050Sstevel@tonic-gate ASSERT(MUTEX_HELD(&rdma_modload_lock)); 4060Sstevel@tonic-gate /* 4070Sstevel@tonic-gate * Load all available RDMA plugins which right now is only IB plugin. 4080Sstevel@tonic-gate * If no IB hardware is present, then quit right away. 4090Sstevel@tonic-gate * ENODEV -- For no device on the system 4100Sstevel@tonic-gate * EPROTONOSUPPORT -- For module not avilable either due to failure to 4110Sstevel@tonic-gate * load or some other reason. 4120Sstevel@tonic-gate */ 4130Sstevel@tonic-gate rdma_modloaded = 1; 4140Sstevel@tonic-gate if (ibt_hw_is_present() == 0) { 4150Sstevel@tonic-gate rdma_dev_available = 0; 4160Sstevel@tonic-gate return (ENODEV); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate rdma_dev_available = 1; 4200Sstevel@tonic-gate if (rpcmod_li == NULL) 4210Sstevel@tonic-gate return (EPROTONOSUPPORT); 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate status = ldi_open_by_name("/devices/ib/rpcib@0:rpcib", 4240Sstevel@tonic-gate FREAD | FWRITE, kcred, 4250Sstevel@tonic-gate &rpcib_handle, rpcmod_li); 4260Sstevel@tonic-gate if (status != 0) 4270Sstevel@tonic-gate return (EPROTONOSUPPORT); 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate /* success */ 4300Sstevel@tonic-gate rdma_kstat_init(); 431*7387SRobert.Gordon@Sun.COM 432*7387SRobert.Gordon@Sun.COM clist_cache = kmem_cache_create("rdma_clist", 433*7387SRobert.Gordon@Sun.COM sizeof (struct clist), _POINTER_ALIGNMENT, NULL, 434*7387SRobert.Gordon@Sun.COM NULL, NULL, NULL, 0, 0); 435*7387SRobert.Gordon@Sun.COM 4360Sstevel@tonic-gate return (0); 4370Sstevel@tonic-gate } 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate void 4400Sstevel@tonic-gate rdma_kstat_init(void) 4410Sstevel@tonic-gate { 4420Sstevel@tonic-gate kstat_t *ksp; 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate /* 4450Sstevel@tonic-gate * The RDMA framework doesn't know how to deal with Zones, and is 4460Sstevel@tonic-gate * only available in the global zone. 4470Sstevel@tonic-gate */ 4480Sstevel@tonic-gate ASSERT(INGLOBALZONE(curproc)); 4490Sstevel@tonic-gate ksp = kstat_create_zone("unix", 0, "rpc_rdma_client", "rpc", 4500Sstevel@tonic-gate KSTAT_TYPE_NAMED, rdmarcstat_ndata, 4510Sstevel@tonic-gate KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, GLOBAL_ZONEID); 4520Sstevel@tonic-gate if (ksp) { 4530Sstevel@tonic-gate ksp->ks_data = (void *) rdmarcstat_ptr; 4540Sstevel@tonic-gate kstat_install(ksp); 4550Sstevel@tonic-gate } 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate ksp = kstat_create_zone("unix", 0, "rpc_rdma_server", "rpc", 4580Sstevel@tonic-gate KSTAT_TYPE_NAMED, rdmarsstat_ndata, 4590Sstevel@tonic-gate KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, GLOBAL_ZONEID); 4600Sstevel@tonic-gate if (ksp) { 4610Sstevel@tonic-gate ksp->ks_data = (void *) rdmarsstat_ptr; 4620Sstevel@tonic-gate kstat_install(ksp); 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate } 465