1 /**
2  * Copyright (c) UT-Battelle, LLC. 2014-2017. ALL RIGHTS RESERVED.
3  * Copyright (C) Mellanox Technologies Ltd. 2020.  ALL RIGHTS RESERVED.
4  * See file LICENSE for terms.
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #  include "config.h"
9 #endif
10 
11 #include "ugni_types.h"
12 #include "ugni_md.h"
13 #include "ugni_device.h"
14 #include "ugni_ep.h"
15 #include "ugni_iface.h"
16 
uct_ugni_iface_flush(uct_iface_h tl_iface,unsigned flags,uct_completion_t * comp)17 ucs_status_t uct_ugni_iface_flush(uct_iface_h tl_iface, unsigned flags,
18                                   uct_completion_t *comp)
19 {
20     uct_ugni_iface_t *iface = ucs_derived_of(tl_iface, uct_ugni_iface_t);
21 
22     if (comp != NULL) {
23         return UCS_ERR_UNSUPPORTED;
24     }
25 
26     if (0 == iface->outstanding) {
27         UCT_TL_IFACE_STAT_FLUSH(ucs_derived_of(tl_iface, uct_base_iface_t));
28         return UCS_OK;
29     }
30 
31     UCT_TL_IFACE_STAT_FLUSH_WAIT(ucs_derived_of(tl_iface, uct_base_iface_t));
32     return UCS_INPROGRESS;
33 }
34 
uct_ugni_iface_get_address(uct_iface_h tl_iface,uct_iface_addr_t * addr)35 ucs_status_t uct_ugni_iface_get_address(uct_iface_h tl_iface,
36                                         uct_iface_addr_t *addr)
37 {
38     uct_ugni_iface_t *iface = ucs_derived_of(tl_iface, uct_ugni_iface_t);
39     uct_sockaddr_ugni_t *iface_addr = (uct_sockaddr_ugni_t*)addr;
40 
41     iface_addr->domain_id   = iface->cdm.domain_id;
42     return UCS_OK;
43 }
44 
uct_ugni_iface_is_reachable(uct_iface_h tl_iface,const uct_device_addr_t * dev_addr,const uct_iface_addr_t * iface_addr)45 int uct_ugni_iface_is_reachable(uct_iface_h tl_iface, const uct_device_addr_t *dev_addr, const uct_iface_addr_t *iface_addr)
46 {
47     return 1;
48 }
49 
50 static ucs_mpool_ops_t uct_ugni_flush_mpool_ops = {
51     .chunk_alloc   = ucs_mpool_chunk_malloc,
52     .chunk_release = ucs_mpool_chunk_free,
53     .obj_init      = NULL,
54     .obj_cleanup   = NULL
55 };
56 
uct_ugni_cleanup_base_iface(uct_ugni_iface_t * iface)57 void uct_ugni_cleanup_base_iface(uct_ugni_iface_t *iface)
58 {
59     ucs_arbiter_cleanup(&iface->arbiter);
60     ucs_mpool_cleanup(&iface->flush_pool, 1);
61     uct_ugni_destroy_cq(iface->local_cq, &iface->cdm);
62     uct_ugni_destroy_cdm(&iface->cdm);
63 }
64 
UCS_CLASS_INIT_FUNC(uct_ugni_iface_t,uct_md_h md,uct_worker_h worker,const uct_iface_params_t * params,uct_iface_ops_t * uct_ugni_iface_ops,const uct_iface_config_t * tl_config UCS_STATS_ARG (ucs_stats_node_t * stats_parent))65 UCS_CLASS_INIT_FUNC(uct_ugni_iface_t, uct_md_h md, uct_worker_h worker,
66                     const uct_iface_params_t *params,
67                     uct_iface_ops_t *uct_ugni_iface_ops,
68                     const uct_iface_config_t *tl_config
69                     UCS_STATS_ARG(ucs_stats_node_t *stats_parent))
70 {
71     uct_ugni_device_t *dev;
72     ucs_status_t status;
73     uct_ugni_iface_config_t *config = ucs_derived_of(tl_config, uct_ugni_iface_config_t);
74     unsigned grow =  (config->mpool.bufs_grow == 0) ? 128 : config->mpool.bufs_grow;
75 
76     ucs_assert(params->open_mode & UCT_IFACE_OPEN_MODE_DEVICE);
77 
78     UCS_CLASS_CALL_SUPER_INIT(uct_base_iface_t, uct_ugni_iface_ops, md, worker,
79                               params, tl_config UCS_STATS_ARG(params->stats_root)
80                               UCS_STATS_ARG(UCT_UGNI_MD_NAME));
81     dev = uct_ugni_device_by_name(params->mode.device.dev_name);
82     if (NULL == dev) {
83         ucs_error("No device was found: %s", params->mode.device.dev_name);
84         return UCS_ERR_NO_DEVICE;
85     }
86     status = uct_ugni_create_cdm(&self->cdm, dev, self->super.worker->thread_mode);
87     if (UCS_OK != status) {
88         ucs_error("Failed to UGNI NIC, Error status: %d", status);
89         return status;
90     }
91     status = uct_ugni_create_cq(&self->local_cq, UCT_UGNI_LOCAL_CQ, &self->cdm);
92     if (UCS_OK != status) {
93         goto clean_cdm;
94     }
95     self->outstanding = 0;
96     sglib_hashed_uct_ugni_ep_t_init(self->eps);
97     ucs_arbiter_init(&self->arbiter);
98     status = ucs_mpool_init(&self->flush_pool,
99                             0,
100                             sizeof(uct_ugni_flush_group_t),
101                             0,                            /* alignment offset */
102                             UCS_SYS_CACHE_LINE_SIZE,      /* alignment */
103                             grow,                         /* grow */
104                             config->mpool.max_bufs,       /* max buffers */
105                             &uct_ugni_flush_mpool_ops,
106                             "UGNI-DESC-ONLY");
107     if (UCS_OK != status) {
108         ucs_error("Could not init iface");
109         goto clean_cq;
110     }
111     return status;
112 clean_cq:
113     uct_ugni_destroy_cq(self->local_cq, &self->cdm);
114 clean_cdm:
115     uct_ugni_destroy_cdm(&self->cdm);
116     return status;
117 }
118 
119 UCS_CLASS_DEFINE_NEW_FUNC(uct_ugni_iface_t, uct_iface_t, uct_md_h, uct_worker_h,
120                           const uct_iface_params_t*, uct_iface_ops_t *,
121                           const uct_iface_config_t * UCS_STATS_ARG(ucs_stats_node_t *));
122 
UCS_CLASS_CLEANUP_FUNC(uct_ugni_iface_t)123 static UCS_CLASS_CLEANUP_FUNC(uct_ugni_iface_t)
124 {
125     uct_ugni_cleanup_base_iface(self);
126 }
127 
128 UCS_CLASS_DEFINE(uct_ugni_iface_t, uct_base_iface_t);
129