Skip to content

Commit 5bf1b5e

Browse files
authored
Merge pull request #800 from ldorau/Fix_updating_offset_mmap_in_file_alloc_aligned
Fix `file_alloc()` of the file memory provider
2 parents 0c82ae5 + 62444d3 commit 5bf1b5e

File tree

2 files changed

+77
-13
lines changed

2 files changed

+77
-13
lines changed

src/provider/provider_file_memory.c

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,22 +263,38 @@ static umf_result_t file_mmap_aligned(file_memory_provider_t *file_provider,
263263
return UMF_RESULT_ERROR_INVALID_ARGUMENT; // arithmetic overflow
264264
}
265265

266-
if (offset_fd + extended_size > size_fd) {
267-
if (utils_fallocate(fd, offset_fd, extended_size)) {
266+
// offset_fd has to be also page-aligned since it is the offset of mmap()
267+
size_t aligned_offset_fd = offset_fd;
268+
rest = aligned_offset_fd & (page_size - 1);
269+
if (rest) {
270+
aligned_offset_fd += page_size - rest;
271+
}
272+
if (aligned_offset_fd < offset_fd) {
273+
LOG_ERR("arithmetic overflow of file offset");
274+
return UMF_RESULT_ERROR_INVALID_ARGUMENT; // arithmetic overflow
275+
}
276+
277+
if (aligned_offset_fd + extended_size > size_fd) {
278+
size_t new_size_fd = aligned_offset_fd + extended_size;
279+
if (utils_fallocate(fd, size_fd, new_size_fd - size_fd)) {
268280
LOG_ERR("cannot grow the file size from %zu to %zu", size_fd,
269-
offset_fd + extended_size);
281+
new_size_fd);
270282
return UMF_RESULT_ERROR_UNKNOWN;
271283
}
272284

273-
LOG_DEBUG("file size grown from %zu to %zu", size_fd,
274-
offset_fd + extended_size);
275-
file_provider->size_fd = size_fd = offset_fd + extended_size;
285+
LOG_DEBUG("file size grown from %zu to %zu", size_fd, new_size_fd);
286+
file_provider->size_fd = new_size_fd;
287+
}
288+
289+
if (aligned_offset_fd > offset_fd) {
290+
file_provider->offset_fd = aligned_offset_fd;
276291
}
277292

278293
ASSERT_IS_ALIGNED(extended_size, page_size);
279-
ASSERT_IS_ALIGNED(offset_fd, page_size);
294+
ASSERT_IS_ALIGNED(aligned_offset_fd, page_size);
280295

281-
void *ptr = utils_mmap_file(NULL, extended_size, prot, flag, fd, offset_fd);
296+
void *ptr =
297+
utils_mmap_file(NULL, extended_size, prot, flag, fd, aligned_offset_fd);
282298
if (ptr == NULL) {
283299
LOG_PERR("memory mapping failed");
284300
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
@@ -292,6 +308,10 @@ static umf_result_t file_mmap_aligned(file_memory_provider_t *file_provider,
292308
ptr, extended_size);
293309
}
294310

311+
LOG_DEBUG(
312+
"inserted a value to the map of memory mapping (addr=%p, size=%zu)",
313+
ptr, extended_size);
314+
295315
file_provider->base_mmap = ptr;
296316
file_provider->size_mmap = extended_size;
297317
file_provider->offset_mmap = 0;
@@ -335,19 +355,31 @@ static umf_result_t file_alloc_aligned(file_memory_provider_t *file_provider,
335355
}
336356

337357
size_t new_offset_mmap = new_aligned_ptr - (uintptr_t)base_mmap;
358+
size_t new_offset_fd =
359+
file_provider->offset_fd + new_offset_mmap - file_provider->offset_mmap;
360+
338361
if (file_provider->size_mmap - new_offset_mmap < size) {
339362
umf_result = file_mmap_aligned(file_provider, size, alignment);
340363
if (umf_result != UMF_RESULT_SUCCESS) {
341364
utils_mutex_unlock(&file_provider->lock);
342365
return umf_result;
343366
}
367+
368+
assert(file_provider->base_mmap);
369+
370+
// file_provider-> base_mmap, offset_mmap, offset_fd
371+
// were updated by file_mmap_aligned():
372+
new_aligned_ptr = (uintptr_t)file_provider->base_mmap;
373+
new_offset_mmap = 0; // == file_provider->offset_mmap
374+
new_offset_fd = file_provider->offset_fd;
375+
376+
ASSERT_IS_ALIGNED(new_aligned_ptr, alignment);
344377
}
345378

346-
size_t old_offset_mmap = file_provider->offset_mmap;
347-
file_provider->offset_mmap = new_offset_mmap;
348-
*alloc_offset_fd =
349-
file_provider->offset_fd + new_offset_mmap - old_offset_mmap;
350-
file_provider->offset_fd = *alloc_offset_fd + size;
379+
*alloc_offset_fd = new_offset_fd;
380+
381+
file_provider->offset_fd = new_offset_fd + size;
382+
file_provider->offset_mmap = new_offset_mmap + size;
351383

352384
*out_addr = (void *)new_aligned_ptr;
353385

test/provider_file_memory.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,38 @@ INSTANTIATE_TEST_SUITE_P(fileProviderTest, FileProviderParamsDefault,
183183

184184
TEST_P(FileProviderParamsDefault, create_destroy) {}
185185

186+
TEST_P(FileProviderParamsDefault, two_allocations) {
187+
umf_result_t umf_result;
188+
void *ptr1 = nullptr;
189+
void *ptr2 = nullptr;
190+
size_t size = page_plus_64;
191+
size_t alignment = page_size;
192+
193+
umf_result = umfMemoryProviderAlloc(provider.get(), size, alignment, &ptr1);
194+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
195+
ASSERT_NE(ptr1, nullptr);
196+
197+
umf_result = umfMemoryProviderAlloc(provider.get(), size, alignment, &ptr2);
198+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
199+
ASSERT_NE(ptr2, nullptr);
200+
201+
ASSERT_NE(ptr1, ptr2);
202+
if ((uintptr_t)ptr1 > (uintptr_t)ptr2) {
203+
ASSERT_GT((uintptr_t)ptr1 - (uintptr_t)ptr2, size);
204+
} else {
205+
ASSERT_GT((uintptr_t)ptr2 - (uintptr_t)ptr1, size);
206+
}
207+
208+
memset(ptr1, 0x11, size);
209+
memset(ptr2, 0x22, size);
210+
211+
umf_result = umfMemoryProviderFree(provider.get(), ptr1, size);
212+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
213+
214+
umf_result = umfMemoryProviderFree(provider.get(), ptr2, size);
215+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
216+
}
217+
186218
TEST_P(FileProviderParamsDefault, alloc_page64_align_0) {
187219
test_alloc_free_success(provider.get(), page_plus_64, 0, PURGE_NONE);
188220
}

0 commit comments

Comments
 (0)