Live data from Hacker News

Safepoints and Fil-C

fil-c.org

31–40 of 45 posts

Re: Safepoints and Fil-C

#31
post #30

Earlier quoted context omitted.

The most commonly used optimization is to have just a load, or just a store, rather than a load-and-branch. Basically you access a page that you mprotect to trigger the handshake. Unrolling loops is also super common. Recognizing loops that have a bounded runtime is also common. My favorite technique to try one day is: 1. just record where the pollcheck points are but don't emit code there 2. to handshake with a thre…

Memory protection games just don't scale. You're modifying global structures, resulting in tons of contention. That's also why compacting GCs prefer to use card marking rather than mprotect. About 2. - that's exactly what I meant. The downside is that now you have to write a full x86 emulator, maybe including SIMD instructions. Good luck. And that's also what I want to try to avoid. Imagine generating a copy of the i…

> Memory protection games just don't scale. You're modifying global structures, resulting in tons of contention. That's also why compacting GCs prefer to use card marking rather than mprotect.

I’m describing what production JVMs do. They do it because it’s a speedup for them. Like, those compacting GCs that you’re saying use card marking are using page faults for safe points more often than not.

It’s true that page protection games don’t result in speedups for generational store barriers. A safe point is not that.

Re: Safepoints and Fil-C

#32
post #30

Earlier quoted context omitted.

Memory protection games just don't scale. You're modifying global structures, resulting in tons of contention. That's also why compacting GCs prefer to use card marking rather than mprotect. About 2. - that's exactly what I meant. The downside is that now you have to write a full x86 emulator, maybe including SIMD instructions. Good luck. And that's also what I want to try to avoid. Imagine generating a copy of the i…

> Memory protection games just don't scale. You're modifying global structures, resulting in tons of contention. That's also why compacting GCs prefer to use card marking rather than mprotect. I’m describing what production JVMs do. They do it because it’s a speedup for them. Like, those compacting GCs that you’re saying use card marking are using page faults for safe points more often than not. It’s true that page p…

I believe, Oracle JVM uses polling?

This is the class responsible for safepoints: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06...

And this is one of the implementations: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06...

The arming code: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06...

I might be missing something, but I'd be terribly surprised if VM games are worth it.

Re: Safepoints and Fil-C

#33

Earlier quoted context omitted.

I'm sure for many people's $WORK the ability to run OpenSSH built with Fil-C and constant-time crypto would be amazing, and it would be great advertising for Fil-C. But there is no way any of us would run OpenSSH built with Fil-C in production w/o constant-time crypto.

That's good to know. If I made the assembly memory safe under Fil-C rules by running it through a transform that inserted additional instructions but did not otherwise change what was happening, would you trust that it's still constant-time?

Yes. Don't branch on key or in-clear data. Otherwise, ok.

If a user is doing onion wrapping, they don't want you to branch on the code data either.

Re: Safepoints and Fil-C

#34
post #32

Earlier quoted context omitted.

> Memory protection games just don't scale. You're modifying global structures, resulting in tons of contention. That's also why compacting GCs prefer to use card marking rather than mprotect. I’m describing what production JVMs do. They do it because it’s a speedup for them. Like, those compacting GCs that you’re saying use card marking are using page faults for safe points more often than not. It’s true that page p…

I believe, Oracle JVM uses polling? This is the class responsible for safepoints: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06... And this is one of the implementations: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06... The arming code: https://github.com/openjdk/jdk/blob/4b544f93ad0e2beae4c80e06... I might be missing something, but I'd be terribly surprised if VM games are worth it.

That JVM totally uses the page protection trick.

Look at the code that talks about polling page.

Re: Safepoints and Fil-C

#36

Earlier quoted context omitted.

I'm sure for many people's $WORK the ability to run OpenSSH built with Fil-C and constant-time crypto would be amazing, and it would be great advertising for Fil-C. But there is no way any of us would run OpenSSH built with Fil-C in production w/o constant-time crypto.

That's good to know. If I made the assembly memory safe under Fil-C rules by running it through a transform that inserted additional instructions but did not otherwise change what was happening, would you trust that it's still constant-time?

You can reason about it, that if the instructions in question are not dependent on a key or plaintext value then it won't affect the constant time nature of the implementation of the cryptographic algorithm.

Re: Safepoints and Fil-C

#37

Earlier quoted context omitted.

Yes, _that_ is not to be allowed. I think you could have LLVM know about `vfork(2)` and treat that as an error -- heck, clang already knows how to do that, does it not?

That's just one example and the problem isn't just checking this one case, but any generalization of it. It can't be a fully static check because you could achieve similar things with longjmp or exceptions (both of which Fil-C supports). And then there are similar issues with heap accesses and safepoints. The vfork child has to particular in safepoints except that it cannot quite (you can't use pthread_mutex/pthread_…

Can we make the C library mutex lock and condvar primitives work on the vfork() child? It's practically like a thread...

Re: Safepoints and Fil-C

#38
post #27

Earlier quoted context omitted.

> Remember that the child side of `vfork(2)` can only do async-signal-safe things as `vfork(2)` is documented And if it does anything that isn't async-signal-safe, then all bets are off. So, the Fil-C implementation of vfork(2) would have to have some way of checking (either statically or dynamically) that nothing async-signal-unsafe happens. That's the hard bit. That's why I think that implementing it is crazy. I'd…

The other place it comes up is launchers and resource managers. We actually have a series of old issues and implementation work on flux (large scale resource manager for clusters) working around fork becoming a significant bottleneck in parallel launch. IIRC it showed up when we had ~1gb of memory in use and needed to spawn between 64 and 192 processes per node. That said, we actually didn’t pivot to vfork, we pivote…

> The other place it comes up is launchers and resource managers.

Yes, and typically for the same reasons as in JVMs etc: `vfork()` is just faster.

Re: Safepoints and Fil-C

#39

Earlier quoted context omitted.

Yes, _that_ is not to be allowed. I think you could have LLVM know about `vfork(2)` and treat that as an error -- heck, clang already knows how to do that, does it not?

That's just one example and the problem isn't just checking this one case, but any generalization of it. It can't be a fully static check because you could achieve similar things with longjmp or exceptions (both of which Fil-C supports). And then there are similar issues with heap accesses and safepoints. The vfork child has to particular in safepoints except that it cannot quite (you can't use pthread_mutex/pthread_…

Another option is to make `posix_spawn(3)` in the program's C library work with Fil-C to let Fil-C implement it w/o instrumentation in its C library. This would work for me.

Re: Safepoints and Fil-C

#40

Earlier quoted context omitted.

That's just one example and the problem isn't just checking this one case, but any generalization of it. It can't be a fully static check because you could achieve similar things with longjmp or exceptions (both of which Fil-C supports). And then there are similar issues with heap accesses and safepoints. The vfork child has to particular in safepoints except that it cannot quite (you can't use pthread_mutex/pthread_…

Can we make the C library mutex lock and condvar primitives work on the vfork() child? It's practically like a thread...

That might be the way to go but my best ideas for how to make vfork work sidestep all of that.

It's just a lot of work. It basically means that the whole Fil-C runtime has to be aware of this alternate mode where we're the vfork child and we have to play by different rules.

Anyway, long story short:

- Yeah I know vfork(2) is important. It's just not the most important thing on my plate. The constant time crypto situation we were talking about in the other thread is definitely more important, for example!

- I know how to do vfork(2) but every version of it that I've come up with is a ton of work and carries the risk of introducing really wacky stability bugs and safety bugs.

So, vfork is just a high risk, high cost, medium reward, medium urgency kind of thing. That probably means it'll be a while before I implement it.

Post reply on HN