x86_64: support nested pages splitting - #2467
Conversation
5ca4eca to
59ea124
Compare
There was a problem hiding this comment.
Benchmark Results
Details
| Benchmark | Current: 8837a27 | Previous: 2e23902 | Performance Ratio |
|---|---|---|---|
| startup_benchmark Build Time | 92.82 s |
80.34 s |
1.16 ❗ |
| startup_benchmark File Size | 0.78 MB |
0.80 MB |
0.99 ❗ |
| Startup Time - 1 core | 0.74 s (±0.02 s) |
0.75 s (±0.02 s) |
0.99 |
| Startup Time - 2 cores | 0.74 s (±0.02 s) |
0.74 s (±0.02 s) |
1.00 |
| Startup Time - 4 cores | 0.76 s (±0.03 s) |
0.74 s (±0.02 s) |
1.02 |
| multithreaded_benchmark Build Time | 93.03 s |
82.11 s |
1.13 ❗ |
| multithreaded_benchmark File Size | 0.85 MB |
0.86 MB |
0.99 ❗ |
| Multithreaded Pi Efficiency - 2 Threads | 65.70 % (±6.81 %) |
85.89 % (±6.61 %) |
0.76 ❗ |
| Multithreaded Pi Efficiency - 4 Threads | 40.24 % (±2.95 %) |
43.43 % (±2.56 %) |
0.93 |
| Multithreaded Pi Efficiency - 8 Threads | 19.79 % (±1.58 %) |
25.76 % (±1.53 %) |
0.77 ❗ |
| micro_benchmarks Build Time | 217.77 s |
80.40 s |
2.71 ❗ |
| micro_benchmarks File Size | 0.85 MB |
0.86 MB |
0.99 ❗ |
| Scheduling time - 1 thread | 164.38 ticks (±33.38 ticks) |
62.65 ticks (±4.06 ticks) |
2.62 ❗ |
| Scheduling time - 2 threads | 100.90 ticks (±20.21 ticks) |
34.08 ticks (±4.10 ticks) |
2.96 ❗ |
| Micro - Time for syscall (getpid) | 9.67 ticks (±5.23 ticks) |
3.45 ticks (±0.58 ticks) |
2.80 ❗ |
| Memcpy speed - (built_in) block size 4096 | 58490.10 MByte/s (±41532.23 MByte/s) |
82448.38 MByte/s (±56997.13 MByte/s) |
0.71 |
| Memcpy speed - (built_in) block size 1048576 | 14333.03 MByte/s (±12172.88 MByte/s) |
30585.98 MByte/s (±24707.84 MByte/s) |
0.47 |
| Memcpy speed - (built_in) block size 16777216 | 12195.25 MByte/s (±10176.09 MByte/s) |
26340.06 MByte/s (±21720.96 MByte/s) |
0.46 |
| Memset speed - (built_in) block size 4096 | 58698.78 MByte/s (±41695.44 MByte/s) |
82292.76 MByte/s (±56891.50 MByte/s) |
0.71 |
| Memset speed - (built_in) block size 1048576 | 14616.19 MByte/s (±12288.45 MByte/s) |
31323.85 MByte/s (±25145.86 MByte/s) |
0.47 |
| Memset speed - (built_in) block size 16777216 | 12512.32 MByte/s (±10354.87 MByte/s) |
27104.68 MByte/s (±22209.94 MByte/s) |
0.46 |
| Memcpy speed - (rust) block size 4096 | 52449.35 MByte/s (±37761.57 MByte/s) |
74097.96 MByte/s (±51811.44 MByte/s) |
0.71 |
| Memcpy speed - (rust) block size 1048576 | 14174.24 MByte/s (±12309.70 MByte/s) |
30361.60 MByte/s (±24602.37 MByte/s) |
0.47 |
| Memcpy speed - (rust) block size 16777216 | 12101.79 MByte/s (±10077.95 MByte/s) |
27625.34 MByte/s (±22806.88 MByte/s) |
0.44 |
| Memset speed - (rust) block size 4096 | 54007.41 MByte/s (±38491.79 MByte/s) |
74373.47 MByte/s (±51976.48 MByte/s) |
0.73 |
| Memset speed - (rust) block size 1048576 | 14600.74 MByte/s (±12562.04 MByte/s) |
31110.89 MByte/s (±25033.24 MByte/s) |
0.47 |
| Memset speed - (rust) block size 16777216 | 12492.05 MByte/s (±10356.39 MByte/s) |
28386.93 MByte/s (±23265.03 MByte/s) |
0.44 |
| alloc_benchmarks Build Time | 211.35 s |
74.76 s |
2.83 ❗ |
| alloc_benchmarks File Size | 0.86 MB |
0.87 MB |
0.99 ❗ |
| Allocations - Allocation success | 91.38 % |
91.31 % |
1.00 ❗ |
| Allocations - Deallocation success | 100.00 % |
100.00 % |
1 |
| Allocations - Pre-fail Allocations | 61.60 % |
61.44 % |
1.00 ❗ |
| Allocations - Average Allocation time | 23995.69 Ticks (±1552.03 Ticks) |
5860.58 Ticks (±98.43 Ticks) |
4.09 ❗ |
| Allocations - Average Allocation time (no fail) | 24757.70 Ticks (±1857.39 Ticks) |
6554.81 Ticks (±92.86 Ticks) |
3.78 ❗ |
| Allocations - Average Deallocation time | 5516.43 Ticks (±1646.98 Ticks) |
1805.01 Ticks (±250.35 Ticks) |
3.06 ❗ |
| mutex_benchmark Build Time | 205.88 s |
79.82 s |
2.58 ❗ |
| mutex_benchmark File Size | 0.85 MB |
0.86 MB |
0.99 ❗ |
| Mutex Stress Test Average Time per Iteration - 1 Threads | 34.96 ns (±6.51 ns) |
12.10 ns (±0.41 ns) |
2.89 ❗ |
| Mutex Stress Test Average Time per Iteration - 2 Threads | 33.74 ns (±8.54 ns) |
40.26 ns (±1.68 ns) |
0.84 |
This comment was automatically generated by workflow using github-action-benchmark.
|
Also fixes #2402 |
mkroening
left a comment
There was a problem hiding this comment.
Could you add a motivation to the PR description? I assume this is for SEV communication pages that need 4k pages, right?
Would it be possible to avoid splitting pages and use a separate page allocator instead for these 4k pages? That way, we can avoid making this split implicit.
|
Yes, we could use a dedicated allocator ; but this is also useful because it makes it possible to call unmap/map for a page regardless of its size. Currently, unmapping à 4KiB page does not work if that page is part of a bigger page. If I remember correctly, this is required for the stack protection PR. |
|
Yeah, that's the exact implicitness that I mean. I would personally be more comfortable if page sizes were handled explicitly by the mapper and page splitting could be avoided. If there's no way around this, it is fine, though. Why does the stack protection PR need this? Can we not use fresh 4k pages there too? |
|
Because as a safety measure I remove any identity mapping for the physically addresses used for the stacks - ensuring nothing accidentally writes there using an old allocation
|
|
I would just leave the identity mapping. Do you think that is such a bad idea? |
|
I think it's better to have only one mapping per address, this way if for any reason/bug the identity address is used, it will cause a page fault instead of silently corrupting a stack somewhere.
It may be a bit overkill, but when I wrote this patch I was chasing after silent memory corruptions (that I was causing), so that's why
|
|
Okay then. Once you have rebased and put these reasons into the PR description or commit message, I will merge. |
59ea124 to
06003e7
Compare
06003e7 to
8837a27
Compare
|
I will discuss this next week, though. I am not very convinced that we should unmap identity-mapped memory. Linux does not do so either. |
Allows unmapping/mapping a page with a size lower than the actual mapping