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