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

UCT/IB: Fix teardown path on memory handler callback #10171

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

tvegas1
Copy link
Contributor

@tvegas1 tvegas1 commented Sep 23, 2024

What

Fix error handling path on multi-threaded registration.

Why ?

Currently we see segfault in the thread because we try to teardown the first failing registration.
More generally, a thread can fail to start or fail to properly register all its tasked mrs.

How ?

  • Make sure we cannot dereg twice.
  • Make sure we only teardown mrs entries corresponding to started threads.
  • Make sure started threads return with their mrs all initialized.

src/uct/ib/base/ib_md.c Show resolved Hide resolved
src/uct/ib/base/ib_md.c Outdated Show resolved Hide resolved
brminich
brminich previously approved these changes Sep 24, 2024
iyastreb
iyastreb previously approved these changes Oct 2, 2024
if (status != UCS_OK) {
goto err;
}
(void)uct_ib_dereg_mr(ctx->mrs[ctx->mr_idx]);
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe print a warning message?

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

@@ -219,6 +219,7 @@ typedef struct {
void *address;
size_t length;
size_t first_mr_size;
int mr_idx;
Copy link
Contributor

Choose a reason for hiding this comment

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

why needed? I would expect the thread will not exit with a partial registration: either it return UCS_OK, or returns an error and reverts all regisrtations

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes. It is for the case where there is at least one failing thread. it will then be used to teardown the other threads that had succeeded.

Copy link
Contributor

Choose a reason for hiding this comment

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

can we check this by the return value of the thread function, instead of adding this var to the context?

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 have to store per-thread because it's only when they are all joined that we know if one failed and we need to tear them down, so I think we cannot.

pthread_join could take return code and set it in ctx but seems better to have the thread update it itself.

MAP_PRIVATE | MAP_ANONYMOUS |
((ptr != nullptr) ? MAP_FIXED : 0),
-1, 0);
return ptr != MAP_FAILED ? ptr : nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

add ( )

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

size_t size = UCS_MBYTE;
const size_t align_mask = (8 * UCS_KBYTE) - 1;
size_t lower_size = ((size / 3)) & ~align_mask;
size_t upper_size = (size - (size / 2)) & ~align_mask;
Copy link
Contributor

Choose a reason for hiding this comment

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

(size - (size / 2)) -> (size / 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.

fixed

/* Find an available VMA */
start = mmap_anon(nullptr, size);
ASSERT_NE(nullptr, start);
mid = reinterpret_cast<char*>(start) + lower_size;
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe use UCS_PTR_BYTE_OFFSET?

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

/* coverity[pass_freed_arg] */
start = mmap_anon(start, lower_size);
last = mmap_anon(last, upper_size);
EXPECT_NE(nullptr, start);
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. move it right after mmap_anon(start, lower_size)
  2. maybe better just munmap between "start+lower_size" until "last"?
    you assume that after we munmap the block in line 338, no other thread will try to allocate in that area

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 both

@tvegas1
Copy link
Contributor Author

tvegas1 commented Oct 14, 2024

/azp run UCX PR

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tvegas1
Copy link
Contributor Author

tvegas1 commented Oct 17, 2024

@yosefe, could you please check it?

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