1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * This software is available to you under a choice of one of two 6*4882a593Smuzhiyun * licenses. You may choose to be licensed under the terms of the GNU 7*4882a593Smuzhiyun * General Public License (GPL) Version 2, available from the file 8*4882a593Smuzhiyun * COPYING in the main directory of this source tree, or the BSD-type 9*4882a593Smuzhiyun * license below: 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without 12*4882a593Smuzhiyun * modification, are permitted provided that the following conditions 13*4882a593Smuzhiyun * are met: 14*4882a593Smuzhiyun * 15*4882a593Smuzhiyun * Redistributions of source code must retain the above copyright 16*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * Redistributions in binary form must reproduce the above 19*4882a593Smuzhiyun * copyright notice, this list of conditions and the following 20*4882a593Smuzhiyun * disclaimer in the documentation and/or other materials provided 21*4882a593Smuzhiyun * with the distribution. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * Neither the name of the Network Appliance, Inc. nor the names of 24*4882a593Smuzhiyun * its contributors may be used to endorse or promote products 25*4882a593Smuzhiyun * derived from this software without specific prior written 26*4882a593Smuzhiyun * permission. 27*4882a593Smuzhiyun * 28*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29*4882a593Smuzhiyun * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30*4882a593Smuzhiyun * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31*4882a593Smuzhiyun * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32*4882a593Smuzhiyun * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33*4882a593Smuzhiyun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34*4882a593Smuzhiyun * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35*4882a593Smuzhiyun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36*4882a593Smuzhiyun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38*4882a593Smuzhiyun * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39*4882a593Smuzhiyun * 40*4882a593Smuzhiyun * Author: Tom Tucker <tom@opengridcomputing.com> 41*4882a593Smuzhiyun */ 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #ifndef SVC_RDMA_H 44*4882a593Smuzhiyun #define SVC_RDMA_H 45*4882a593Smuzhiyun #include <linux/llist.h> 46*4882a593Smuzhiyun #include <linux/sunrpc/xdr.h> 47*4882a593Smuzhiyun #include <linux/sunrpc/svcsock.h> 48*4882a593Smuzhiyun #include <linux/sunrpc/rpc_rdma.h> 49*4882a593Smuzhiyun #include <linux/sunrpc/rpc_rdma_cid.h> 50*4882a593Smuzhiyun #include <rdma/ib_verbs.h> 51*4882a593Smuzhiyun #include <rdma/rdma_cm.h> 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /* Default and maximum inline threshold sizes */ 54*4882a593Smuzhiyun enum { 55*4882a593Smuzhiyun RPCRDMA_PULLUP_THRESH = RPCRDMA_V1_DEF_INLINE_SIZE >> 1, 56*4882a593Smuzhiyun RPCRDMA_DEF_INLINE_THRESH = 4096, 57*4882a593Smuzhiyun RPCRDMA_MAX_INLINE_THRESH = 65536 58*4882a593Smuzhiyun }; 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /* RPC/RDMA parameters and stats */ 61*4882a593Smuzhiyun extern unsigned int svcrdma_ord; 62*4882a593Smuzhiyun extern unsigned int svcrdma_max_requests; 63*4882a593Smuzhiyun extern unsigned int svcrdma_max_bc_requests; 64*4882a593Smuzhiyun extern unsigned int svcrdma_max_req_size; 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun extern atomic_t rdma_stat_recv; 67*4882a593Smuzhiyun extern atomic_t rdma_stat_read; 68*4882a593Smuzhiyun extern atomic_t rdma_stat_write; 69*4882a593Smuzhiyun extern atomic_t rdma_stat_sq_starve; 70*4882a593Smuzhiyun extern atomic_t rdma_stat_rq_starve; 71*4882a593Smuzhiyun extern atomic_t rdma_stat_rq_poll; 72*4882a593Smuzhiyun extern atomic_t rdma_stat_rq_prod; 73*4882a593Smuzhiyun extern atomic_t rdma_stat_sq_poll; 74*4882a593Smuzhiyun extern atomic_t rdma_stat_sq_prod; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun struct svcxprt_rdma { 77*4882a593Smuzhiyun struct svc_xprt sc_xprt; /* SVC transport structure */ 78*4882a593Smuzhiyun struct rdma_cm_id *sc_cm_id; /* RDMA connection id */ 79*4882a593Smuzhiyun struct list_head sc_accept_q; /* Conn. waiting accept */ 80*4882a593Smuzhiyun int sc_ord; /* RDMA read limit */ 81*4882a593Smuzhiyun int sc_max_send_sges; 82*4882a593Smuzhiyun bool sc_snd_w_inv; /* OK to use Send With Invalidate */ 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun atomic_t sc_sq_avail; /* SQEs ready to be consumed */ 85*4882a593Smuzhiyun unsigned int sc_sq_depth; /* Depth of SQ */ 86*4882a593Smuzhiyun __be32 sc_fc_credits; /* Forward credits */ 87*4882a593Smuzhiyun u32 sc_max_requests; /* Max requests */ 88*4882a593Smuzhiyun u32 sc_max_bc_requests;/* Backward credits */ 89*4882a593Smuzhiyun int sc_max_req_size; /* Size of each RQ WR buf */ 90*4882a593Smuzhiyun u8 sc_port_num; 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun struct ib_pd *sc_pd; 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun spinlock_t sc_send_lock; 95*4882a593Smuzhiyun struct list_head sc_send_ctxts; 96*4882a593Smuzhiyun spinlock_t sc_rw_ctxt_lock; 97*4882a593Smuzhiyun struct list_head sc_rw_ctxts; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun struct list_head sc_rq_dto_q; 100*4882a593Smuzhiyun spinlock_t sc_rq_dto_lock; 101*4882a593Smuzhiyun struct ib_qp *sc_qp; 102*4882a593Smuzhiyun struct ib_cq *sc_rq_cq; 103*4882a593Smuzhiyun struct ib_cq *sc_sq_cq; 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun spinlock_t sc_lock; /* transport lock */ 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun wait_queue_head_t sc_send_wait; /* SQ exhaustion waitlist */ 108*4882a593Smuzhiyun unsigned long sc_flags; 109*4882a593Smuzhiyun struct list_head sc_read_complete_q; 110*4882a593Smuzhiyun struct work_struct sc_work; 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun struct llist_head sc_recv_ctxts; 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun atomic_t sc_completion_ids; 115*4882a593Smuzhiyun }; 116*4882a593Smuzhiyun /* sc_flags */ 117*4882a593Smuzhiyun #define RDMAXPRT_CONN_PENDING 3 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun * Default connection parameters 121*4882a593Smuzhiyun */ 122*4882a593Smuzhiyun enum { 123*4882a593Smuzhiyun RPCRDMA_LISTEN_BACKLOG = 10, 124*4882a593Smuzhiyun RPCRDMA_MAX_REQUESTS = 64, 125*4882a593Smuzhiyun RPCRDMA_MAX_BC_REQUESTS = 2, 126*4882a593Smuzhiyun }; 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun struct svc_rdma_recv_ctxt { 131*4882a593Smuzhiyun struct llist_node rc_node; 132*4882a593Smuzhiyun struct list_head rc_list; 133*4882a593Smuzhiyun struct ib_recv_wr rc_recv_wr; 134*4882a593Smuzhiyun struct ib_cqe rc_cqe; 135*4882a593Smuzhiyun struct rpc_rdma_cid rc_cid; 136*4882a593Smuzhiyun struct ib_sge rc_recv_sge; 137*4882a593Smuzhiyun void *rc_recv_buf; 138*4882a593Smuzhiyun struct xdr_buf rc_arg; 139*4882a593Smuzhiyun struct xdr_stream rc_stream; 140*4882a593Smuzhiyun bool rc_temp; 141*4882a593Smuzhiyun u32 rc_byte_len; 142*4882a593Smuzhiyun unsigned int rc_page_count; 143*4882a593Smuzhiyun unsigned int rc_hdr_count; 144*4882a593Smuzhiyun u32 rc_inv_rkey; 145*4882a593Smuzhiyun __be32 *rc_write_list; 146*4882a593Smuzhiyun __be32 *rc_reply_chunk; 147*4882a593Smuzhiyun unsigned int rc_read_payload_offset; 148*4882a593Smuzhiyun unsigned int rc_read_payload_length; 149*4882a593Smuzhiyun struct page *rc_pages[RPCSVC_MAXPAGES]; 150*4882a593Smuzhiyun }; 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun struct svc_rdma_send_ctxt { 153*4882a593Smuzhiyun struct list_head sc_list; 154*4882a593Smuzhiyun struct rpc_rdma_cid sc_cid; 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun struct ib_send_wr sc_send_wr; 157*4882a593Smuzhiyun struct ib_cqe sc_cqe; 158*4882a593Smuzhiyun struct xdr_buf sc_hdrbuf; 159*4882a593Smuzhiyun struct xdr_stream sc_stream; 160*4882a593Smuzhiyun void *sc_xprt_buf; 161*4882a593Smuzhiyun int sc_page_count; 162*4882a593Smuzhiyun int sc_cur_sge_no; 163*4882a593Smuzhiyun struct page *sc_pages[RPCSVC_MAXPAGES]; 164*4882a593Smuzhiyun struct ib_sge sc_sges[]; 165*4882a593Smuzhiyun }; 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun /* svc_rdma_backchannel.c */ 168*4882a593Smuzhiyun extern void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp, 169*4882a593Smuzhiyun struct svc_rdma_recv_ctxt *rctxt); 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun /* svc_rdma_recvfrom.c */ 172*4882a593Smuzhiyun extern void svc_rdma_recv_ctxts_destroy(struct svcxprt_rdma *rdma); 173*4882a593Smuzhiyun extern bool svc_rdma_post_recvs(struct svcxprt_rdma *rdma); 174*4882a593Smuzhiyun extern void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma, 175*4882a593Smuzhiyun struct svc_rdma_recv_ctxt *ctxt); 176*4882a593Smuzhiyun extern void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma); 177*4882a593Smuzhiyun extern void svc_rdma_release_rqst(struct svc_rqst *rqstp); 178*4882a593Smuzhiyun extern int svc_rdma_recvfrom(struct svc_rqst *); 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun /* svc_rdma_rw.c */ 181*4882a593Smuzhiyun extern void svc_rdma_destroy_rw_ctxts(struct svcxprt_rdma *rdma); 182*4882a593Smuzhiyun extern int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, 183*4882a593Smuzhiyun struct svc_rqst *rqstp, 184*4882a593Smuzhiyun struct svc_rdma_recv_ctxt *head, __be32 *p); 185*4882a593Smuzhiyun extern int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma, 186*4882a593Smuzhiyun __be32 *wr_ch, struct xdr_buf *xdr, 187*4882a593Smuzhiyun unsigned int offset, 188*4882a593Smuzhiyun unsigned long length); 189*4882a593Smuzhiyun extern int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma, 190*4882a593Smuzhiyun const struct svc_rdma_recv_ctxt *rctxt, 191*4882a593Smuzhiyun struct xdr_buf *xdr); 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun /* svc_rdma_sendto.c */ 194*4882a593Smuzhiyun extern void svc_rdma_send_ctxts_destroy(struct svcxprt_rdma *rdma); 195*4882a593Smuzhiyun extern struct svc_rdma_send_ctxt * 196*4882a593Smuzhiyun svc_rdma_send_ctxt_get(struct svcxprt_rdma *rdma); 197*4882a593Smuzhiyun extern void svc_rdma_send_ctxt_put(struct svcxprt_rdma *rdma, 198*4882a593Smuzhiyun struct svc_rdma_send_ctxt *ctxt); 199*4882a593Smuzhiyun extern int svc_rdma_send(struct svcxprt_rdma *rdma, 200*4882a593Smuzhiyun struct svc_rdma_send_ctxt *ctxt); 201*4882a593Smuzhiyun extern int svc_rdma_map_reply_msg(struct svcxprt_rdma *rdma, 202*4882a593Smuzhiyun struct svc_rdma_send_ctxt *sctxt, 203*4882a593Smuzhiyun const struct svc_rdma_recv_ctxt *rctxt, 204*4882a593Smuzhiyun struct xdr_buf *xdr); 205*4882a593Smuzhiyun extern void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, 206*4882a593Smuzhiyun struct svc_rdma_send_ctxt *sctxt, 207*4882a593Smuzhiyun struct svc_rdma_recv_ctxt *rctxt, 208*4882a593Smuzhiyun int status); 209*4882a593Smuzhiyun extern int svc_rdma_sendto(struct svc_rqst *); 210*4882a593Smuzhiyun extern int svc_rdma_read_payload(struct svc_rqst *rqstp, unsigned int offset, 211*4882a593Smuzhiyun unsigned int length); 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun /* svc_rdma_transport.c */ 214*4882a593Smuzhiyun extern struct svc_xprt_class svc_rdma_class; 215*4882a593Smuzhiyun #ifdef CONFIG_SUNRPC_BACKCHANNEL 216*4882a593Smuzhiyun extern struct svc_xprt_class svc_rdma_bc_class; 217*4882a593Smuzhiyun #endif 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun /* svc_rdma.c */ 220*4882a593Smuzhiyun extern int svc_rdma_init(void); 221*4882a593Smuzhiyun extern void svc_rdma_cleanup(void); 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun #endif 224