fsverity: remove hash page spin lock
authorAndrey Albershteyn <aalbersh@redhat.com>
Thu, 1 Feb 2024 05:28:13 +0000 (21:28 -0800)
committerEric Biggers <ebiggers@google.com>
Thu, 1 Feb 2024 23:19:23 +0000 (15:19 -0800)
commit8e43fb06e10d2c811797740dd578c5099a3e6378
tree15bfa2a8fa3c5a968812a6dd4f29465bf7b4725a
parent41bccc98fb7931d63d03f326a746ac4d429c1dd3
fsverity: remove hash page spin lock

The spin lock is not necessary here as it can be replaced with
memory barrier which should be better performance-wise.

When Merkle tree block size differs from page size, in
is_hash_block_verified() two things are modified during check - a
bitmap and PG_checked flag of the page.

Each bit in the bitmap represent verification status of the Merkle
tree blocks. PG_checked flag tells if page was just re-instantiated
or was in pagecache. Both of this states are shared between
verification threads. Page which was re-instantiated can not have
already verified blocks (bit set in bitmap).

The spin lock was used to allow only one thread to modify both of
these states and keep order of operations. The only requirement here
is that PG_Checked is set strictly after bitmap is updated.
This way other threads which see that PG_Checked=1 (page cached)
knows that bitmap is up-to-date. Otherwise, if PG_Checked is set
before bitmap is cleared, other threads can see bit=1 and therefore
will not perform verification of that Merkle tree block.

However, there's still the case when one thread is setting a bit in
verify_data_block() and other thread is clearing it in
is_hash_block_verified(). This can happen if two threads get to
!PageChecked branch and one of the threads is rescheduled before
resetting the bitmap. This is fine as at worst blocks are
re-verified in each thread.

Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
[ebiggers: improved the comment and removed the 'verified' variable]
Link: https://lore.kernel.org/r/20240201052813.68380-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
fs/verity/fsverity_private.h
fs/verity/open.c
fs/verity/verify.c