/* * Copyright (c) 2013-2017 Intel Corporation. All rights reserved. * * This software is available to you under 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. */ #include #include #include "fabtest.h" static int ft_open_fabric(void) { int ret; if (fabric) { if (fabric_info->fabric_attr->fabric && fabric_info->fabric_attr->fabric != fabric) { printf("Opened fabric / fabric_attr mismatch\n"); return -FI_EOTHER; } return 0; } ret = fi_fabric(fabric_info->fabric_attr, &fabric, NULL); if (ret) FT_PRINTERR("fi_fabric", ret); return ret; } static int ft_open_eq(void) { struct fi_eq_attr attr; int ret; if (eq) return 0; memset(&attr, 0, sizeof attr); attr.wait_obj = test_info.eq_wait_obj; ret = fi_eq_open(fabric, &attr, &eq, NULL); if (ret) FT_PRINTERR("fi_eq_open", ret); return ret; } int ft_eq_readerr(void) { struct fi_eq_err_entry err; ssize_t ret; memset(&err, 0, sizeof(err)); ret = fi_eq_readerr(eq, &err, 0); if (ret != sizeof(err)) { FT_PRINTERR("fi_eq_readerr", ret); return ret; } else { fprintf(stderr, "Error event %d %s\n", err.err, fi_strerror(err.err)); return err.err; } } ssize_t ft_get_event(uint32_t *event, void *buf, size_t len, uint32_t event_check, size_t len_check) { ssize_t ret; switch(test_info.eq_wait_obj) { case FI_WAIT_NONE: do { ret = fi_eq_read(eq, event, buf, len, 0); if (ret == -FI_EAVAIL) { return ft_eq_readerr(); } else if (ret < 0 && ret != -FI_EAGAIN) { FT_PRINTERR("fi_eq_read", ret); return ret; } } while (ret == -FI_EAGAIN); break; case FI_WAIT_UNSPEC: case FI_WAIT_FD: case FI_WAIT_MUTEX_COND: ret = fi_eq_sread(eq, event, buf, len, FT_SREAD_TO, 0); if (ret == -FI_EAVAIL) { return ft_eq_readerr(); } else if (ret < 0) { FT_PRINTERR("fi_eq_sread", ret); return ret; } break; case FI_WAIT_SET: FT_ERR("fi_ubertest: Unsupported eq wait object"); return -1; default: FT_ERR("Unknown eq wait object"); return -1; } if (event_check && event_check != *event) { fprintf(stderr, "Unexpected event %d, wanted %d\n", *event, event_check); return -FI_ENOMSG; } if (ret < len_check) { fprintf(stderr, "Reported event too small\n"); return -FI_ETOOSMALL; } return ret; } static int ft_open_domain(void) { int ret; if (domain) { if (fabric_info->domain_attr->domain && fabric_info->domain_attr->domain != domain) { fprintf(stderr, "Opened domain / domain_attr mismatch\n"); return -FI_EDOMAIN; } return 0; } ret = fi_domain(fabric, fabric_info, &domain, NULL); if (ret) FT_PRINTERR("fi_domain", ret); return ret; } static int ft_open_av(void) { struct fi_av_attr attr; int ret; if (av) return 0; memset(&attr, 0, sizeof attr); attr.type = test_info.av_type; attr.count = 2; ret = fi_av_open(domain, &attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); return ret; } return ret; } static int ft_setup_xcontrol_bufs(struct ft_xcontrol *ctrl) { size_t size; int i, ret; uint64_t key; size = ft_ctrl.size_array[ft_ctrl.size_cnt - 1]; if (!ctrl->buf) { ret = ft_hmem_alloc(opts.iface, opts.device, &ctrl->buf, size); if (ret) return ret; ctrl->cpy_buf = calloc(1, size); if (!ctrl->buf || !ctrl->cpy_buf) return -FI_ENOMEM; key = (ctrl == &ft_tx_ctrl ? FT_TX_MR_KEY : FT_RX_MR_KEY); ret = ft_reg_mr(fabric_info, ctrl->buf, size, ft_info_to_mr_access(fabric_info), key, opts.iface, opts.device, &ctrl->mr, &ctrl->memdesc); if (ret) { FT_PRINTERR("fi_mr_reg", ret); return ret; } for (i = 0; i < ft_ctrl.iov_cnt; i++) ctrl->iov_desc[i] = ctrl->memdesc; } else { ft_hmem_memset(opts.iface, opts.device, ctrl->buf, 0, size); } return 0; } static int ft_setup_atomic_control(struct ft_atomic_control *ctrl) { size_t size; int ret = 0; uint64_t access; size = ft_ctrl.size_array[ft_ctrl.size_cnt - 1]; if (!ctrl->res_buf) { ctrl->res_buf = calloc(1, size); if (!ctrl->res_buf) return -FI_ENOMEM; } else { memset(ctrl->res_buf, 0, size); } if (!ctrl->comp_buf) { ctrl->comp_buf = calloc(1, size); if (!ctrl->comp_buf) return -FI_ENOMEM; } else { memset(ctrl->comp_buf, 0, size); } if (!ctrl->orig_buf) { ctrl->orig_buf = calloc(1, size); if (!ctrl->orig_buf) return -FI_ENOMEM; } else { memset(ctrl->orig_buf, 0, size); } if (fabric_info->domain_attr->mr_mode & FI_MR_LOCAL) { access = FI_READ | FI_WRITE | FI_REMOTE_READ | FI_REMOTE_WRITE; if (!ctrl->res_mr) { ret = fi_mr_reg(domain, ctrl->res_buf, size, access, 0, 0, 0, &ctrl->res_mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); return ret; } ctrl->res_memdesc = fi_mr_desc(ctrl->res_mr); } if (!ctrl->comp_mr) { ret = fi_mr_reg(domain, ctrl->comp_buf, size, access, 0, 0, 0, &ctrl->comp_mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); return ret; } ctrl->comp_memdesc = fi_mr_desc(ctrl->comp_mr); } } ft_atom_ctrl.op = test_info.op; ft_atom_ctrl.datatype = test_info.datatype; return ret; } static int ft_setup_mr_control(struct ft_mr_control *ctrl) { size_t size; int ret; uint64_t access; if (!(fabric_info->caps & (FI_RMA | FI_ATOMIC))) return 0; size = ft_ctrl.size_array[ft_ctrl.size_cnt - 1]; if (!ctrl->buf) { ctrl->buf = calloc(1, size); if (!ctrl->buf) return -FI_ENOMEM; } else { memset(ctrl->buf, 0, size); } if (!ctrl->mr) { access = FI_READ | FI_WRITE | FI_REMOTE_READ | FI_REMOTE_WRITE; ret = fi_mr_reg(domain, ctrl->buf, size, access, 0, FT_MR_KEY, 0, &ctrl->mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); return ret; } ctrl->memdesc = fi_mr_desc(ctrl->mr); ctrl->peer_mr_key = ctrl->mr_key = fi_mr_key(ctrl->mr); } return 0; } static int ft_setup_bufs(void) { int ret; ret = ft_setup_xcontrol_bufs(&ft_rx_ctrl); if (ret) return ret; ret = ft_setup_xcontrol_bufs(&ft_tx_ctrl); if (ret) return ret; ret = ft_hmem_alloc_host(opts.iface, &dev_host_buf, ft_ctrl.size_array[ft_ctrl.size_cnt - 1]); if (ret) return ret; ret = ft_setup_mr_control(&ft_mr_ctrl); if (ret) return ret; ret = ft_setup_atomic_control(&ft_atom_ctrl); if (ret) return ret; return 0; } int ft_open_control(void) { int ret; ret = ft_open_fabric(); if (ret) return ret; ret = ft_open_eq(); if (ret) return ret; ret = ft_open_domain(); if (ret) return ret; ret = ft_setup_bufs(); if (ret) return ret; if (test_info.ep_type != FI_EP_MSG) { ret = ft_open_av(); if (ret) return ret; } return 0; }