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