Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add threshold to proxy lib to call system allocator #883

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ldorau
Copy link
Contributor

@ldorau ldorau commented Nov 8, 2024

Description

Add threshold to proxy lib to call system allocator
when a size is less than the given threshold (Linux only yet).

Ref: #894

Requires:

Checklist

  • Code compiles without errors locally
  • All tests pass locally
  • CI workflows execute properly

@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch 10 times, most recently from 8bfade2 to 2a5fb9e Compare November 12, 2024 08:47
@ldorau ldorau changed the title [WIP] Add threshold to proxy lib to call system allocator Add threshold to proxy lib to call system allocator Nov 12, 2024
@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch from 2a5fb9e to 4cdba02 Compare November 12, 2024 08:57
@ldorau ldorau marked this pull request as ready for review November 12, 2024 08:57
@ldorau ldorau requested a review from a team as a code owner November 12, 2024 08:57
@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch 2 times, most recently from 0d3f0c7 to 7c781ef Compare November 12, 2024 11:34
UMF_PROXY="size.threshold=128"
UMF_LOG="level:debug;flush:debug;output:stderr;pid:yes"
LD_PRELOAD=./lib/libumf_proxy.so
ctest --output-on-failure -E provider_file_memory_ipc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have a test where you use umfPoolByPtr() to check allocs smaller than threshold were not registered in the tracker

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a test for that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bratpiorka tests added
Done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/proxy_lib/proxy_lib.c Outdated Show resolved Hide resolved
src/libumf.c Show resolved Hide resolved
Comment on lines 309 to 445
if (Proxy_pool) {
if (!was_called_from_umfPool && Proxy_pool &&
(umfPoolByPtr(ptr) == Proxy_pool)) {
was_called_from_umfPool = 1;
void *new_ptr = umfPoolRealloc(Proxy_pool, ptr, size);
was_called_from_umfPool = 0;
return new_ptr;
}

assert(0);
if (threshold_value) {
return system_realloc(ptr, size);
}

Copy link
Contributor

@lplewa lplewa Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test
ptr = Malloc(threshold_value + 1)
realloc(ptr, threshold_value - 1)

and vice versa.
ptr = Malloc(threshold_value - 1)
realloc(ptr, threshold_value + 1)

Both cases check then umfPoolByPtr if it returns expected value.

(atm in this PR we are not supporting this correctly - if we increasing or decrease size of allocation thru realoc we should "realloc this allocation" to correct allocator.

Copy link
Contributor Author

@ldorau ldorau Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lplewa Tests added.
Done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lplewa If you would like to change an allocator in realloc() depending on a size of an allocation, where do you get from the size of the current allocation coming from glibc ? You have to know the original size to do memcopy() inside realloc() ...

@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch from db760b2 to 4ac6b3e Compare November 14, 2024 09:02
.github/workflows/reusable_proxy_lib.yml Outdated Show resolved Hide resolved
src/libumf.c Outdated
if (utils_is_running_in_proxy_lib_with_size_threshold()) {
// We cannot destroy the TRACKER nor the base allocator
// when we are running in the proxy library with a size threshold,
// because it could lead to calling the system free() with an invalid pointer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant "It could lead to something", so "calling ..." , not "call ..."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe lead to should be followed by either something or to <verb>
you could write it somehow differently e.g. it could result in calling, or lead to system free call with ...

that's my understanding, but you know... I'm not native ;)

I'd re-phrase with it could result in calling ... and a segfault.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with it could result in calling ...
Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now the last part as a result is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

test/CMakeLists.txt Outdated Show resolved Hide resolved
src/proxy_lib/proxy_lib.c Outdated Show resolved Hide resolved
*end = '\0';
}

size_t int_threshold = (size_t)atoi(str_threshold);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't coverity complain about int -> size_t conversion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check that? I cannot. We will see ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh, ok, let me re-phrase the question - should we worry if the user pass size.threshold=-1 (e.g. by mistake)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.
Done.

src/proxy_lib/proxy_lib.c Show resolved Hide resolved
test/test_proxy_lib.cpp Outdated Show resolved Hide resolved
// replace ';' with '\0' to mark end of the string
*end = '\0';
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have a test for checking this parsing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have to move this function to utils, it cannot be tested here as a part of proxy lib.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have a script or part of CI, that will run multiple configurations, like:

UMF_PROXY="size.threshold=XYZ;<other var>" LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure
UMF_PROXY="<other var>;size.threshold=ABC" LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure
etc...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have a script or part of CI, that will run multiple configurations, like:

UMF_PROXY="size.threshold=XYZ;<other var>" LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure
UMF_PROXY="<other var>;size.threshold=ABC" LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure
etc...

I am afraid it would take too much time ...

#endif
}

TEST_F(test, proxyLib_size_threshold_malloc) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have a test with multiple allocs, not just 2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would it change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we would have more tests 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only 2 are needed in tests of the size threshold: one for the default system allocator (size < threshold) and another one for the proxy library pool UMF pool allocator (size >= threshold). There is no need for an extra one.

test/test_proxy_lib.cpp Outdated Show resolved Hide resolved
@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch from 4ac6b3e to 846f30b Compare November 14, 2024 15:14
Signed-off-by: Lukasz Dorau <[email protected]>
Do not assert(ptr) in umfMemoryTrackerGetAllocInfo(),
return UMF_RESULT_ERROR_INVALID_ARGUMENT instead.
Replace LOG_WARN() with LOG_DEBUG().
Add utils_env_var_get_str() to utils_common.
Use utils_env_var_get_str() inside utils_env_var_has_str()
and utils_is_running_in_proxy_lib().

Signed-off-by: Lukasz Dorau <[email protected]>
Add a size threshold to proxy lib to call system allocator
when the size is less than the given threshold (Linux only yet).

Signed-off-by: Lukasz Dorau <[email protected]>
@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch from 846f30b to 653bd3d Compare November 14, 2024 19:56
This WA for the issue:
oneapi-src#894
It protects us from a recursion in malloc_usable_size()
when the JEMALLOC proxy_lib_pool is used.

TODO: remove this WA when the issue is fixed.

Signed-off-by: Lukasz Dorau <[email protected]>
The proxyLib_size_threshold_* tests test the size threshold
of the proxy library (Linux only yet). The size threshold
is set to 64 bytes in this test, so all allocations of:
1) size <  64 go through the default system allocator
   and (umfPoolByPtr(ptr_size < 64) == nullptr)
2) size >= 64 go through the proxy lib allocator
   and (umfPoolByPtr(ptr_size >= 64) != nullptr).

Ref: oneapi-src#894

Signed-off-by: Lukasz Dorau <[email protected]>
@ldorau ldorau force-pushed the Add_threshold_to_proxy_lib_to_call_system_allocator branch from 653bd3d to ec89615 Compare November 14, 2024 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants