Skip to content

Conversation

jounathaen
Copy link
Member

I had buggy code that was using lseek.

Turns out, FUSE is a little odd in that regard (I might be wrong, but this is how it looks to me):

  • All reads and writes in FUSE are referenced to an absolute offset.
  • For that reason, reads and writes don't change the file offset in virtiofsd (it uses preadv64 internally)
  • Lseek does exist in FUSE and in virtiofsd it maps to the host's lseek. It also returns the host's lseek return value.
  • In Hermit, this also seems to return meaningful results for seeks from the start and the end, but since a read/write doesn't change the file offset, lseek with a Cur whence doesn't return a meaningful value.
  • As mentioned before, read/write in virtiofsd is not affected by the file offset, therefore simply forwarding lseek to the deamon is not sufficient for seeking through a file (we already use an internal offset correctly in these cases).

This PR fixes the incorrect behaviour in lseek by:

  • only calling virtiofsd for lseeks relative to the file's end (we don't know the size of the file in Hermit, so this inevitable)
  • updating the offset in case of Set and Cur.

This should have a slightly positive effect on the performance, since it reduces virtio transactions.

Note that this is not tested for Data and Hole, so these might still be buggy.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Benchmark Results

Benchmark Current: c441518 Previous: 250f22e Performance Ratio
startup_benchmark Build Time 137.67 s 124.48 s 1.11
startup_benchmark File Size 0.91 MB 0.91 MB 1.00
Startup Time - 1 core 0.94 s (±0.01 s) 0.93 s (±0.02 s) 1.01
Startup Time - 2 cores 0.95 s (±0.02 s) 0.93 s (±0.03 s) 1.02
Startup Time - 4 cores 0.96 s (±0.02 s) 0.95 s (±0.02 s) 1.01
multithreaded_benchmark Build Time 139.44 s 122.65 s 1.14
multithreaded_benchmark File Size 1.02 MB 1.02 MB 1.00
Multithreaded Pi Efficiency - 2 Threads 3.22 % (±15.47 %) 2.79 % (±13.37 %) 1.16
Multithreaded Pi Efficiency - 4 Threads 1.76 % (±8.46 %) 1.58 % (±7.57 %) 1.12
Multithreaded Pi Efficiency - 8 Threads 0.85 % (±4.10 %) 0.82 % (±3.93 %) 1.04
micro_benchmarks Build Time 171.86 s 145.61 s 1.18
micro_benchmarks File Size 1.02 MB 1.03 MB 1.00
Scheduling time - 1 thread 3.78 ticks (±18.15 ticks) 3.05 ticks (±14.65 ticks) 1.24
Scheduling time - 2 threads 1.57 ticks (±7.53 ticks) 1.56 ticks (±7.50 ticks) 1.00
Micro - Time for syscall (getpid) 0.20 ticks (±0.94 ticks) 0.18 ticks (±0.86 ticks) 1.09
Memcpy speed - (built_in) block size 4096 1250.00 MByte/s (±6000.00 MByte/s) 1313.03 MByte/s (±6302.52 MByte/s) 0.95
Memcpy speed - (built_in) block size 1048576 554.00 MByte/s (±2659.21 MByte/s) 692.52 MByte/s (±3324.10 MByte/s) 0.80
Memcpy speed - (built_in) block size 16777216 205.21 MByte/s (±984.99 MByte/s) 211.07 MByte/s (±1013.12 MByte/s) 0.97
Memset speed - (built_in) block size 4096 1290.32 MByte/s (±6193.55 MByte/s) 1290.32 MByte/s (±6193.55 MByte/s) 1
Memset speed - (built_in) block size 1048576 1339.18 MByte/s (±6428.07 MByte/s) 1331.78 MByte/s (±6392.54 MByte/s) 1.01
Memset speed - (built_in) block size 16777216 873.30 MByte/s (±4191.82 MByte/s) 866.63 MByte/s (±4159.85 MByte/s) 1.01
Memcpy speed - (rust) block size 4096 1304.35 MByte/s (±6260.87 MByte/s) 960.00 MByte/s (±4608.00 MByte/s) 1.36
Memcpy speed - (rust) block size 1048576 501.56 MByte/s (±2407.49 MByte/s) 562.78 MByte/s (±2701.33 MByte/s) 0.89
Memcpy speed - (rust) block size 16777216 206.11 MByte/s (±989.32 MByte/s) 203.06 MByte/s (±974.70 MByte/s) 1.01
Memset speed - (rust) block size 4096 1578.95 MByte/s (±7578.95 MByte/s) 1500.00 MByte/s (±7200.00 MByte/s) 1.05
Memset speed - (rust) block size 1048576 979.55 MByte/s (±4701.85 MByte/s) 1289.16 MByte/s (±6187.96 MByte/s) 0.76
Memset speed - (rust) block size 16777216 880.28 MByte/s (±4225.35 MByte/s) 882.37 MByte/s (±4235.38 MByte/s) 1.00
alloc_benchmarks Build Time 159.83 s 141.09 s 1.13
alloc_benchmarks File Size 0.98 MB 0.98 MB 1.00
Allocations - Allocation success 2.00 % (±13.86 %) 2.00 % (±13.86 %) 1
Allocations - Deallocation success 1.40 % (±9.69 %) 1.40 % (±9.74 %) 1.00
Allocations - Pre-fail Allocations 2.00 % (±13.86 %) 2.00 % (±13.86 %) 1
Allocations - Average Allocation time 261.32 Ticks (±1810.83 Ticks) 245.11 Ticks (±1698.52 Ticks) 1.07
Allocations - Average Allocation time (no fail) 261.32 Ticks (±1810.83 Ticks) 245.11 Ticks (±1698.52 Ticks) 1.07
Allocations - Average Deallocation time 17.32 Ticks (±119.99 Ticks) 17.05 Ticks (±118.16 Ticks) 1.02
mutex_benchmark Build Time 156.02 s 142.06 s 1.10
mutex_benchmark File Size 1.03 MB 1.03 MB 1.00
Mutex Stress Test Average Time per Iteration - 1 Threads 0.30 ns (±2.08 ns) 0.34 ns (±2.36 ns) 0.88
Mutex Stress Test Average Time per Iteration - 2 Threads 0.38 ns (±2.63 ns) 0.36 ns (±2.49 ns) 1.06

This comment was automatically generated by workflow using github-action-benchmark.

@mkroening mkroening self-assigned this Sep 17, 2025
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.

2 participants