1 /* 2 * Copyright (c) 2026 Rick Macklem 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #ifndef _RPC_CLNTRDMA_H_ 8 #define _RPC_CLNTRDMA_H_ 9 10 #ifdef _KERNEL 11 #define RPCRDMA_IO_NUMBUFS 64 /* Max. # of concurrent RPCs. */ 12 13 struct rpcrdma_reduce_pg { 14 uint32_t xid; 15 uint32_t pos; 16 uint32_t len; 17 uint32_t npg; 18 uint32_t into_mem; 19 vm_page_t pg[]; 20 }; 21 22 /* Structure for a connection. */ 23 struct rpcrdma_xprt { 24 struct mtx mtx; 25 uint32_t credits; 26 uint32_t maxrpc; 27 uint32_t maxbck; 28 uint32_t maxio; 29 uint32_t maxsge; 30 uint32_t maxsegs; 31 uint32_t use_bounce; 32 void *ep; 33 }; 34 35 #define RPCRDMA_MAX_SEGMENTS 16 /* Limit from RFC8267. */ 36 #define RPCRDMA_MAX_INLINE 1024 /* Limit from RFC8267. */ 37 38 /* 39 * Since I/O sizes are always a power of 2 and RPCRDMA_MAX_SEGMENTS is a 40 * power of 2, RPCRDMA_MAX_SGE must be a power of 2 plus 1. 41 * The +1 is for the rest of the RPC message that goes along with the data. 42 * This value sets the size of the arrays and, as such, is the upper bound 43 * for xp->maxsge, which is set to a power of 2 + 1 by xprt_rdma_connect(). 44 * At this time, the power of 2 is 16 for Mellanox, 8 for Intel and ?? for 45 * Chelsio. If future NICs support larger powers of 2, based on their 46 * max_sge, max_sge_rd and max_qp_rd_atom values, this constant can be 47 * increased. The only effect is making the array sizes in 48 * "struct _rpcrdma_chunk_priv" larger. 49 */ 50 #define RPCRDMA_MAX_SGE (16 + 1) 51 52 struct rpcrdma_chunk { 53 int ind; 54 unsigned int first_off; 55 uint32_t last_len; 56 uint32_t num_segment; 57 uint32_t into_mem; 58 uint32_t sge_cnt[RPCRDMA_MAX_SEGMENTS]; 59 uint32_t handle[RPCRDMA_MAX_SEGMENTS]; 60 uint32_t length[RPCRDMA_MAX_SEGMENTS]; 61 uint64_t offset[RPCRDMA_MAX_SEGMENTS]; 62 struct mbuf *mextpg; 63 }; 64 65 #define RPCRDMA_DEBUG(level, ...) do { \ 66 if (rpcrdma_debuglevel >= (level)) \ 67 printf(__VA_ARGS__); \ 68 } while (0) 69 70 extern int rpcrdma_debuglevel; 71 72 /* 73 * Upcall to krpc or similar. Passes mbuf chain and context up. 74 */ 75 typedef void (*xprt_rdma_upcall)(struct rpcrdma_xprt *xp, struct mbuf *mp); 76 77 void xprt_rdma_init(struct rpcrdma_xprt *xp, xprt_rdma_upcall rdma_upcall); 78 79 int xprt_rdma_check_route(struct vnet *net, struct sockaddr *saddr, 80 uint32_t cbslots); 81 82 int xprt_rdma_connect(struct vnet *net, struct sockaddr *saddr, 83 struct rpcrdma_xprt *xp, size_t buflen, uint32_t cbslots); 84 85 void xprt_rdma_disconnect(struct rpcrdma_xprt *xp); 86 87 int xprt_rdma_send(struct rpcrdma_xprt *xp, struct mbuf *mreq, int ind); 88 89 void xprt_rdma_release_send(struct rpcrdma_xprt *xp, int ind, 90 struct rpcrdma_chunk *extern_chp, struct rpcrdma_chunk *extern_reply_chp, 91 struct rpcrdma_chunk *extern_request_chp); 92 93 int xprt_rdma_recv(struct rpcrdma_xprt *xp); 94 95 void xprt_rdma_release_ep(struct rpcrdma_xprt *xp); 96 97 struct rpcrdma_chunk *xprt_rdma_create_chunk(struct rpcrdma_xprt *xp, 98 uint32_t num_pg, struct rpcrdma_reduce_pg *rb, struct mbuf *mextpg, 99 bool into_mem, int ind); 100 101 int xprt_rdma_isdisconnected(struct rpcrdma_xprt *xp); 102 103 void xprt_rdma_mark_disconnected(struct rpcrdma_xprt *xp); 104 105 int xprt_rdma_acquire_buf(struct rpcrdma_xprt *xp, int start, int end); 106 107 void xprt_rdma_unmap_chunk(struct rpcrdma_xprt *xp, struct rpcrdma_chunk *chp); 108 109 struct mbuf *rpc_reduce_pg(int len, int pos, bool to_mem); 110 111 void rpc_free_rdma_reduction(struct mbuf *mr); 112 113 int rpc_copy_uio_pages(struct mbuf *mr, struct uio *uiop, int len, 114 bool from_pages); 115 116 void rpc_copy_mbuf_to_rb(struct mbuf *m, struct rpcrdma_reduce_pg *rb); 117 118 void rpc_remove_mreduce(struct mbuf *m, bool free_it); 119 #endif /* _KERNEL */ 120 121 #endif /* _RPC_CLNTRDMA_H_ */ 122