diff options
author | Andrey Albershteyn <aalbersh@redhat.com> | 2024-02-01 08:28:13 +0300 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2024-02-02 02:19:23 +0300 |
commit | 8e43fb06e10d2c811797740dd578c5099a3e6378 (patch) | |
tree | 15bfa2a8fa3c5a968812a6dd4f29465bf7b4725a /fs/verity/open.c | |
parent | 41bccc98fb7931d63d03f326a746ac4d429c1dd3 (diff) | |
download | linux-8e43fb06e10d2c811797740dd578c5099a3e6378.tar.xz |
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>
Diffstat (limited to 'fs/verity/open.c')
-rw-r--r-- | fs/verity/open.c | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/fs/verity/open.c b/fs/verity/open.c index 6c31a871b84b..fdeb95eca3af 100644 --- a/fs/verity/open.c +++ b/fs/verity/open.c @@ -239,7 +239,6 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode, err = -ENOMEM; goto fail; } - spin_lock_init(&vi->hash_page_init_lock); } return vi; |