-
Notifications
You must be signed in to change notification settings - Fork 200
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
[PAL-SGX] alternative gettimeofday() implementation for gramine #1799
Comments
I like this idea, seems more portable than what we currently have and still simple. |
I don't see any specific problems with this approach. The description by @jonathan-sha seems solid, I appreciate the details!
Do you mean you exit the SGX enclave and then perform two gettimeofday() calls? How do you calculate the latency of each of these calls? I guess if you do two such double-gettimeofday readings, you can learn the latency of each call, and thus you can calibrate TSC based on some math formula?
What does this "performing 2 extra ocalls that are far enough apart" mean exactly?
Yes, this turned out to be a mess. As soon as you go to virtualized environments, things become hairy. Each hypervisor/VMM uses a different way to report Invariant TSC...
I'm not sure how clock recalibration and timezones are related. Can you elaborate on this more? |
I think he meant just doing a gettimeofday-like ocall twice.
I think you don't need to? You can do rdtsc -> gettimeofday() -> wait some time -> rdtsc -> gettimeofday() and then subtract and divide.
See above (at least that's how I understand the idea).
It's unrelated, as stated by op ;) I think he just implemented it while working on this part of the codebase. |
How do we account for the latency of the |
Correct. From my experimentation, taking two time-points that are about 1sec apart is sufficient for getting sub-millisecond accuracy over time. I did a lot of experimentation with this, increasing the "calibration time", using clock_gettime in nanosecond accuracy instead of gettimeofday(). None of this noticeably improved the accuracy of the clock frequency. I tried accounting for the OCALL latency as well by adding the calibration rdtsc read to the OCALL itself, but this didn't help much either. Overall I think the current accuracy is acceptable.
gettimeofday() method returns an optional timezone struct, which is deprecated and shouldn't be used. When I take the "ground truth" timepoints (i.e. OCALL gettimeofday()) I retrieve this timezone and cache it in case it's ever needed by the caller. |
Some more details about the implementation... I implemented this as a state machine with the following states. Calling gettimeofday() at any point will call into the current state's handler.
This state machine guarantees we use the fast path whenever we can and OCALL when we need to, and over time we stay in sync with the host. |
Thanks @jonathan-sha! This looks very good. Feel free to submit a PR. (Though depending on the complexity of the PR, it may take a long time to review it.) |
But the method I explained already accounts for that? ("rdtsc -> gettimeofday() -> wait some time -> rdtsc -> gettimeofday()")
Notice that both RDTSC and gettimeofday include the same amount of each type of steps: RDTSC measures points 1-6 and gettimeofday measures 3-8. Both of them include exactly one OCALL entry execution and one OCALL return execution. |
Hey, sorry for the delay with this. I had some other things to take care of first. I opened an MR as draft - I have a few things I need to fix still
|
@jonathan-sha: Let's move the discussion about these points to the PR review, so we can discuss them next to the code (and in a single place). |
Description of the feature
Looking at the gettimeofday() implementation used by gramine, there are many similarities with an implementation we did for "native" sgx apps that we develop where I work. But, we also took some different approaches listed below.
I have working and highly tested code I can share with you, if you're interested in my implementation. It's currently written in c++ but if there's interest I will be happy to port it to c and add it to gramine.
This code was stressed and tested on azure, I know in the past gramine had some issues with the fast-path not working on azure?
Please let me know if this is interesting to you.
Why Gramine should implement it?
Out implementation is measured to run in ~47 cycles (with -O3 compile flag) which is faster than the ~60 cycles it takes to run gettimeofday() natively on the host!
Also, as an unrelated note, we do handle getting the (deprecated) timezone struct when re\calibrating our ground-truth, just in case some old code uses this parameter. I saw an issue regarding this still open on gramine.
The text was updated successfully, but these errors were encountered: