1 /*
2  * Copyright (C) 2016 by Argonne National Laboratory.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 #include "rdma/bgq/fi_bgq.h"
33 #include <ofi_enosys.h>
34 #include <errno.h>
35 
36 /* "FI_BGQ_RMA_SPECIALIZED_FUNC(0)" is already declared via FABRIC_DIRECT */
37 FI_BGQ_RMA_SPECIALIZED_FUNC(1)
38 
39 #define FI_BGQ_RMA_OPS_STRUCT_NAME(LOCK)			\
40 	fi_bgq_ops_rma_ ## LOCK
41 
42 #define FI_BGQ_RMA_OPS_STRUCT(LOCK)				\
43 static struct fi_ops_rma					\
44 	FI_BGQ_RMA_OPS_STRUCT_NAME(LOCK) = {			\
45 	.size	= sizeof(struct fi_ops_rma),			\
46 	.read	= FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(read, LOCK),	\
47 	.readv	= fi_no_rma_readv,				\
48 	.readmsg = FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(readmsg,	\
49 			LOCK),					\
50 	.write	= FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(write,	\
51 			LOCK),					\
52 	.inject = FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(inject_write,\
53 			LOCK),					\
54 	.writev = FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(writev,	\
55 			LOCK),					\
56 	.writemsg = FI_BGQ_RMA_SPECIALIZED_FUNC_NAME(writemsg,	\
57 			LOCK),					\
58 	.writedata = fi_no_rma_writedata,			\
59 }
60 
61 FI_BGQ_RMA_OPS_STRUCT(0);
62 FI_BGQ_RMA_OPS_STRUCT(1);
63 
fi_bgq_rma_read(struct fid_ep * ep,void * buf,size_t len,void * desc,fi_addr_t src_addr,uint64_t addr,uint64_t key,void * context)64 static inline ssize_t fi_bgq_rma_read(struct fid_ep *ep,
65 		void *buf, size_t len, void *desc,
66 		fi_addr_t src_addr, uint64_t addr,
67 		uint64_t key, void *context)
68 {
69 	int lock_required;
70 	struct fi_bgq_ep *bgq_ep;
71 
72 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
73 
74 	switch (bgq_ep->threading) {
75 	case FI_THREAD_ENDPOINT:
76 	case FI_THREAD_DOMAIN:
77 		lock_required = 0;
78 	default:
79 		lock_required = 1;
80 	}
81 
82 	return fi_bgq_read_generic(ep, buf, len, desc, src_addr,
83 			addr, key, context, lock_required);
84 }
85 
fi_bgq_rma_readmsg(struct fid_ep * ep,const struct fi_msg_rma * msg,uint64_t flags)86 static inline ssize_t fi_bgq_rma_readmsg(struct fid_ep *ep,
87 		const struct fi_msg_rma *msg, uint64_t flags)
88 {
89 	int lock_required;
90 	struct fi_bgq_ep *bgq_ep;
91 
92 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
93 
94 	switch (bgq_ep->threading) {
95 	case FI_THREAD_ENDPOINT:
96 	case FI_THREAD_DOMAIN:
97 		lock_required = 0;
98 	default:
99 		lock_required = 1;
100 	}
101 
102 	return fi_bgq_readmsg_generic(ep, msg, flags,
103 			lock_required);
104 }
105 
fi_bgq_rma_inject_write(struct fid_ep * ep,const void * buf,size_t len,fi_addr_t dst_addr,uint64_t addr,uint64_t key)106 static inline ssize_t fi_bgq_rma_inject_write(struct fid_ep *ep,
107 		const void *buf, size_t len,
108 		fi_addr_t dst_addr, uint64_t addr, uint64_t key)
109 {
110 	int lock_required;
111 	struct fi_bgq_ep *bgq_ep;
112 
113 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
114 
115 	switch (bgq_ep->threading) {
116 		case FI_THREAD_ENDPOINT:
117 		case FI_THREAD_DOMAIN:
118 			lock_required = 0;
119 		default:
120 			lock_required = 1;
121 	}
122 
123 	return fi_bgq_inject_write_generic(ep, buf, len, dst_addr,
124 			addr, key, lock_required);
125 }
126 
fi_bgq_rma_write(struct fid_ep * ep,const void * buf,size_t len,void * desc,fi_addr_t dst_addr,uint64_t addr,uint64_t key,void * context)127 static inline ssize_t fi_bgq_rma_write(struct fid_ep *ep,
128 		const void *buf, size_t len, void *desc,
129 		fi_addr_t dst_addr, uint64_t addr,
130 		uint64_t key, void *context)
131 {
132 	int lock_required;
133 	struct fi_bgq_ep *bgq_ep;
134 
135 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
136 
137 	switch (bgq_ep->threading) {
138 	case FI_THREAD_ENDPOINT:
139 	case FI_THREAD_DOMAIN:
140 		lock_required = 0;
141 	default:
142 		lock_required = 1;
143 	}
144 
145 	return fi_bgq_write_generic(ep, buf, len, desc, dst_addr,
146 			addr, key, context, lock_required);
147 }
148 
fi_bgq_rma_writev(struct fid_ep * ep,const struct iovec * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t addr,uint64_t key,void * context)149 static inline ssize_t fi_bgq_rma_writev(struct fid_ep *ep,
150 		const struct iovec *iov, void **desc,
151 		size_t count, fi_addr_t dest_addr, uint64_t addr,
152 		uint64_t key, void *context)
153 {
154 	int lock_required;
155 	struct fi_bgq_ep *bgq_ep;
156 
157 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
158 
159 	switch (bgq_ep->threading) {
160 	case FI_THREAD_ENDPOINT:
161 	case FI_THREAD_DOMAIN:
162 		lock_required = 0;
163 	default:
164 		lock_required = 1;
165 	}
166 
167 	return fi_bgq_writev_generic(ep, iov, desc, count, dest_addr, addr,
168 			key, context, lock_required);
169 }
170 
fi_bgq_rma_writemsg(struct fid_ep * ep,const struct fi_msg_rma * msg,uint64_t flags)171 static inline ssize_t fi_bgq_rma_writemsg(struct fid_ep *ep,
172 		const struct fi_msg_rma *msg, uint64_t flags)
173 {
174 	int lock_required;
175 	struct fi_bgq_ep *bgq_ep;
176 
177 	bgq_ep = container_of(ep, struct fi_bgq_ep, ep_fid);
178 
179 	switch (bgq_ep->threading) {
180 	case FI_THREAD_ENDPOINT:
181 	case FI_THREAD_DOMAIN:
182 		lock_required = 0;
183 	default:
184 		lock_required = 1;
185 	}
186 
187 	return fi_bgq_writemsg_generic(ep, msg, flags,
188 			lock_required);
189 }
190 
191 static struct fi_ops_rma fi_bgq_ops_rma_default = {
192 	.size		= sizeof(struct fi_ops_rma),
193 	.read		= fi_bgq_rma_read,
194 	.readv		= fi_no_rma_readv,
195 	.readmsg	= fi_bgq_rma_readmsg,
196 	.write		= fi_bgq_rma_write,
197 	.inject		= fi_bgq_rma_inject_write,
198 	.writev		= fi_bgq_rma_writev,
199 	.writemsg	= fi_bgq_rma_writemsg,
200 	.writedata	= fi_no_rma_writedata,
201 };
202 
fi_bgq_init_rma_ops(struct fi_bgq_ep * bgq_ep,struct fi_info * info)203 int fi_bgq_init_rma_ops(struct fi_bgq_ep *bgq_ep, struct fi_info *info)
204 {
205 	if (!bgq_ep || !info) {
206 		errno = FI_EINVAL;
207 		goto err;
208 	}
209 
210 	return 0;
211 err:
212 	return -errno;
213 }
214 
fi_bgq_enable_rma_ops(struct fi_bgq_ep * bgq_ep)215 int fi_bgq_enable_rma_ops(struct fi_bgq_ep *bgq_ep)
216 {
217 	if (!bgq_ep || !bgq_ep->domain) {
218 		errno = FI_EINVAL;
219 		goto err;
220 	}
221 
222 	if (!(bgq_ep->tx.caps & FI_RMA)) {
223 		/* rma ops not enabled on this endpoint */
224 		return 0;
225 	}
226 
227 	switch (bgq_ep->domain->threading) {
228 	case FI_THREAD_ENDPOINT:
229 	case FI_THREAD_DOMAIN:
230 	case FI_THREAD_COMPLETION:
231 		bgq_ep->ep_fid.rma = &FI_BGQ_RMA_OPS_STRUCT_NAME(0);
232 		break;
233 	case FI_THREAD_FID:
234 	case FI_THREAD_UNSPEC:
235 	case FI_THREAD_SAFE:
236 		bgq_ep->ep_fid.rma = &FI_BGQ_RMA_OPS_STRUCT_NAME(1);
237 		break;
238 	default:
239 		/*bgq_ep->ep_fid.rma = &fi_bgq_ops_rma_default;*/
240 		errno = FI_EINVAL;
241 		goto err;
242 	}
243 
244 
245 	return 0;
246 err:
247 	return -errno;
248 }
249 
fi_bgq_finalize_rma_ops(struct fi_bgq_ep * bgq_ep)250 int fi_bgq_finalize_rma_ops(struct fi_bgq_ep *bgq_ep)
251 {
252 	if (!bgq_ep) {
253 		return 0;
254 	}
255 
256 	return 0;
257 }
258