1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2015. ALL RIGHTS RESERVED.
3 * Copyright (c) UT-Battelle, LLC. 2014-2015. ALL RIGHTS RESERVED.
4 *
5 * See file LICENSE for terms.
6 */
7
8 #ifdef HAVE_CONFIG_H
9 # include "config.h"
10 #endif
11
12 #include "mm_md.h"
13
14 #include <ucs/debug/log.h>
15 #include <inttypes.h>
16 #include <limits.h>
17
18
19 ucs_config_field_t uct_mm_md_config_table[] = {
20 {"", "", NULL,
21 ucs_offsetof(uct_mm_md_config_t, super), UCS_CONFIG_TYPE_TABLE(uct_md_config_table)},
22
23 {"HUGETLB_MODE", "try",
24 "Enable using huge pages for internal buffers. "
25 "Possible values are:\n"
26 " y - Allocate memory using huge pages only.\n"
27 " n - Allocate memory using regular pages only.\n"
28 " try - Try to allocate memory using huge pages and if it fails, allocate regular pages.\n",
29 ucs_offsetof(uct_mm_md_config_t, hugetlb_mode), UCS_CONFIG_TYPE_TERNARY},
30
31 {NULL}
32 };
33
uct_mm_query_md_resources(uct_component_t * component,uct_md_resource_desc_t ** resources_p,unsigned * num_resources_p)34 ucs_status_t uct_mm_query_md_resources(uct_component_t *component,
35 uct_md_resource_desc_t **resources_p,
36 unsigned *num_resources_p)
37 {
38 ucs_status_t status;
39
40 status = uct_mm_mdc_mapper_ops(component)->query();
41 switch (status) {
42 case UCS_OK:
43 return uct_md_query_single_md_resource(component, resources_p,
44 num_resources_p);
45 case UCS_ERR_UNSUPPORTED:
46 return uct_md_query_empty_md_resource(resources_p, num_resources_p);
47 default:
48 return status;
49 }
50 }
51
uct_mm_seg_new(void * address,size_t length,uct_mm_seg_t ** seg_p)52 ucs_status_t uct_mm_seg_new(void *address, size_t length, uct_mm_seg_t **seg_p)
53 {
54 uct_mm_seg_t *seg;
55
56 seg = ucs_malloc(sizeof(*seg), "mm_seg");
57 if (seg == NULL) {
58 ucs_error("failed to allocate mm segment");
59 return UCS_ERR_NO_MEMORY;
60 }
61
62 seg->address = address;
63 seg->length = length;
64 seg->seg_id = 0;
65 *seg_p = seg;
66 return UCS_OK;
67 }
68
uct_mm_md_query(uct_md_h md,uct_md_attr_t * md_attr,int support_alloc)69 void uct_mm_md_query(uct_md_h md, uct_md_attr_t *md_attr, int support_alloc)
70 {
71 memset(md_attr, 0, sizeof(*md_attr));
72
73 md_attr->cap.flags = UCT_MD_FLAG_RKEY_PTR |
74 UCT_MD_FLAG_NEED_RKEY;
75 md_attr->cap.max_reg = 0;
76 md_attr->cap.max_alloc = 0;
77 md_attr->cap.access_mem_type = UCS_MEMORY_TYPE_HOST;
78 md_attr->cap.detect_mem_types = 0;
79
80 if (support_alloc) {
81 md_attr->cap.flags |= UCT_MD_FLAG_ALLOC | UCT_MD_FLAG_FIXED;
82 md_attr->cap.max_alloc = ULONG_MAX;
83 }
84
85 memset(&md_attr->local_cpus, 0xff, sizeof(md_attr->local_cpus));
86 }
87
uct_mm_rkey_ptr(uct_component_t * component,uct_rkey_t rkey,void * handle,uint64_t raddr,void ** laddr_p)88 ucs_status_t uct_mm_rkey_ptr(uct_component_t *component, uct_rkey_t rkey,
89 void *handle, uint64_t raddr, void **laddr_p)
90 {
91 /* rkey stores offset from the remote va */
92 *laddr_p = UCS_PTR_BYTE_OFFSET(raddr, (ptrdiff_t)rkey);
93 return UCS_OK;
94 }
95
uct_mm_md_open(uct_component_t * component,const char * md_name,const uct_md_config_t * config,uct_md_h * md_p)96 ucs_status_t uct_mm_md_open(uct_component_t *component, const char *md_name,
97 const uct_md_config_t *config, uct_md_h *md_p)
98 {
99 uct_mm_component_t *mmc = ucs_derived_of(component, uct_mm_component_t);
100 ucs_status_t status;
101 uct_mm_md_t *md;
102
103 md = ucs_malloc(sizeof(*md), "uct_mm_md_t");
104 if (md == NULL) {
105 ucs_error("Failed to allocate memory for uct_mm_md_t");
106 status = UCS_ERR_NO_MEMORY;
107 goto err;
108 }
109
110 md->config = ucs_malloc(mmc->super.md_config.size, "mm_md config");
111 if (md->config == NULL) {
112 ucs_error("Failed to allocate memory for mm_md config");
113 status = UCS_ERR_NO_MEMORY;
114 goto err_free_mm_md;
115 }
116
117 status = ucs_config_parser_clone_opts(config, md->config,
118 mmc->super.md_config.table);
119 if (status != UCS_OK) {
120 ucs_error("Failed to clone opts");
121 goto err_free_mm_md_config;
122 }
123
124 md->super.ops = &mmc->md_ops->super;
125 md->super.component = &mmc->super;
126 md->iface_addr_len = mmc->md_ops->iface_addr_length(md);
127
128 /* cppcheck-suppress autoVariables */
129 *md_p = &md->super;
130 return UCS_OK;
131
132 err_free_mm_md_config:
133 ucs_free(md->config);
134 err_free_mm_md:
135 ucs_free(md);
136 err:
137 return status;
138 }
139
uct_mm_md_close(uct_md_h md)140 void uct_mm_md_close(uct_md_h md)
141 {
142 uct_mm_md_t *mm_md = ucs_derived_of(md, uct_mm_md_t);
143
144 ucs_config_parser_release_opts(mm_md->config,
145 md->component->md_config.table);
146 ucs_free(mm_md->config);
147 ucs_free(mm_md);
148 }
149