1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
|
/*
* Copyright (c) 2018-2019 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL); Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _OFI_HOOK_H_
#define _OFI_HOOK_H_
#include <assert.h>
#include <rdma/fabric.h>
#include <rdma/fi_atomic.h>
#include <rdma/fi_collective.h>
#include <rdma/fi_cm.h>
#include <rdma/fi_domain.h>
#include <rdma/fi_endpoint.h>
#include <rdma/fi_eq.h>
#include <rdma/fi_rma.h>
#include <rdma/fi_tagged.h>
#include <ofi.h>
#include <rdma/providers/fi_prov.h>
/* This field needs to be updated whenever new FI class is added in fabric.h */
#define HOOK_FI_CLASS_MAX (FI_CLASS_NIC + 1)
/*
* Hooks are installed from top down.
* Values must start at 0 and increment by one.
*/
// TODO figure out how to remove this now that we have ini/fini calls
enum ofi_hook_class {
HOOK_NOOP,
HOOK_PERF,
HOOK_TRACE,
HOOK_PROFILE,
HOOK_DEBUG,
HOOK_HMEM,
HOOK_DMABUF_PEER_MEM,
};
/*
* Default fi_ops members, can be used to construct custom fi_ops
*/
int hook_close(struct fid *fid);
int hook_bind(struct fid *fid, struct fid *bfid, uint64_t flags);
int hook_control(struct fid *fid, int command, void *arg);
int hook_ops_open(struct fid *fid, const char *name,
uint64_t flags, void **ops, void *context);
/*
* Define hook structs so we can cast from fid to parent using simple cast.
* This lets us have a single close() call.
*/
extern struct fi_ops hook_fid_ops;
struct fid *hook_to_hfid(const struct fid *fid);
struct fid_wait *hook_to_hwait(const struct fid_wait *wait);
/*
* TODO
* comment from GitHub PR #5052:
* "another option would be to store the ini/fini calls in a separate structure
* that we reference from struct ofi_prov_context. We could even extend the
* definition of ofi_prov_context with a union that is accessed based on the
* prov_type. That might work better if we want to support external hooks,
* without the external hook provider needing to implement everything"
*/
struct hook_prov_ctx {
struct fi_provider prov;
/*
* Hooking providers can override ini/fini calls of a specific fid class
* to override any initializations that the common code may have done.
* For example, this allows overriding any specific op and not having to
* hook into every resource creation call until the point where the op
* can be overridden. Refer to hook_perf for an example.
*
* Note: if a hooking provider overrides any of the resource creation calls
* (e.g. fi_endpoint) directly, then these ini/fini calls won't be
* invoked. */
int (*ini_fid[HOOK_FI_CLASS_MAX])(struct fid *fid);
int (*fini_fid[HOOK_FI_CLASS_MAX])(struct fid *fid);
};
/*
* TODO
* comment from GitHub PR #5052:
* "We could set all ini/fini calls to a no-op as part of hook initialization
* to avoid this check"
*/
static inline int hook_ini_fid(struct hook_prov_ctx *prov_ctx, struct fid *fid)
{
return (prov_ctx->ini_fid[fid->fclass] ?
prov_ctx->ini_fid[fid->fclass](fid) : 0);
}
static inline int hook_fini_fid(struct hook_prov_ctx *prov_ctx, struct fid *fid)
{
return (prov_ctx->fini_fid[fid->fclass] ?
prov_ctx->fini_fid[fid->fclass](fid) : 0);
}
struct hook_fabric {
struct fid_fabric fabric;
struct fid_fabric *hfabric;
enum ofi_hook_class hclass;
struct fi_provider *hprov;
struct hook_prov_ctx *prov_ctx;
};
void hook_fabric_init(struct hook_fabric *fabric, enum ofi_hook_class hclass,
struct fid_fabric *hfabric, struct fi_provider *hprov,
struct fi_ops *f_ops, struct hook_prov_ctx *prov_ctx);
struct hook_fabric *hook_to_fabric(const struct fid *fid);
static inline struct hook_prov_ctx *hook_to_prov_ctx(const struct fid *fid)
{
return (hook_to_fabric(fid))->prov_ctx;
}
static inline struct fi_provider *
hook_fabric_to_hprov(const struct hook_fabric *fabric)
{
return fabric->hprov;
}
static inline struct fi_provider *hook_to_hprov(const struct fid *fid)
{
return hook_fabric_to_hprov(hook_to_fabric(fid));
}
struct ofi_ops_flow_ctrl;
struct hook_domain {
struct fid_domain domain;
struct fid_domain *hdomain;
struct hook_fabric *fabric;
struct ofi_ops_flow_ctrl *base_ops_flow_ctrl;
ssize_t (*base_credit_handler)(struct fid_ep *ep_fid, uint64_t credits);
};
int hook_domain_init(struct fid_fabric *fabric, struct fi_info *info,
struct fid_domain **domain, void *context,
struct hook_domain *dom);
int hook_domain(struct fid_fabric *fabric, struct fi_info *info,
struct fid_domain **domain, void *context);
struct hook_av {
struct fid_av av;
struct fid_av *hav;
struct hook_domain *domain;
};
int hook_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
struct fid_av **av, void *context);
struct hook_wait {
struct fid_wait wait;
struct fid_wait *hwait;
struct hook_fabric *fabric;
};
int hook_wait_open(struct fid_fabric *fabric, struct fi_wait_attr *attr,
struct fid_wait **waitset);
int hook_trywait(struct fid_fabric *fabric, struct fid **fids, int count);
struct hook_poll {
struct fid_poll poll;
struct fid_poll *hpoll;
struct hook_domain *domain;
};
int hook_poll_open(struct fid_domain *domain, struct fi_poll_attr *attr,
struct fid_poll **pollset);
/*
* EQ
*/
extern struct fi_ops_eq hook_eq_ops;
struct hook_eq {
struct fid_eq eq;
struct fid_eq *heq;
struct hook_fabric *fabric;
};
ssize_t hook_eq_read(struct fid_eq *eq, uint32_t *event,
void *buf, size_t len, uint64_t flags);
ssize_t hook_eq_sread(struct fid_eq *eq, uint32_t *event,
void *buf, size_t len, int timeout, uint64_t flags);
int hook_eq_init(struct fid_fabric *fabric, struct fi_eq_attr *attr,
struct fid_eq **eq, void *context, struct hook_eq *myeq);
int hook_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
struct fid_eq **eq, void *context);
/*
* CQ
*/
struct hook_cq {
struct fid_cq cq;
struct fid_cq *hcq;
struct hook_domain *domain;
void *context;
enum fi_cq_format format;
};
int hook_cq_init(struct fid_domain *domain, struct fi_cq_attr *attr,
struct fid_cq **cq, void *context, struct hook_cq *mycq);
int hook_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr,
struct fid_cq **cq, void *context);
const char *
hook_cq_strerror(struct fid_cq *cq, int prov_errno,
const void *err_data, char *buf, size_t len);
struct hook_cntr {
struct fid_cntr cntr;
struct fid_cntr *hcntr;
struct hook_domain *domain;
};
int hook_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr,
struct fid_cntr **cntr, void *context);
struct hook_ep {
struct fid_ep ep;
struct fid_ep *hep;
struct hook_domain *domain;
void *context;
};
int hook_endpoint_init(struct fid_domain *domain, struct fi_info *info,
struct fid_ep **ep, void *context, struct hook_ep *myep);
int hook_endpoint(struct fid_domain *domain, struct fi_info *info,
struct fid_ep **ep, void *context);
int hook_scalable_ep(struct fid_domain *domain, struct fi_info *info,
struct fid_ep **sep, void *context);
int hook_srx_ctx(struct fid_domain *domain,
struct fi_rx_attr *attr, struct fid_ep **rx_ep,
void *context);
int hook_query_atomic(struct fid_domain *domain, enum fi_datatype datatype,
enum fi_op op, struct fi_atomic_attr *attr, uint64_t flags);
int hook_query_collective(struct fid_domain *domain, enum fi_collective_op coll,
struct fi_collective_attr *attr, uint64_t flags);
extern struct fi_ops hook_fabric_fid_ops;
extern struct fi_ops hook_domain_fid_ops;
extern struct fi_ops_fabric hook_fabric_ops;
extern struct fi_ops_domain hook_domain_ops;
extern struct fi_ops_cq hook_cq_ops;
extern struct fi_ops_cntr hook_cntr_ops;
extern struct fi_ops_cm hook_cm_ops;
extern struct fi_ops_msg hook_msg_ops;
extern struct fi_ops_rma hook_rma_ops;
extern struct fi_ops_tagged hook_tagged_ops;
extern struct fi_ops_atomic hook_atomic_ops;
struct hook_pep {
struct fid_pep pep;
struct fid_pep *hpep;
struct hook_fabric *fabric;
};
int hook_passive_ep(struct fid_fabric *fabric, struct fi_info *info,
struct fid_pep **pep, void *context);
struct hook_stx {
struct fid_stx stx;
struct fid_stx *hstx;
struct hook_domain *domain;
};
int hook_stx_ctx(struct fid_domain *domain,
struct fi_tx_attr *attr, struct fid_stx **stx,
void *context);
struct hook_mr {
struct fid_mr mr;
struct fid_mr *hmr;
struct hook_domain *domain;
};
#endif /* _OFI_HOOK_H_ */
|