1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2015. ALL RIGHTS RESERVED.
3 *
4 * See file LICENSE for terms.
5 */
6
7 #include "uct_test.h"
8
9 #include <ucs/sys/sys.h>
10
11
12 class test_mem : public testing::TestWithParam<uct_alloc_method_t>,
13 public uct_test_base {
14 public:
15 UCS_TEST_BASE_IMPL;
16
init()17 virtual void init() {
18 ucs::skip_on_address_sanitizer();
19 uct_test_base::init();
20 }
21
22 protected:
23
check_mem(const uct_allocated_memory & mem,size_t min_length)24 void check_mem(const uct_allocated_memory &mem, size_t min_length) {
25 EXPECT_TRUE(mem.address != 0);
26 EXPECT_GE(mem.length, min_length);
27 if (mem.method == UCT_ALLOC_METHOD_MD) {
28 EXPECT_TRUE(mem.md != NULL);
29 EXPECT_TRUE(mem.memh != UCT_MEM_HANDLE_NULL);
30 } else {
31 EXPECT_TRUE((mem.method == GetParam()) ||
32 (mem.method == UCT_ALLOC_METHOD_HEAP));
33 }
34 }
35
36 static const size_t min_length = 1234557;
37 };
38
39
UCS_TEST_P(test_mem,nomd_alloc)40 UCS_TEST_P(test_mem, nomd_alloc) {
41 uct_alloc_method_t methods[2];
42 uct_allocated_memory mem;
43 ucs_status_t status;
44
45 methods[0] = GetParam();
46 methods[1] = UCT_ALLOC_METHOD_HEAP;
47
48 status = uct_mem_alloc(NULL, min_length, UCT_MD_MEM_ACCESS_ALL, methods,
49 2, NULL, 0, "test", &mem);
50 ASSERT_UCS_OK(status);
51
52 check_mem(mem, min_length);
53
54 uct_mem_free(&mem);
55 }
56
UCS_TEST_P(test_mem,md_alloc)57 UCS_TEST_P(test_mem, md_alloc) {
58 uct_alloc_method_t methods[3];
59 uct_allocated_memory mem;
60 std::vector<md_resource> md_resources;
61 uct_md_attr_t md_attr;
62 ucs_status_t status;
63 uct_md_h md;
64 uct_md_config_t *md_config;
65 int nonblock;
66
67 methods[0] = UCT_ALLOC_METHOD_MD;
68 methods[1] = GetParam();
69 methods[2] = UCT_ALLOC_METHOD_HEAP;
70
71 md_resources = enum_md_resources();
72 for (std::vector<md_resource>::iterator iter = md_resources.begin();
73 iter != md_resources.end(); ++iter) {
74
75 status = uct_md_config_read(iter->cmpt, NULL, NULL, &md_config);
76 ASSERT_UCS_OK(status);
77
78 status = uct_md_open(iter->cmpt, iter->rsc_desc.md_name, md_config, &md);
79 uct_config_release(md_config);
80 ASSERT_UCS_OK(status);
81
82 status = uct_md_query(md, &md_attr);
83 ASSERT_UCS_OK(status);
84
85 for (nonblock = 0; nonblock <= 1; ++nonblock) {
86 int flags = nonblock ? UCT_MD_MEM_FLAG_NONBLOCK : 0;
87 flags |= UCT_MD_MEM_ACCESS_ALL;
88 status = uct_mem_alloc(NULL, min_length, flags, methods, 3, &md, 1,
89 "test", &mem);
90 ASSERT_UCS_OK(status);
91
92 if (md_attr.cap.flags & UCT_MD_FLAG_ALLOC) {
93 EXPECT_EQ(UCT_ALLOC_METHOD_MD, mem.method);
94 } else {
95 EXPECT_NE(UCT_ALLOC_METHOD_MD, mem.method);
96 }
97
98 check_mem(mem, min_length);
99
100 uct_mem_free(&mem);
101 }
102
103 uct_md_close(md);
104 }
105 }
106
UCS_TEST_P(test_mem,md_fixed)107 UCS_TEST_P(test_mem, md_fixed) {
108 std::vector<md_resource> md_resources;
109 uct_md_attr_t md_attr;
110 uct_md_config_t *md_config;
111 uct_md_h md;
112 unsigned j;
113
114 const size_t page_size = ucs_get_page_size();
115 const size_t n_tryes = 101;
116 uct_alloc_method_t meth;
117 void* p_addr = ucs::mmap_fixed_address();
118 size_t n_success;
119
120 uct_allocated_memory_t uct_mem;
121 ucs_status_t status;
122
123 md_resources = enum_md_resources();
124 for (std::vector<md_resource>::iterator iter = md_resources.begin();
125 iter != md_resources.end(); ++iter) {
126
127 status = uct_md_config_read(iter->cmpt, NULL, NULL, &md_config);
128 ASSERT_UCS_OK(status);
129
130 status = uct_md_open(iter->cmpt, iter->rsc_desc.md_name, md_config, &md);
131 uct_config_release(md_config);
132 ASSERT_UCS_OK(status);
133
134 status = uct_md_query(md, &md_attr);
135 ASSERT_UCS_OK(status);
136
137 if ((md_attr.cap.flags & UCT_MD_FLAG_ALLOC) &&
138 (md_attr.cap.flags & UCT_MD_FLAG_FIXED)) {
139 n_success = 0;
140
141 for (j = 0; j < n_tryes; ++j) {
142 meth = UCT_ALLOC_METHOD_MD;
143
144 status = uct_mem_alloc(p_addr, 1,
145 UCT_MD_MEM_FLAG_FIXED|
146 UCT_MD_MEM_ACCESS_ALL,
147 &meth, 1, &md, 1, "test", &uct_mem);
148 if (status == UCS_OK) {
149 ++n_success;
150 EXPECT_EQ(meth, uct_mem.method);
151 EXPECT_EQ(p_addr, uct_mem.address);
152 EXPECT_GE(uct_mem.length, (size_t)1);
153 /* touch the page*/
154 memset(uct_mem.address, 'c', uct_mem.length);
155 EXPECT_EQ(*(char*)p_addr, 'c');
156 status = uct_mem_free(&uct_mem);
157 } else {
158 EXPECT_EQ(status, UCS_ERR_NO_MEMORY);
159 }
160
161 p_addr = (char*)p_addr + (2 * page_size);
162 }
163
164 EXPECT_GT(n_success, (size_t)0);
165 }
166
167 uct_md_close(md);
168 }
169 }
170
171
UCS_TEST_P(test_mem,mmap_fixed)172 UCS_TEST_P(test_mem, mmap_fixed) {
173 unsigned i;
174
175 const size_t page_size = ucs_get_page_size();
176 const size_t n_tryes = 101;
177 uct_alloc_method_t meth;
178 void* p_addr = ucs::mmap_fixed_address();
179 size_t n_success;
180
181 uct_allocated_memory_t uct_mem;
182 ucs_status_t status;
183
184 n_success = 0;
185
186 for (i = 0; i < n_tryes; ++i) {
187 meth = (i % 2) ? UCT_ALLOC_METHOD_MMAP : UCT_ALLOC_METHOD_HUGE;
188
189 status = uct_mem_alloc(p_addr, 1,
190 UCT_MD_MEM_FLAG_FIXED|UCT_MD_MEM_ACCESS_ALL,
191 &meth, 1, NULL, 0, "test", &uct_mem);
192 if (status == UCS_OK) {
193 ++n_success;
194 EXPECT_EQ(meth, uct_mem.method);
195 EXPECT_EQ(p_addr, uct_mem.address);
196 EXPECT_GE(uct_mem.length, (size_t)1);
197 /* touch the page*/
198 memset(uct_mem.address, 'c', uct_mem.length);
199 EXPECT_EQ(*(char*)p_addr, 'c');
200 status = uct_mem_free(&uct_mem);
201 } else {
202 EXPECT_EQ(status, UCS_ERR_NO_MEMORY);
203 }
204 p_addr = (char*)p_addr + (2 * page_size);
205 }
206 }
207
208 INSTANTIATE_TEST_CASE_P(alloc_methods, test_mem,
209 ::testing::Values(UCT_ALLOC_METHOD_THP,
210 UCT_ALLOC_METHOD_HEAP,
211 UCT_ALLOC_METHOD_MMAP,
212 UCT_ALLOC_METHOD_HUGE));
213