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