Skip to content

Commit b726d3e

Browse files
committed
File provider IPC API requires UMF_MEM_MAP_SHARED or UMF_MEM_MAP_SYNC
IPC API of file memory provider requires the `UMF_MEM_MAP_SHARED` or `UMF_MEM_MAP_SYNC` memory `visibility` mode (`UMF_RESULT_ERROR_INVALID_ARGUMENT` is returned otherwise). Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 5ed9882 commit b726d3e

File tree

3 files changed

+114
-23
lines changed

3 files changed

+114
-23
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ so it should be used with a pool manager that will take over
203203
the managing of the provided memory - for example the jemalloc pool
204204
with the `disable_provider_free` parameter set to true.
205205

206+
IPC API requires the `UMF_MEM_MAP_SHARED` or `UMF_MEM_MAP_SYNC` memory `visibility` mode
207+
(`UMF_RESULT_ERROR_INVALID_ARGUMENT` is returned otherwise).
208+
206209
The memory visibility mode parameter must be set to `UMF_MEM_MAP_SYNC` in case of FSDAX.
207210

208211
##### Requirements

src/provider/provider_file_memory.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <assert.h>
99
#include <errno.h>
1010
#include <limits.h>
11+
#include <stdbool.h>
1112
#include <stddef.h>
1213
#include <stdio.h>
1314
#include <stdlib.h>
@@ -41,6 +42,9 @@ typedef struct file_memory_provider_t {
4142
unsigned visibility; // memory visibility mode
4243
size_t page_size; // minimum page size
4344

45+
// IPC is enabled only for UMF_MEM_MAP_SHARED or UMF_MEM_MAP_SYNC visibility
46+
bool IPC_enabled;
47+
4448
critnib *mmaps; // a critnib map storing mmap mappings (addr, size)
4549

4650
// A critnib map storing (ptr, fd_offset + 1) pairs. We add 1 to fd_offset
@@ -101,6 +105,10 @@ file_translate_params(umf_file_memory_provider_params_t *in_params,
101105
return result;
102106
}
103107

108+
// IPC is enabled only for UMF_MEM_MAP_SHARED or UMF_MEM_MAP_SYNC visibility
109+
provider->IPC_enabled = (in_params->visibility == UMF_MEM_MAP_SHARED ||
110+
in_params->visibility == UMF_MEM_MAP_SYNC);
111+
104112
return UMF_RESULT_SUCCESS;
105113
}
106114

@@ -545,6 +553,13 @@ static umf_result_t file_get_ipc_handle_size(void *provider, size_t *size) {
545553
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
546554
}
547555

556+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
557+
if (!file_provider->IPC_enabled) {
558+
LOG_ERR("memory visibility mode is not UMF_MEM_MAP_SHARED nor "
559+
"UMF_MEM_MAP_SYNC")
560+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
561+
}
562+
548563
*size = sizeof(file_ipc_data_t);
549564

550565
return UMF_RESULT_SUCCESS;
@@ -557,6 +572,11 @@ static umf_result_t file_get_ipc_handle(void *provider, const void *ptr,
557572
}
558573

559574
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
575+
if (!file_provider->IPC_enabled) {
576+
LOG_ERR("memory visibility mode is not UMF_MEM_MAP_SHARED nor "
577+
"UMF_MEM_MAP_SYNC")
578+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
579+
}
560580

561581
void *value = critnib_get(file_provider->fd_offset_map, (uintptr_t)ptr);
562582
if (value == NULL) {
@@ -581,6 +601,12 @@ static umf_result_t file_put_ipc_handle(void *provider, void *providerIpcData) {
581601
}
582602

583603
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
604+
if (!file_provider->IPC_enabled) {
605+
LOG_ERR("memory visibility mode is not UMF_MEM_MAP_SHARED nor "
606+
"UMF_MEM_MAP_SYNC")
607+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
608+
}
609+
584610
file_ipc_data_t *file_ipc_data = (file_ipc_data_t *)providerIpcData;
585611

586612
if (strncmp(file_ipc_data->path, file_provider->path, PATH_MAX)) {
@@ -597,6 +623,12 @@ static umf_result_t file_open_ipc_handle(void *provider, void *providerIpcData,
597623
}
598624

599625
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
626+
if (!file_provider->IPC_enabled) {
627+
LOG_ERR("memory visibility mode is not UMF_MEM_MAP_SHARED nor "
628+
"UMF_MEM_MAP_SYNC")
629+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
630+
}
631+
600632
file_ipc_data_t *file_ipc_data = (file_ipc_data_t *)providerIpcData;
601633
umf_result_t ret = UMF_RESULT_SUCCESS;
602634
int fd;
@@ -631,6 +663,13 @@ static umf_result_t file_close_ipc_handle(void *provider, void *ptr,
631663
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
632664
}
633665

666+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
667+
if (!file_provider->IPC_enabled) {
668+
LOG_ERR("memory visibility mode is not UMF_MEM_MAP_SHARED nor "
669+
"UMF_MEM_MAP_SYNC")
670+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
671+
}
672+
634673
errno = 0;
635674
int ret = utils_munmap(ptr, size);
636675
// ignore error when size == 0

test/provider_file_memory.cpp

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static void providerCreateExt(providerCreateExtParams params,
5555
umf::provider_unique_handle_t(hProvider, &umfMemoryProviderDestroy);
5656
}
5757

58-
struct umfProviderTest
58+
struct FileProviderParamsDefault
5959
: umf_test::test,
6060
::testing::WithParamInterface<providerCreateExtParams> {
6161
void SetUp() override {
@@ -75,6 +75,8 @@ struct umfProviderTest
7575
size_t page_plus_64;
7676
};
7777

78+
struct FileProviderParamsShared : FileProviderParamsDefault {};
79+
7880
static void test_alloc_free_success(umf_memory_provider_handle_t provider,
7981
size_t size, size_t alignment,
8082
purge_t purge) {
@@ -161,6 +163,9 @@ TEST_F(test, test_if_mapped_with_MAP_SYNC) {
161163

162164
// positive tests using test_alloc_free_success
163165

166+
umf_file_memory_provider_params_t file_params_default =
167+
umfFileMemoryProviderParamsDefault(FILE_PATH);
168+
164169
umf_file_memory_provider_params_t get_file_params_shared(char *path) {
165170
umf_file_memory_provider_params_t file_params =
166171
umfFileMemoryProviderParamsDefault(path);
@@ -171,68 +176,108 @@ umf_file_memory_provider_params_t get_file_params_shared(char *path) {
171176
umf_file_memory_provider_params_t file_params_shared =
172177
get_file_params_shared(FILE_PATH);
173178

174-
INSTANTIATE_TEST_SUITE_P(fileProviderTest, umfProviderTest,
179+
INSTANTIATE_TEST_SUITE_P(fileProviderTest, FileProviderParamsDefault,
175180
::testing::Values(providerCreateExtParams{
176-
umfFileMemoryProviderOps(), &file_params_shared}));
181+
umfFileMemoryProviderOps(),
182+
&file_params_default}));
177183

178-
TEST_P(umfProviderTest, create_destroy) {}
184+
TEST_P(FileProviderParamsDefault, create_destroy) {}
179185

180-
TEST_P(umfProviderTest, alloc_page64_align_0) {
186+
TEST_P(FileProviderParamsDefault, alloc_page64_align_0) {
181187
test_alloc_free_success(provider.get(), page_plus_64, 0, PURGE_NONE);
182188
}
183189

184-
TEST_P(umfProviderTest, alloc_page64_align_page_div_2) {
190+
TEST_P(FileProviderParamsDefault, alloc_page64_align_page_div_2) {
185191
test_alloc_free_success(provider.get(), page_plus_64, page_size / 2,
186192
PURGE_NONE);
187193
}
188194

189-
TEST_P(umfProviderTest, purge_lazy) {
195+
TEST_P(FileProviderParamsDefault, purge_lazy) {
190196
test_alloc_free_success(provider.get(), page_plus_64, 0, PURGE_LAZY);
191197
}
192198

193-
TEST_P(umfProviderTest, purge_force) {
199+
TEST_P(FileProviderParamsDefault, purge_force) {
194200
test_alloc_free_success(provider.get(), page_plus_64, 0, PURGE_FORCE);
195201
}
196202

197203
// negative tests using test_alloc_failure
198204

199-
TEST_P(umfProviderTest, alloc_WRONG_SIZE) {
205+
TEST_P(FileProviderParamsDefault, alloc_WRONG_SIZE) {
200206
test_alloc_failure(provider.get(), -1, 0, UMF_RESULT_ERROR_INVALID_ARGUMENT,
201207
0);
202208
}
203209

204-
TEST_P(umfProviderTest, alloc_page64_WRONG_ALIGNMENT_3_pages) {
210+
TEST_P(FileProviderParamsDefault, alloc_page64_WRONG_ALIGNMENT_3_pages) {
205211
test_alloc_failure(provider.get(), page_plus_64, 3 * page_size,
206212
UMF_RESULT_ERROR_INVALID_ALIGNMENT, 0);
207213
}
208214

209-
TEST_P(umfProviderTest, alloc_3pages_WRONG_ALIGNMENT_3pages) {
215+
TEST_P(FileProviderParamsDefault, alloc_3pages_WRONG_ALIGNMENT_3pages) {
210216
test_alloc_failure(provider.get(), 3 * page_size, 3 * page_size,
211217
UMF_RESULT_ERROR_INVALID_ALIGNMENT, 0);
212218
}
213219

214-
TEST_P(umfProviderTest, alloc_page64_align_page_minus_1_WRONG_ALIGNMENT_1) {
220+
TEST_P(FileProviderParamsDefault,
221+
alloc_page64_align_page_minus_1_WRONG_ALIGNMENT_1) {
215222
test_alloc_failure(provider.get(), page_plus_64, page_size - 1,
216223
UMF_RESULT_ERROR_INVALID_ALIGNMENT, 0);
217224
}
218225

219-
TEST_P(umfProviderTest, alloc_page64_align_one_half_pages_WRONG_ALIGNMENT_2) {
226+
TEST_P(FileProviderParamsDefault,
227+
alloc_page64_align_one_half_pages_WRONG_ALIGNMENT_2) {
220228
test_alloc_failure(provider.get(), page_plus_64,
221229
page_size + (page_size / 2),
222230
UMF_RESULT_ERROR_INVALID_ALIGNMENT, 0);
223231
}
224232

233+
// negative IPC tests
234+
235+
TEST_P(FileProviderParamsDefault, get_ipc_handle_size_wrong_visibility) {
236+
size_t size;
237+
umf_result_t umf_result =
238+
umfMemoryProviderGetIPCHandleSize(provider.get(), &size);
239+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
240+
}
241+
242+
TEST_P(FileProviderParamsDefault, get_ipc_handle_wrong_visibility) {
243+
char providerIpcData;
244+
umf_result_t umf_result = umfMemoryProviderGetIPCHandle(
245+
provider.get(), INVALID_PTR, 1, &providerIpcData);
246+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
247+
}
248+
249+
TEST_P(FileProviderParamsDefault, put_ipc_handle_wrong_visibility) {
250+
char providerIpcData;
251+
umf_result_t umf_result =
252+
umfMemoryProviderPutIPCHandle(provider.get(), &providerIpcData);
253+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
254+
}
255+
256+
TEST_P(FileProviderParamsDefault, open_ipc_handle_wrong_visibility) {
257+
char providerIpcData;
258+
void *ptr;
259+
umf_result_t umf_result =
260+
umfMemoryProviderOpenIPCHandle(provider.get(), &providerIpcData, &ptr);
261+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
262+
}
263+
264+
TEST_P(FileProviderParamsDefault, close_ipc_handle_wrong_visibility) {
265+
umf_result_t umf_result =
266+
umfMemoryProviderCloseIPCHandle(provider.get(), INVALID_PTR, 1);
267+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
268+
}
269+
225270
// other positive tests
226271

227-
TEST_P(umfProviderTest, get_min_page_size) {
272+
TEST_P(FileProviderParamsDefault, get_min_page_size) {
228273
size_t min_page_size;
229274
umf_result_t umf_result = umfMemoryProviderGetMinPageSize(
230275
provider.get(), nullptr, &min_page_size);
231276
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
232277
ASSERT_LE(min_page_size, page_size);
233278
}
234279

235-
TEST_P(umfProviderTest, get_recommended_page_size) {
280+
TEST_P(FileProviderParamsDefault, get_recommended_page_size) {
236281
size_t min_page_size;
237282
umf_result_t umf_result = umfMemoryProviderGetMinPageSize(
238283
provider.get(), nullptr, &min_page_size);
@@ -246,18 +291,18 @@ TEST_P(umfProviderTest, get_recommended_page_size) {
246291
ASSERT_GE(recommended_page_size, min_page_size);
247292
}
248293

249-
TEST_P(umfProviderTest, get_name) {
294+
TEST_P(FileProviderParamsDefault, get_name) {
250295
const char *name = umfMemoryProviderGetName(provider.get());
251296
ASSERT_STREQ(name, "FILE");
252297
}
253298

254-
TEST_P(umfProviderTest, free_size_0_ptr_not_null) {
299+
TEST_P(FileProviderParamsDefault, free_size_0_ptr_not_null) {
255300
umf_result_t umf_result =
256301
umfMemoryProviderFree(provider.get(), INVALID_PTR, 0);
257302
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
258303
}
259304

260-
TEST_P(umfProviderTest, free_NULL) {
305+
TEST_P(FileProviderParamsDefault, free_NULL) {
261306
umf_result_t umf_result = umfMemoryProviderFree(provider.get(), nullptr, 0);
262307
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
263308
}
@@ -274,19 +319,19 @@ TEST_F(test, create_empty_path) {
274319
EXPECT_EQ(hProvider, nullptr);
275320
}
276321

277-
TEST_P(umfProviderTest, free_INVALID_POINTER_SIZE_GT_0) {
322+
TEST_P(FileProviderParamsDefault, free_INVALID_POINTER_SIZE_GT_0) {
278323
umf_result_t umf_result =
279324
umfMemoryProviderFree(provider.get(), INVALID_PTR, page_plus_64);
280325
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
281326
}
282327

283-
TEST_P(umfProviderTest, purge_lazy_INVALID_POINTER) {
328+
TEST_P(FileProviderParamsDefault, purge_lazy_INVALID_POINTER) {
284329
umf_result_t umf_result =
285330
umfMemoryProviderPurgeLazy(provider.get(), INVALID_PTR, 1);
286331
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
287332
}
288333

289-
TEST_P(umfProviderTest, purge_force_INVALID_POINTER) {
334+
TEST_P(FileProviderParamsDefault, purge_force_INVALID_POINTER) {
290335
umf_result_t umf_result =
291336
umfMemoryProviderPurgeForce(provider.get(), INVALID_PTR, 1);
292337
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC);
@@ -297,7 +342,11 @@ TEST_P(umfProviderTest, purge_force_INVALID_POINTER) {
297342

298343
// IPC tests
299344

300-
TEST_P(umfProviderTest, IPC_base_success_test) {
345+
INSTANTIATE_TEST_SUITE_P(fileProviderTest, FileProviderParamsShared,
346+
::testing::Values(providerCreateExtParams{
347+
umfFileMemoryProviderOps(), &file_params_shared}));
348+
349+
TEST_P(FileProviderParamsShared, IPC_base_success_test) {
301350
umf_result_t umf_result;
302351
void *ptr = nullptr;
303352
size_t size = page_size;
@@ -338,7 +387,7 @@ TEST_P(umfProviderTest, IPC_base_success_test) {
338387
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
339388
}
340389

341-
TEST_P(umfProviderTest, IPC_file_not_exist) {
390+
TEST_P(FileProviderParamsShared, IPC_file_not_exist) {
342391
umf_result_t umf_result;
343392
void *ptr = nullptr;
344393
size_t size = page_size;

0 commit comments

Comments
 (0)