gramine icon indicating copy to clipboard operation
gramine copied to clipboard

[LibOS] Do not perform `lock(&hdl->pos_lock)` on non-seeking handles

Open dimakuv opened this issue 2 years ago • 0 comments

Description of the changes

Handles can be file-like (allow seeking and thus have a file position) and stream-like (do not allow seeking and thus file position field pos is unused). Previously, LibOS emulations of read(), write(), sendfile(), etc. did not distinguish between file-like and stream-like handles and always acquired hdl->pos_lock.

This led to a bug on stream-like handles, in particular, on eventfd handles: read() and write() operations are blocking for eventfds, thus a blocking read() would acquire the hdl->pos_lock indefinitely and e.g. hang another thread that performs write() on same eventfd.

This commit fixes this bug by skipping this lock on stream-like handles. This has an additional performance benefit: stream-like handles like pipes, sockets and eventfds don't spend cycles in acquiring and releasing the lock inside the relevant (and very frequent) syscalls.


This bug was detected while working on https://github.com/gramineproject/gramine/pull/1728.

For context, this is the commit where this pos_lock was introduced: https://github.com/gramineproject/gramine/commit/e474134a4fd84fe72397e2f33a5a4e9950e06885#diff-d79d43998e924cff687e6a56d5f3b0643951f90b5b050730239d830e2f3e8b98

It's interesting to note that this bug does not exhibit itself on pipes, FIFOs and UNIX sockets (socketpairs). This is because these objects are unidirectional. I tried to write a test using a pipe or a socketpair first, but quickly realized that I can't write to and read from the same pipe/socket end even on normal Linux.

How to test this PR?

New LibOS regression test eventfd_read_then_write is added to test this bug fix.


This change is Reviewable

dimakuv avatar Jan 26 '24 12:01 dimakuv