17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50a701b1eSRobert Gordon * Common Development and Distribution License (the "License"). 60a701b1eSRobert Gordon * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*51f34d4bSRajkumar Sivaprakasam * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 260a701b1eSRobert Gordon /* 27*51f34d4bSRajkumar Sivaprakasam * Copyright (c) 2008, The Ohio State University. All rights reserved. 280a701b1eSRobert Gordon * 290a701b1eSRobert Gordon * Portions of this source code is developed by the team members of 300a701b1eSRobert Gordon * The Ohio State University's Network-Based Computing Laboratory (NBCL), 310a701b1eSRobert Gordon * headed by Professor Dhabaleswar K. (DK) Panda. 320a701b1eSRobert Gordon * 330a701b1eSRobert Gordon * Acknowledgements to contributions from developors: 340a701b1eSRobert Gordon * Ranjit Noronha: noronha@cse.ohio-state.edu 350a701b1eSRobert Gordon * Lei Chai : chail@cse.ohio-state.edu 360a701b1eSRobert Gordon * Weikuan Yu : yuw@cse.ohio-state.edu 370a701b1eSRobert Gordon * 380a701b1eSRobert Gordon */ 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include <sys/systm.h> 417c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 427c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 430a701b1eSRobert Gordon #include <sys/sdt.h> 447c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #include <sys/ib/ibtl/ibti.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate uint_t rdma_minchunk = RDMA_MINCHUNK; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * Globals 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate int rdma_modloaded = 0; /* flag to load RDMA plugin modules */ 547c478bd9Sstevel@tonic-gate int rdma_dev_available = 0; /* if any RDMA device is loaded */ 557c478bd9Sstevel@tonic-gate kmutex_t rdma_modload_lock; /* protects rdma_modloaded flag */ 56*51f34d4bSRajkumar Sivaprakasam 57*51f34d4bSRajkumar Sivaprakasam rdma_svc_wait_t rdma_wait; 58*51f34d4bSRajkumar Sivaprakasam 597c478bd9Sstevel@tonic-gate rdma_registry_t *rdma_mod_head = NULL; /* head for RDMA modules */ 607c478bd9Sstevel@tonic-gate krwlock_t rdma_lock; /* protects rdma_mod_head list */ 617c478bd9Sstevel@tonic-gate ldi_ident_t rpcmod_li = NULL; /* identifies us with ldi_ framework */ 627c478bd9Sstevel@tonic-gate 630a701b1eSRobert Gordon kmem_cache_t *clist_cache = NULL; 640a701b1eSRobert Gordon 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * Statics 677c478bd9Sstevel@tonic-gate */ 68*51f34d4bSRajkumar Sivaprakasam ldi_handle_t rpcib_handle = NULL; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * Externs 727c478bd9Sstevel@tonic-gate */ 737c478bd9Sstevel@tonic-gate extern kstat_named_t *rdmarcstat_ptr; 747c478bd9Sstevel@tonic-gate extern uint_t rdmarcstat_ndata; 757c478bd9Sstevel@tonic-gate extern kstat_named_t *rdmarsstat_ptr; 767c478bd9Sstevel@tonic-gate extern uint_t rdmarsstat_ndata; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate void rdma_kstat_init(); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * RDMATF module registration routine. 827c478bd9Sstevel@tonic-gate * This routine is expected to be called by the init routine in 837c478bd9Sstevel@tonic-gate * the plugin modules. 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate rdma_stat 867c478bd9Sstevel@tonic-gate rdma_register_mod(rdma_mod_t *mod) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate rdma_registry_t **mp, *m; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate if (mod->rdma_version != RDMATF_VERS) { 917c478bd9Sstevel@tonic-gate return (RDMA_BADVERS); 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate rw_enter(&rdma_lock, RW_WRITER); 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Ensure not already registered 977c478bd9Sstevel@tonic-gate */ 987c478bd9Sstevel@tonic-gate mp = &rdma_mod_head; 997c478bd9Sstevel@tonic-gate while (*mp != NULL) { 1007c478bd9Sstevel@tonic-gate if (strncmp((*mp)->r_mod->rdma_api, mod->rdma_api, 1017c478bd9Sstevel@tonic-gate KNC_STRSIZE) == 0) { 102*51f34d4bSRajkumar Sivaprakasam if ((*mp)->r_mod_state == RDMA_MOD_INACTIVE) { 103*51f34d4bSRajkumar Sivaprakasam (*mp)->r_mod_state = RDMA_MOD_ACTIVE; 104*51f34d4bSRajkumar Sivaprakasam (*mp)->r_mod->rdma_ops = mod->rdma_ops; 105*51f34d4bSRajkumar Sivaprakasam (*mp)->r_mod->rdma_count = mod->rdma_count; 106*51f34d4bSRajkumar Sivaprakasam goto announce_hca; 107*51f34d4bSRajkumar Sivaprakasam } 1087c478bd9Sstevel@tonic-gate rw_exit(&rdma_lock); 1097c478bd9Sstevel@tonic-gate return (RDMA_REG_EXIST); 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate mp = &((*mp)->r_next); 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* 1157c478bd9Sstevel@tonic-gate * New one, create and add to registry 1167c478bd9Sstevel@tonic-gate */ 1177c478bd9Sstevel@tonic-gate m = kmem_alloc(sizeof (rdma_registry_t), KM_SLEEP); 1187c478bd9Sstevel@tonic-gate m->r_mod = kmem_alloc(sizeof (rdma_mod_t), KM_SLEEP); 1197c478bd9Sstevel@tonic-gate *m->r_mod = *mod; 1207c478bd9Sstevel@tonic-gate m->r_next = NULL; 1217c478bd9Sstevel@tonic-gate m->r_mod->rdma_api = kmem_zalloc(KNC_STRSIZE, KM_SLEEP); 1227c478bd9Sstevel@tonic-gate (void) strncpy(m->r_mod->rdma_api, mod->rdma_api, KNC_STRSIZE); 1237c478bd9Sstevel@tonic-gate m->r_mod->rdma_api[KNC_STRSIZE - 1] = '\0'; 124*51f34d4bSRajkumar Sivaprakasam m->r_mod_state = RDMA_MOD_ACTIVE; 1257c478bd9Sstevel@tonic-gate *mp = m; 126*51f34d4bSRajkumar Sivaprakasam 127*51f34d4bSRajkumar Sivaprakasam announce_hca: 1287c478bd9Sstevel@tonic-gate rw_exit(&rdma_lock); 129*51f34d4bSRajkumar Sivaprakasam /* 130*51f34d4bSRajkumar Sivaprakasam * Start the nfs service on the rdma xprts. 131*51f34d4bSRajkumar Sivaprakasam * (this notification mechanism will need to change when we support 132*51f34d4bSRajkumar Sivaprakasam * multiple hcas and have support for multiple rdma plugins). 133*51f34d4bSRajkumar Sivaprakasam */ 134*51f34d4bSRajkumar Sivaprakasam mutex_enter(&rdma_wait.svc_lock); 135*51f34d4bSRajkumar Sivaprakasam rdma_wait.svc_stat = RDMA_HCA_ATTACH; 136*51f34d4bSRajkumar Sivaprakasam cv_signal(&rdma_wait.svc_cv); 137*51f34d4bSRajkumar Sivaprakasam mutex_exit(&rdma_wait.svc_lock); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate return (RDMA_SUCCESS); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate /* 1437c478bd9Sstevel@tonic-gate * RDMATF module unregistration routine. 1447c478bd9Sstevel@tonic-gate * This routine is expected to be called by the fini routine in 1457c478bd9Sstevel@tonic-gate * the plugin modules. 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate rdma_stat 1487c478bd9Sstevel@tonic-gate rdma_unregister_mod(rdma_mod_t *mod) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate rdma_registry_t **m, *mmod = NULL; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate rw_enter(&rdma_lock, RW_WRITER); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate m = &rdma_mod_head; 1557c478bd9Sstevel@tonic-gate while (*m != NULL) { 1567c478bd9Sstevel@tonic-gate if (strncmp((*m)->r_mod->rdma_api, mod->rdma_api, 1577c478bd9Sstevel@tonic-gate KNC_STRSIZE) != 0) { 1587c478bd9Sstevel@tonic-gate m = &((*m)->r_next); 1597c478bd9Sstevel@tonic-gate continue; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate /* 1627c478bd9Sstevel@tonic-gate * Check if any device attached, if so return error 1637c478bd9Sstevel@tonic-gate */ 164*51f34d4bSRajkumar Sivaprakasam if (mod->rdma_count != 0) { 1657c478bd9Sstevel@tonic-gate rw_exit(&rdma_lock); 1667c478bd9Sstevel@tonic-gate return (RDMA_FAILED); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate /* 169*51f34d4bSRajkumar Sivaprakasam * Found entry. Mark it inactive. 1707c478bd9Sstevel@tonic-gate */ 1717c478bd9Sstevel@tonic-gate mmod = *m; 172*51f34d4bSRajkumar Sivaprakasam mmod->r_mod->rdma_count = 0; 173*51f34d4bSRajkumar Sivaprakasam mmod->r_mod_state = RDMA_MOD_INACTIVE; 174*51f34d4bSRajkumar Sivaprakasam break; 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 177*51f34d4bSRajkumar Sivaprakasam rdma_modloaded = 0; 178*51f34d4bSRajkumar Sivaprakasam rdma_dev_available = 0; 179*51f34d4bSRajkumar Sivaprakasam rw_exit(&rdma_lock); 180*51f34d4bSRajkumar Sivaprakasam 181*51f34d4bSRajkumar Sivaprakasam /* 182*51f34d4bSRajkumar Sivaprakasam * Stop the nfs service running on the rdma xprts. 183*51f34d4bSRajkumar Sivaprakasam * (this notification mechanism will need to change when we support 184*51f34d4bSRajkumar Sivaprakasam * multiple hcas and have support for multiple rdma plugins). 185*51f34d4bSRajkumar Sivaprakasam */ 186*51f34d4bSRajkumar Sivaprakasam mutex_enter(&rdma_wait.svc_lock); 187*51f34d4bSRajkumar Sivaprakasam rdma_wait.svc_stat = RDMA_HCA_DETACH; 188*51f34d4bSRajkumar Sivaprakasam cv_signal(&rdma_wait.svc_cv); 189*51f34d4bSRajkumar Sivaprakasam mutex_exit(&rdma_wait.svc_lock); 190*51f34d4bSRajkumar Sivaprakasam 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * Not found. 1937c478bd9Sstevel@tonic-gate */ 194*51f34d4bSRajkumar Sivaprakasam return (RDMA_SUCCESS); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1970a701b1eSRobert Gordon struct clist * 1980a701b1eSRobert Gordon clist_alloc(void) 1990a701b1eSRobert Gordon { 2000a701b1eSRobert Gordon struct clist *clp; 2010a701b1eSRobert Gordon 2020a701b1eSRobert Gordon clp = kmem_cache_alloc(clist_cache, KM_SLEEP); 2030a701b1eSRobert Gordon 2040a701b1eSRobert Gordon bzero(clp, sizeof (*clp)); 2050a701b1eSRobert Gordon 2060a701b1eSRobert Gordon return (clp); 2070a701b1eSRobert Gordon } 2080a701b1eSRobert Gordon 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Creates a new chunk list entry, and 2117c478bd9Sstevel@tonic-gate * adds it to the end of a chunk list. 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate void 2147c478bd9Sstevel@tonic-gate clist_add(struct clist **clp, uint32_t xdroff, int len, 2157c478bd9Sstevel@tonic-gate struct mrc *shandle, caddr_t saddr, 2167c478bd9Sstevel@tonic-gate struct mrc *dhandle, caddr_t daddr) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate struct clist *cl; 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate /* Find the end of the list */ 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate while (*clp != NULL) 2237c478bd9Sstevel@tonic-gate clp = &((*clp)->c_next); 2247c478bd9Sstevel@tonic-gate 2250a701b1eSRobert Gordon cl = clist_alloc(); 2267c478bd9Sstevel@tonic-gate cl->c_xdroff = xdroff; 2277c478bd9Sstevel@tonic-gate cl->c_len = len; 2280a701b1eSRobert Gordon cl->w.c_saddr = (uint64_t)(uintptr_t)saddr; 2297c478bd9Sstevel@tonic-gate if (shandle) 2307c478bd9Sstevel@tonic-gate cl->c_smemhandle = *shandle; 2310a701b1eSRobert Gordon cl->u.c_daddr = (uint64_t)(uintptr_t)daddr; 2327c478bd9Sstevel@tonic-gate if (dhandle) 2337c478bd9Sstevel@tonic-gate cl->c_dmemhandle = *dhandle; 2347c478bd9Sstevel@tonic-gate cl->c_next = NULL; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate *clp = cl; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2390a701b1eSRobert Gordon rdma_stat 2400a701b1eSRobert Gordon clist_register(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 2417c478bd9Sstevel@tonic-gate { 2427c478bd9Sstevel@tonic-gate struct clist *c; 2437c478bd9Sstevel@tonic-gate int status; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate for (c = cl; c; c = c->c_next) { 2460a701b1eSRobert Gordon if (c->c_len <= 0) 2470a701b1eSRobert Gordon continue; 2480a701b1eSRobert Gordon switch (dstsrc) { 2490a701b1eSRobert Gordon case CLIST_REG_SOURCE: 2507c478bd9Sstevel@tonic-gate status = RDMA_REGMEMSYNC(conn, 2510a701b1eSRobert Gordon (caddr_t)(struct as *)cl->c_adspc, 2520a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->w.c_saddr3, c->c_len, 2530a701b1eSRobert Gordon &c->c_smemhandle, (void **)&c->c_ssynchandle, 2540a701b1eSRobert Gordon (void *)c->rb_longbuf.rb_private); 2550a701b1eSRobert Gordon break; 2560a701b1eSRobert Gordon case CLIST_REG_DST: 2577c478bd9Sstevel@tonic-gate status = RDMA_REGMEMSYNC(conn, 2580a701b1eSRobert Gordon (caddr_t)(struct as *)cl->c_adspc, 2590a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->u.c_daddr3, c->c_len, 2600a701b1eSRobert Gordon &c->c_dmemhandle, (void **)&c->c_dsynchandle, 2610a701b1eSRobert Gordon (void *)c->rb_longbuf.rb_private); 2620a701b1eSRobert Gordon break; 2630a701b1eSRobert Gordon default: 2640a701b1eSRobert Gordon return (RDMA_INVAL); 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate if (status != RDMA_SUCCESS) { 2670a701b1eSRobert Gordon (void) clist_deregister(conn, cl, dstsrc); 2687c478bd9Sstevel@tonic-gate return (status); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate return (RDMA_SUCCESS); 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2750a701b1eSRobert Gordon rdma_stat 2760a701b1eSRobert Gordon clist_deregister(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 2777c478bd9Sstevel@tonic-gate { 2787c478bd9Sstevel@tonic-gate struct clist *c; 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate for (c = cl; c; c = c->c_next) { 2810a701b1eSRobert Gordon switch (dstsrc) { 2820a701b1eSRobert Gordon case CLIST_REG_SOURCE: 2837c478bd9Sstevel@tonic-gate if (c->c_smemhandle.mrc_rmr != 0) { 2847c478bd9Sstevel@tonic-gate (void) RDMA_DEREGMEMSYNC(conn, 2850a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->w.c_saddr3, 2867c478bd9Sstevel@tonic-gate c->c_smemhandle, 2870a701b1eSRobert Gordon (void *)(uintptr_t)c->c_ssynchandle, 2880a701b1eSRobert Gordon (void *)c->rb_longbuf.rb_private); 2897c478bd9Sstevel@tonic-gate c->c_smemhandle.mrc_rmr = 0; 2907c478bd9Sstevel@tonic-gate c->c_ssynchandle = NULL; 2917c478bd9Sstevel@tonic-gate } 2920a701b1eSRobert Gordon break; 2930a701b1eSRobert Gordon case CLIST_REG_DST: 2947c478bd9Sstevel@tonic-gate if (c->c_dmemhandle.mrc_rmr != 0) { 2957c478bd9Sstevel@tonic-gate (void) RDMA_DEREGMEMSYNC(conn, 2960a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->u.c_daddr3, 2977c478bd9Sstevel@tonic-gate c->c_dmemhandle, 2980a701b1eSRobert Gordon (void *)(uintptr_t)c->c_dsynchandle, 2990a701b1eSRobert Gordon (void *)c->rb_longbuf.rb_private); 3007c478bd9Sstevel@tonic-gate c->c_dmemhandle.mrc_rmr = 0; 3017c478bd9Sstevel@tonic-gate c->c_dsynchandle = NULL; 3027c478bd9Sstevel@tonic-gate } 3030a701b1eSRobert Gordon break; 3040a701b1eSRobert Gordon default: 3050a701b1eSRobert Gordon return (RDMA_INVAL); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate return (RDMA_SUCCESS); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3120a701b1eSRobert Gordon rdma_stat 3130a701b1eSRobert Gordon clist_syncmem(CONN *conn, struct clist *cl, clist_dstsrc dstsrc) 3140a701b1eSRobert Gordon { 3150a701b1eSRobert Gordon struct clist *c; 3160a701b1eSRobert Gordon rdma_stat status; 3170a701b1eSRobert Gordon 3180a701b1eSRobert Gordon c = cl; 3190a701b1eSRobert Gordon switch (dstsrc) { 3200a701b1eSRobert Gordon case CLIST_REG_SOURCE: 3210a701b1eSRobert Gordon while (c != NULL) { 3220a701b1eSRobert Gordon if (c->c_ssynchandle) { 3230a701b1eSRobert Gordon status = RDMA_SYNCMEM(conn, 3240a701b1eSRobert Gordon (void *)(uintptr_t)c->c_ssynchandle, 3250a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->w.c_saddr3, 3260a701b1eSRobert Gordon c->c_len, 0); 3270a701b1eSRobert Gordon if (status != RDMA_SUCCESS) 3280a701b1eSRobert Gordon return (status); 3290a701b1eSRobert Gordon } 3300a701b1eSRobert Gordon c = c->c_next; 3310a701b1eSRobert Gordon } 3320a701b1eSRobert Gordon break; 3330a701b1eSRobert Gordon case CLIST_REG_DST: 3340a701b1eSRobert Gordon while (c != NULL) { 3350a701b1eSRobert Gordon if (c->c_ssynchandle) { 3360a701b1eSRobert Gordon status = RDMA_SYNCMEM(conn, 3370a701b1eSRobert Gordon (void *)(uintptr_t)c->c_dsynchandle, 3380a701b1eSRobert Gordon (caddr_t)(uintptr_t)c->u.c_daddr3, 3390a701b1eSRobert Gordon c->c_len, 1); 3400a701b1eSRobert Gordon if (status != RDMA_SUCCESS) 3410a701b1eSRobert Gordon return (status); 3420a701b1eSRobert Gordon } 3430a701b1eSRobert Gordon c = c->c_next; 3440a701b1eSRobert Gordon } 3450a701b1eSRobert Gordon break; 3460a701b1eSRobert Gordon default: 3470a701b1eSRobert Gordon return (RDMA_INVAL); 3480a701b1eSRobert Gordon } 3490a701b1eSRobert Gordon 3500a701b1eSRobert Gordon return (RDMA_SUCCESS); 3510a701b1eSRobert Gordon } 3520a701b1eSRobert Gordon 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * Frees up entries in chunk list 3557c478bd9Sstevel@tonic-gate */ 3567c478bd9Sstevel@tonic-gate void 3577c478bd9Sstevel@tonic-gate clist_free(struct clist *cl) 3587c478bd9Sstevel@tonic-gate { 3597c478bd9Sstevel@tonic-gate struct clist *c = cl; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate while (c != NULL) { 3627c478bd9Sstevel@tonic-gate cl = cl->c_next; 3630a701b1eSRobert Gordon kmem_cache_free(clist_cache, c); 3647c478bd9Sstevel@tonic-gate c = cl; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate rdma_stat 3697c478bd9Sstevel@tonic-gate rdma_clnt_postrecv(CONN *conn, uint32_t xid) 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate struct clist *cl = NULL; 3727c478bd9Sstevel@tonic-gate rdma_stat retval; 3730a701b1eSRobert Gordon rdma_buf_t rbuf = {0}; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate rbuf.type = RECV_BUFFER; 3767c478bd9Sstevel@tonic-gate if (RDMA_BUF_ALLOC(conn, &rbuf)) { 3770a701b1eSRobert Gordon return (RDMA_NORESOURCE); 3787c478bd9Sstevel@tonic-gate } 3790a701b1eSRobert Gordon 3800a701b1eSRobert Gordon clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr, 3810a701b1eSRobert Gordon NULL, NULL); 3820a701b1eSRobert Gordon retval = RDMA_CLNT_RECVBUF(conn, cl, xid); 3830a701b1eSRobert Gordon clist_free(cl); 3840a701b1eSRobert Gordon 3857c478bd9Sstevel@tonic-gate return (retval); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3880a701b1eSRobert Gordon rdma_stat 3890a701b1eSRobert Gordon rdma_clnt_postrecv_remove(CONN *conn, uint32_t xid) 3900a701b1eSRobert Gordon { 3910a701b1eSRobert Gordon return (RDMA_CLNT_RECVBUF_REMOVE(conn, xid)); 3920a701b1eSRobert Gordon } 3930a701b1eSRobert Gordon 3947c478bd9Sstevel@tonic-gate rdma_stat 3957c478bd9Sstevel@tonic-gate rdma_svc_postrecv(CONN *conn) 3967c478bd9Sstevel@tonic-gate { 3977c478bd9Sstevel@tonic-gate struct clist *cl = NULL; 3987c478bd9Sstevel@tonic-gate rdma_stat retval; 3990a701b1eSRobert Gordon rdma_buf_t rbuf = {0}; 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate rbuf.type = RECV_BUFFER; 4027c478bd9Sstevel@tonic-gate if (RDMA_BUF_ALLOC(conn, &rbuf)) { 4037c478bd9Sstevel@tonic-gate retval = RDMA_NORESOURCE; 4047c478bd9Sstevel@tonic-gate } else { 4057c478bd9Sstevel@tonic-gate clist_add(&cl, 0, rbuf.len, &rbuf.handle, rbuf.addr, 4060a701b1eSRobert Gordon NULL, NULL); 4077c478bd9Sstevel@tonic-gate retval = RDMA_SVC_RECVBUF(conn, cl); 4087c478bd9Sstevel@tonic-gate clist_free(cl); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate return (retval); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate rdma_stat 4140a701b1eSRobert Gordon rdma_buf_alloc(CONN *conn, rdma_buf_t *rbuf) 4157c478bd9Sstevel@tonic-gate { 4160a701b1eSRobert Gordon return (RDMA_BUF_ALLOC(conn, rbuf)); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate void 4207c478bd9Sstevel@tonic-gate rdma_buf_free(CONN *conn, rdma_buf_t *rbuf) 4217c478bd9Sstevel@tonic-gate { 4227c478bd9Sstevel@tonic-gate if (!rbuf || rbuf->addr == NULL) { 4237c478bd9Sstevel@tonic-gate return; 4247c478bd9Sstevel@tonic-gate } 4250a701b1eSRobert Gordon RDMA_BUF_FREE(conn, rbuf); 4260a701b1eSRobert Gordon bzero(rbuf, sizeof (rdma_buf_t)); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * Caller is holding rdma_modload_lock mutex 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate int 4337c478bd9Sstevel@tonic-gate rdma_modload() 4347c478bd9Sstevel@tonic-gate { 4357c478bd9Sstevel@tonic-gate int status; 4367c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&rdma_modload_lock)); 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * Load all available RDMA plugins which right now is only IB plugin. 4397c478bd9Sstevel@tonic-gate * If no IB hardware is present, then quit right away. 4407c478bd9Sstevel@tonic-gate * ENODEV -- For no device on the system 4417c478bd9Sstevel@tonic-gate * EPROTONOSUPPORT -- For module not avilable either due to failure to 4427c478bd9Sstevel@tonic-gate * load or some other reason. 4437c478bd9Sstevel@tonic-gate */ 4447c478bd9Sstevel@tonic-gate rdma_modloaded = 1; 4457c478bd9Sstevel@tonic-gate if (ibt_hw_is_present() == 0) { 4467c478bd9Sstevel@tonic-gate rdma_dev_available = 0; 4477c478bd9Sstevel@tonic-gate return (ENODEV); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate rdma_dev_available = 1; 4517c478bd9Sstevel@tonic-gate if (rpcmod_li == NULL) 4527c478bd9Sstevel@tonic-gate return (EPROTONOSUPPORT); 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate status = ldi_open_by_name("/devices/ib/rpcib@0:rpcib", 4557c478bd9Sstevel@tonic-gate FREAD | FWRITE, kcred, 4567c478bd9Sstevel@tonic-gate &rpcib_handle, rpcmod_li); 457*51f34d4bSRajkumar Sivaprakasam 4587c478bd9Sstevel@tonic-gate if (status != 0) 4597c478bd9Sstevel@tonic-gate return (EPROTONOSUPPORT); 4607c478bd9Sstevel@tonic-gate 4610a701b1eSRobert Gordon 462*51f34d4bSRajkumar Sivaprakasam /* 463*51f34d4bSRajkumar Sivaprakasam * We will need to reload the plugin module after it was unregistered 464*51f34d4bSRajkumar Sivaprakasam * but the resources below need to allocated only the first time. 465*51f34d4bSRajkumar Sivaprakasam */ 466*51f34d4bSRajkumar Sivaprakasam if (!clist_cache) { 467*51f34d4bSRajkumar Sivaprakasam clist_cache = kmem_cache_create("rdma_clist", 468*51f34d4bSRajkumar Sivaprakasam sizeof (struct clist), _POINTER_ALIGNMENT, NULL, 469*51f34d4bSRajkumar Sivaprakasam NULL, NULL, NULL, 0, 0); 470*51f34d4bSRajkumar Sivaprakasam rdma_kstat_init(); 471*51f34d4bSRajkumar Sivaprakasam } 472*51f34d4bSRajkumar Sivaprakasam 473*51f34d4bSRajkumar Sivaprakasam (void) ldi_close(rpcib_handle, FREAD|FWRITE, kcred); 4740a701b1eSRobert Gordon 4757c478bd9Sstevel@tonic-gate return (0); 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate void 4797c478bd9Sstevel@tonic-gate rdma_kstat_init(void) 4807c478bd9Sstevel@tonic-gate { 4817c478bd9Sstevel@tonic-gate kstat_t *ksp; 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate /* 4847c478bd9Sstevel@tonic-gate * The RDMA framework doesn't know how to deal with Zones, and is 4857c478bd9Sstevel@tonic-gate * only available in the global zone. 4867c478bd9Sstevel@tonic-gate */ 4877c478bd9Sstevel@tonic-gate ASSERT(INGLOBALZONE(curproc)); 4887c478bd9Sstevel@tonic-gate ksp = kstat_create_zone("unix", 0, "rpc_rdma_client", "rpc", 4897c478bd9Sstevel@tonic-gate KSTAT_TYPE_NAMED, rdmarcstat_ndata, 4907c478bd9Sstevel@tonic-gate KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, GLOBAL_ZONEID); 4917c478bd9Sstevel@tonic-gate if (ksp) { 4927c478bd9Sstevel@tonic-gate ksp->ks_data = (void *) rdmarcstat_ptr; 4937c478bd9Sstevel@tonic-gate kstat_install(ksp); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate ksp = kstat_create_zone("unix", 0, "rpc_rdma_server", "rpc", 4977c478bd9Sstevel@tonic-gate KSTAT_TYPE_NAMED, rdmarsstat_ndata, 4987c478bd9Sstevel@tonic-gate KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, GLOBAL_ZONEID); 4997c478bd9Sstevel@tonic-gate if (ksp) { 5007c478bd9Sstevel@tonic-gate ksp->ks_data = (void *) rdmarsstat_ptr; 5017c478bd9Sstevel@tonic-gate kstat_install(ksp); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate } 504*51f34d4bSRajkumar Sivaprakasam 505*51f34d4bSRajkumar Sivaprakasam rdma_stat 506*51f34d4bSRajkumar Sivaprakasam rdma_kwait(void) 507*51f34d4bSRajkumar Sivaprakasam { 508*51f34d4bSRajkumar Sivaprakasam int ret; 509*51f34d4bSRajkumar Sivaprakasam rdma_stat stat; 510*51f34d4bSRajkumar Sivaprakasam 511*51f34d4bSRajkumar Sivaprakasam mutex_enter(&rdma_wait.svc_lock); 512*51f34d4bSRajkumar Sivaprakasam 513*51f34d4bSRajkumar Sivaprakasam ret = cv_wait_sig(&rdma_wait.svc_cv, &rdma_wait.svc_lock); 514*51f34d4bSRajkumar Sivaprakasam 515*51f34d4bSRajkumar Sivaprakasam /* 516*51f34d4bSRajkumar Sivaprakasam * If signalled by a hca attach/detach, pass the right 517*51f34d4bSRajkumar Sivaprakasam * stat back. 518*51f34d4bSRajkumar Sivaprakasam */ 519*51f34d4bSRajkumar Sivaprakasam 520*51f34d4bSRajkumar Sivaprakasam if (ret) 521*51f34d4bSRajkumar Sivaprakasam stat = rdma_wait.svc_stat; 522*51f34d4bSRajkumar Sivaprakasam else 523*51f34d4bSRajkumar Sivaprakasam stat = RDMA_INTR; 524*51f34d4bSRajkumar Sivaprakasam 525*51f34d4bSRajkumar Sivaprakasam mutex_exit(&rdma_wait.svc_lock); 526*51f34d4bSRajkumar Sivaprakasam 527*51f34d4bSRajkumar Sivaprakasam return (stat); 528*51f34d4bSRajkumar Sivaprakasam } 529