xref: /freebsd/sys/rpc/clntrdma.h (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
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