1 /*
2 * Copyright (c) 2013-2017 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 #include "psmx.h"
34
35 struct psmx_fid_fabric *psmx_active_fabric = NULL;
36
psmx_fabric_close(fid_t fid)37 static int psmx_fabric_close(fid_t fid)
38 {
39 struct psmx_fid_fabric *fabric;
40
41 fabric = container_of(fid, struct psmx_fid_fabric,
42 util_fabric.fabric_fid.fid);
43
44 FI_INFO(&psmx_prov, FI_LOG_CORE, "refcnt=%d\n",
45 ofi_atomic_get32(&fabric->util_fabric.ref));
46
47 if (psmx_env.name_server)
48 ofi_ns_stop_server(&fabric->name_server);
49
50 psmx_fabric_release(fabric);
51
52 if (ofi_fabric_close(&fabric->util_fabric))
53 return 0;
54
55 if (fabric->active_domain) {
56 FI_WARN(&psmx_prov, FI_LOG_CORE, "forced closing of active_domain\n");
57 fi_close(&fabric->active_domain->util_domain.domain_fid.fid);
58 }
59 assert(fabric == psmx_active_fabric);
60 psmx_active_fabric = NULL;
61 free(fabric);
62
63 return 0;
64 }
65
66 static struct fi_ops psmx_fabric_fi_ops = {
67 .size = sizeof(struct fi_ops),
68 .close = psmx_fabric_close,
69 };
70
71 static struct fi_ops_fabric psmx_fabric_ops = {
72 .size = sizeof(struct fi_ops_fabric),
73 .domain = psmx_domain_open,
74 .passive_ep = fi_no_passive_ep,
75 .eq_open = ofi_eq_create,
76 .wait_open = psmx_wait_open,
77 .trywait = psmx_wait_trywait,
78 };
79
80 static struct fi_fabric_attr psmx_fabric_attr = {
81 .name = PSMX_FABRIC_NAME,
82 .prov_version = OFI_VERSION_DEF_PROV,
83 };
84
psmx_fabric(struct fi_fabric_attr * attr,struct fid_fabric ** fabric,void * context)85 int psmx_fabric(struct fi_fabric_attr *attr,
86 struct fid_fabric **fabric, void *context)
87 {
88 struct psmx_fid_fabric *fabric_priv;
89 int ret;
90
91 FI_INFO(&psmx_prov, FI_LOG_CORE, "\n");
92
93 if (strcmp(attr->name, PSMX_FABRIC_NAME))
94 return -FI_ENODATA;
95
96 if (psmx_active_fabric) {
97 psmx_fabric_acquire(psmx_active_fabric);
98 *fabric = &psmx_active_fabric->util_fabric.fabric_fid;
99 return 0;
100 }
101
102 fabric_priv = calloc(1, sizeof(*fabric_priv));
103 if (!fabric_priv)
104 return -FI_ENOMEM;
105
106 psmx_get_uuid(fabric_priv->uuid);
107 if (psmx_env.name_server) {
108 fabric_priv->name_server.port = psmx_uuid_to_port(fabric_priv->uuid);
109 fabric_priv->name_server.name_len = sizeof(psm_epid_t);
110 fabric_priv->name_server.service_len = sizeof(int);
111 fabric_priv->name_server.service_cmp = psmx_ns_service_cmp;
112 fabric_priv->name_server.is_service_wildcard = psmx_ns_is_service_wildcard;
113
114 ofi_ns_init(&fabric_priv->name_server);
115 ofi_ns_start_server(&fabric_priv->name_server);
116 }
117
118 ret = ofi_fabric_init(&psmx_prov, &psmx_fabric_attr, attr,
119 &fabric_priv->util_fabric, context);
120 if (ret) {
121 FI_INFO(&psmx_prov, FI_LOG_CORE, "ofi_fabric_init returns %d\n", ret);
122 if (psmx_env.name_server)
123 ofi_ns_stop_server(&fabric_priv->name_server);
124 free(fabric_priv);
125 return ret;
126 }
127
128 /* fclass & context initialzied in ofi_fabric_init */
129 fabric_priv->util_fabric.fabric_fid.fid.ops = &psmx_fabric_fi_ops;
130 fabric_priv->util_fabric.fabric_fid.ops = &psmx_fabric_ops;
131
132 psmx_query_mpi();
133
134 /* take the reference to count for multiple fabric open calls */
135 psmx_fabric_acquire(fabric_priv);
136
137 *fabric = &fabric_priv->util_fabric.fabric_fid;
138 psmx_active_fabric = fabric_priv;
139
140 return 0;
141 }
142
143