1 /*
2  * Copyright (c) 2013-2014 Intel Corporation. All rights reserved.
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 
33 #ifndef FI_ATOMIC_H
34 #define FI_ATOMIC_H
35 
36 #include <rdma/fabric.h>
37 #include <rdma/fi_endpoint.h>
38 #include <rdma/fi_rma.h>
39 
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 
46 /* Atomic flags */
47 #define FI_FETCH_ATOMIC		(1ULL << 58)
48 #define FI_COMPARE_ATOMIC	(1ULL << 59)
49 
50 struct fi_atomic_attr {
51 	size_t			count;
52 	size_t			size;
53 };
54 
55 struct fi_msg_atomic {
56 	const struct fi_ioc	*msg_iov;
57 	void			**desc;
58 	size_t			iov_count;
59 	fi_addr_t		addr;
60 	const struct fi_rma_ioc	*rma_iov;
61 	size_t			rma_iov_count;
62 	enum fi_datatype	datatype;
63 	enum fi_op		op;
64 	void			*context;
65 	uint64_t		data;
66 };
67 
68 struct fi_msg_fetch {
69 	struct fi_ioc		*msg_iov;
70 	void			**desc;
71 	size_t			iov_count;
72 };
73 
74 struct fi_msg_compare {
75 	const struct fi_ioc	*msg_iov;
76 	void			**desc;
77 	size_t			iov_count;
78 };
79 
80 struct fi_ops_atomic {
81 	size_t	size;
82 	ssize_t	(*write)(struct fid_ep *ep,
83 			const void *buf, size_t count, void *desc,
84 			fi_addr_t dest_addr,
85 			uint64_t addr, uint64_t key,
86 			enum fi_datatype datatype, enum fi_op op, void *context);
87 	ssize_t	(*writev)(struct fid_ep *ep,
88 			const struct fi_ioc *iov, void **desc, size_t count,
89 			fi_addr_t dest_addr,
90 			uint64_t addr, uint64_t key,
91 			enum fi_datatype datatype, enum fi_op op, void *context);
92 	ssize_t	(*writemsg)(struct fid_ep *ep,
93 			const struct fi_msg_atomic *msg, uint64_t flags);
94 	ssize_t	(*inject)(struct fid_ep *ep, const void *buf, size_t count,
95 			fi_addr_t dest_addr, uint64_t addr, uint64_t key,
96 			enum fi_datatype datatype, enum fi_op op);
97 
98 	ssize_t	(*readwrite)(struct fid_ep *ep,
99 			const void *buf, size_t count, void *desc,
100 			void *result, void *result_desc,
101 			fi_addr_t dest_addr,
102 			uint64_t addr, uint64_t key,
103 			enum fi_datatype datatype, enum fi_op op, void *context);
104 	ssize_t	(*readwritev)(struct fid_ep *ep,
105 			const struct fi_ioc *iov, void **desc, size_t count,
106 			struct fi_ioc *resultv, void **result_desc, size_t result_count,
107 			fi_addr_t dest_addr,
108 			uint64_t addr, uint64_t key,
109 			enum fi_datatype datatype, enum fi_op op, void *context);
110 	ssize_t	(*readwritemsg)(struct fid_ep *ep,
111 			const struct fi_msg_atomic *msg,
112 			struct fi_ioc *resultv, void **result_desc, size_t result_count,
113 			uint64_t flags);
114 
115 	ssize_t	(*compwrite)(struct fid_ep *ep,
116 			const void *buf, size_t count, void *desc,
117 			const void *compare, void *compare_desc,
118 			void *result, void *result_desc,
119 			fi_addr_t dest_addr,
120 			uint64_t addr, uint64_t key,
121 			enum fi_datatype datatype, enum fi_op op, void *context);
122 	ssize_t	(*compwritev)(struct fid_ep *ep,
123 			const struct fi_ioc *iov, void **desc, size_t count,
124 			const struct fi_ioc *comparev, void **compare_desc, size_t compare_count,
125 			struct fi_ioc *resultv, void **result_desc, size_t result_count,
126 			fi_addr_t dest_addr,
127 			uint64_t addr, uint64_t key,
128 			enum fi_datatype datatype, enum fi_op op, void *context);
129 	ssize_t	(*compwritemsg)(struct fid_ep *ep,
130 			const struct fi_msg_atomic *msg,
131 			const struct fi_ioc *comparev, void **compare_desc, size_t compare_count,
132 			struct fi_ioc *resultv, void **result_desc, size_t result_count,
133 			uint64_t flags);
134 
135 	int	(*writevalid)(struct fid_ep *ep,
136 			enum fi_datatype datatype, enum fi_op op, size_t *count);
137 	int	(*readwritevalid)(struct fid_ep *ep,
138 			enum fi_datatype datatype, enum fi_op op, size_t *count);
139 	int	(*compwritevalid)(struct fid_ep *ep,
140 			enum fi_datatype datatype, enum fi_op op, size_t *count);
141 };
142 
143 #ifdef FABRIC_DIRECT
144 #include <rdma/fi_direct_atomic.h>
145 #endif	/* FABRIC_DIRECT */
146 
147 #ifndef FABRIC_DIRECT_ATOMIC
148 
149 static inline ssize_t
fi_atomic(struct fid_ep * ep,const void * buf,size_t count,void * desc,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)150 fi_atomic(struct fid_ep *ep,
151 	  const void *buf, size_t count, void *desc,
152 	  fi_addr_t dest_addr,
153 	  uint64_t addr, uint64_t key,
154 	  enum fi_datatype datatype, enum fi_op op, void *context)
155 {
156 	return ep->atomic->write(ep, buf, count, desc, dest_addr, addr, key,
157 			datatype, op, context);
158 }
159 
160 static inline ssize_t
fi_atomicv(struct fid_ep * ep,const struct fi_ioc * iov,void ** desc,size_t count,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)161 fi_atomicv(struct fid_ep *ep,
162 	   const struct fi_ioc *iov, void **desc, size_t count,
163 	   fi_addr_t dest_addr,
164 	   uint64_t addr, uint64_t key,
165 	   enum fi_datatype datatype, enum fi_op op, void *context)
166 {
167 	return ep->atomic->writev(ep, iov, desc, count, dest_addr, addr, key,
168 			datatype, op, context);
169 }
170 
171 static inline ssize_t
fi_atomicmsg(struct fid_ep * ep,const struct fi_msg_atomic * msg,uint64_t flags)172 fi_atomicmsg(struct fid_ep *ep,
173 	     const struct fi_msg_atomic *msg, uint64_t flags)
174 {
175 	return ep->atomic->writemsg(ep, msg, flags);
176 }
177 
178 static inline ssize_t
fi_inject_atomic(struct fid_ep * ep,const void * buf,size_t count,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op)179 fi_inject_atomic(struct fid_ep *ep, const void *buf, size_t count,
180 		 fi_addr_t dest_addr, uint64_t addr, uint64_t key,
181 		 enum fi_datatype datatype, enum fi_op op)
182 {
183 	return ep->atomic->inject(ep, buf, count, dest_addr, addr,
184 			key, datatype, op);
185 }
186 
187 static inline ssize_t
fi_fetch_atomic(struct fid_ep * ep,const void * buf,size_t count,void * desc,void * result,void * result_desc,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)188 fi_fetch_atomic(struct fid_ep *ep,
189 		const void *buf, size_t count, void *desc,
190 		void *result, void *result_desc,
191 		fi_addr_t dest_addr,
192 		uint64_t addr, uint64_t key,
193 		enum fi_datatype datatype, enum fi_op op, void *context)
194 {
195 	return ep->atomic->readwrite(ep, buf, count, desc, result, result_desc,
196 			dest_addr, addr, key, datatype, op, context);
197 }
198 
199 static inline ssize_t
fi_fetch_atomicv(struct fid_ep * ep,const struct fi_ioc * iov,void ** desc,size_t count,struct fi_ioc * resultv,void ** result_desc,size_t result_count,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)200 fi_fetch_atomicv(struct fid_ep *ep,
201 		 const struct fi_ioc *iov, void **desc, size_t count,
202 		 struct fi_ioc *resultv, void **result_desc, size_t result_count,
203 		 fi_addr_t dest_addr,
204 		 uint64_t addr, uint64_t key,
205 		 enum fi_datatype datatype, enum fi_op op, void *context)
206 {
207 	return ep->atomic->readwritev(ep, iov, desc, count,
208 			resultv, result_desc, result_count,
209 			dest_addr, addr, key, datatype, op, context);
210 }
211 
212 static inline ssize_t
fi_fetch_atomicmsg(struct fid_ep * ep,const struct fi_msg_atomic * msg,struct fi_ioc * resultv,void ** result_desc,size_t result_count,uint64_t flags)213 fi_fetch_atomicmsg(struct fid_ep *ep,
214 		   const struct fi_msg_atomic *msg,
215 		   struct fi_ioc *resultv, void **result_desc, size_t result_count,
216 		   uint64_t flags)
217 {
218 	return ep->atomic->readwritemsg(ep, msg, resultv, result_desc,
219 			result_count, flags);
220 }
221 
222 static inline ssize_t
fi_compare_atomic(struct fid_ep * ep,const void * buf,size_t count,void * desc,const void * compare,void * compare_desc,void * result,void * result_desc,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)223 fi_compare_atomic(struct fid_ep *ep,
224 		  const void *buf, size_t count, void *desc,
225 		  const void *compare, void *compare_desc,
226 		  void *result, void *result_desc,
227 		  fi_addr_t dest_addr,
228 		  uint64_t addr, uint64_t key,
229 		  enum fi_datatype datatype, enum fi_op op, void *context)
230 {
231 	return ep->atomic->compwrite(ep, buf, count, desc,
232 			compare, compare_desc, result, result_desc,
233 			dest_addr, addr, key, datatype, op, context);
234 }
235 
236 static inline ssize_t
fi_compare_atomicv(struct fid_ep * ep,const struct fi_ioc * iov,void ** desc,size_t count,const struct fi_ioc * comparev,void ** compare_desc,size_t compare_count,struct fi_ioc * resultv,void ** result_desc,size_t result_count,fi_addr_t dest_addr,uint64_t addr,uint64_t key,enum fi_datatype datatype,enum fi_op op,void * context)237 fi_compare_atomicv(struct fid_ep *ep,
238 		   const struct fi_ioc *iov, void **desc, size_t count,
239 		   const struct fi_ioc *comparev, void **compare_desc, size_t compare_count,
240 		   struct fi_ioc *resultv, void **result_desc, size_t result_count,
241 		   fi_addr_t dest_addr,
242 		   uint64_t addr, uint64_t key,
243 		   enum fi_datatype datatype, enum fi_op op, void *context)
244 {
245 	return ep->atomic->compwritev(ep, iov, desc, count,
246 			comparev, compare_desc, compare_count,
247 			resultv, result_desc, result_count,
248 			dest_addr, addr, key, datatype, op, context);
249 }
250 
251 static inline ssize_t
fi_compare_atomicmsg(struct fid_ep * ep,const struct fi_msg_atomic * msg,const struct fi_ioc * comparev,void ** compare_desc,size_t compare_count,struct fi_ioc * resultv,void ** result_desc,size_t result_count,uint64_t flags)252 fi_compare_atomicmsg(struct fid_ep *ep,
253 		     const struct fi_msg_atomic *msg,
254 		     const struct fi_ioc *comparev, void **compare_desc, size_t compare_count,
255 		     struct fi_ioc *resultv, void **result_desc, size_t result_count,
256 		     uint64_t flags)
257 {
258 	return ep->atomic->compwritemsg(ep, msg,
259 			comparev, compare_desc, compare_count,
260 			resultv, result_desc, result_count, flags);
261 }
262 
263 static inline int
fi_atomicvalid(struct fid_ep * ep,enum fi_datatype datatype,enum fi_op op,size_t * count)264 fi_atomicvalid(struct fid_ep *ep,
265 	       enum fi_datatype datatype, enum fi_op op, size_t *count)
266 {
267 	return ep->atomic->writevalid(ep, datatype, op, count);
268 }
269 
270 static inline int
fi_fetch_atomicvalid(struct fid_ep * ep,enum fi_datatype datatype,enum fi_op op,size_t * count)271 fi_fetch_atomicvalid(struct fid_ep *ep,
272 		     enum fi_datatype datatype, enum fi_op op, size_t *count)
273 {
274 	return ep->atomic->readwritevalid(ep, datatype, op, count);
275 }
276 
277 static inline int
fi_compare_atomicvalid(struct fid_ep * ep,enum fi_datatype datatype,enum fi_op op,size_t * count)278 fi_compare_atomicvalid(struct fid_ep *ep,
279 		       enum fi_datatype datatype, enum fi_op op, size_t *count)
280 {
281 	return ep->atomic->compwritevalid(ep, datatype, op, count);
282 }
283 
284 static inline int
fi_query_atomic(struct fid_domain * domain,enum fi_datatype datatype,enum fi_op op,struct fi_atomic_attr * attr,uint64_t flags)285 fi_query_atomic(struct fid_domain *domain,
286 		enum fi_datatype datatype, enum fi_op op,
287 		struct fi_atomic_attr *attr, uint64_t flags)
288 {
289 	return FI_CHECK_OP(domain->ops, struct fi_ops_domain, query_atomic) ?
290 		domain->ops->query_atomic(domain, datatype, op, attr, flags) :
291 		-FI_ENOSYS;
292 }
293 
294 #endif
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif /* FI_ATOMIC_H */
301