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

configure: Check for membarrier support #1704

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

clementguidi
Copy link
Contributor

@clementguidi clementguidi commented May 11, 2023

This is the third PR in a series of patches intended to bring runtime dynamic tracing on x86_64 to uftrace.

  1. dynamic: Refactor logic to perform multiple updates #1702
  2. dynamic: Refactor patch pattern logic #1703
  3. configure: Check for membarrier support #1704 🠈
  4. utils: Add helpers for runtime dynamic patching #1705
  5. dynamic: x86_64: refactor patch code #1745
  6. dynamic: x86_64: Support runtime dynamic patching #1746
  7. dynamic: x86_64: Optimize runtime dynamic patching #1747
  8. dynamic: x86 64: Support runtime dynamic unpatching #1748
  9. agent: Trigger runtime dynamic instrumentation #1749
  10. dynamic: x86_64: Fall back to original patching strategy when target is not running #1750
  11. dynamic: Display enhanced dynamic stats #1751

Runtime dynamic patching requires cache synchronization. This is best achieved by using the MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE memory barrier. However it was introduced in Linux 4.16. We set a flag
indicating whether this membarrier can be used or if libmcount has to rely on other mechanisms (e.g. signals).

We introduce a configuration option --without-membarrier to disable the use of MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE even if it is available.

Related: #1698

Runtime dynamic patching requires cache synchronization. This is best
achieved by using the 'MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE'
memory barrier. However it was introduced in Linux 4.16. We set a flag
indicating whether this membarrier can be used or if libmcount has to
rely on other mechanisms (e.g. signals).

Signed-off-by: Clément Guidi <[email protected]>
int main()
{
syscall(__NR_membarrier, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, 0, 0);
syscall(__NR_membarrier, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, 0, 0);
Copy link
Owner

Choose a reason for hiding this comment

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

By using _PRIVATE_EXPEDITED_SYNC_CORE, can we delete the old copy right after the syscall?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, what do you mean by "the old copy"?

Here is an extract from the membarrier manual, for future reference:

MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE (since Linux 4.16)

In addition to providing the memory ordering guarantees described in MEMBARRIER_CMD_PRIVATE_EXPEDITED, upon return from system call the calling thread has a guarantee that all its running thread siblings have executed a core serializing instruction. This guarantee is provided only for threads in the same process as the calling thread.

The "expedited" commands complete faster than the non-expedited ones, they never block, but have the downside of causing extra overhead.

A process must register its intent to use the private expedited sync core command prior to using it.

MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE (since Linux 4.16)

Register the process's intent to use MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE.

Copy link
Owner

Choose a reason for hiding this comment

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

Sorry for the late reply. I think you want to use membarrier to update global state like in a RCU fashion. Something like below:

new_data = copy_data(shared_data);
add_some_data(new_data);

old_data = shared_data;
shared_data = new_data;  // WRITE_ONCE ?

membarrier();

free(old_data);

Copy link

Choose a reason for hiding this comment

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

That is somewhat true. We want to use membarriers to stop all running threads before entering patching/unpatching code as will be done in this other commit:
f07ab57

Note that this particular PR merely checks for availability of membarrier system call. The actual usage is left for PR #1747

Copy link
Owner

Choose a reason for hiding this comment

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

I know, I was just curious how it's gonna be used.

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.

3 participants