summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2020-04-30 18:57:55 +0300
committerDavid Sterba <dsterba@suse.com>2020-05-25 12:25:34 +0300
commitba8a9a0537770df69d9dc38c11312c9b0f840cf2 (patch)
tree5d5f54bb5fa505011ff196dcf27432ddf98de456
parent84da071f3df5a9c0df0352d1c52b0c36ddb1c53f (diff)
downloadlinux-ba8a9a0537770df69d9dc38c11312c9b0f840cf2.tar.xz
btrfs: optimize split page read in btrfs_get_token_##bits
The fallback path calls helper read_extent_buffer to do read of the data spanning two extent buffer pages. As the size is known, we can do the read directly in two steps. This removes one function call and compiler can optimize memcpy as the sizes are known at compile time. The cached token address is set to the second page. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/struct-funcs.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index 46a7269bee07..63cab91507f8 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -66,7 +66,8 @@ u##bits btrfs_get_token_##bits(struct btrfs_map_token *token, \
const unsigned long idx = member_offset >> PAGE_SHIFT; \
const unsigned long oip = offset_in_page(member_offset); \
const int size = sizeof(u##bits); \
- __le##bits leres; \
+ u8 lebytes[sizeof(u##bits)]; \
+ const int part = PAGE_SIZE - oip; \
\
ASSERT(token); \
ASSERT(token->kaddr); \
@@ -75,15 +76,16 @@ u##bits btrfs_get_token_##bits(struct btrfs_map_token *token, \
member_offset + size <= token->offset + PAGE_SIZE) { \
return get_unaligned_le##bits(token->kaddr + oip); \
} \
- if (oip + size <= PAGE_SIZE) { \
- token->kaddr = page_address(token->eb->pages[idx]); \
- token->offset = idx << PAGE_SHIFT; \
+ token->kaddr = page_address(token->eb->pages[idx]); \
+ token->offset = idx << PAGE_SHIFT; \
+ if (oip + size <= PAGE_SIZE) \
return get_unaligned_le##bits(token->kaddr + oip); \
- } \
+ \
+ memcpy(lebytes, token->kaddr + oip, part); \
token->kaddr = page_address(token->eb->pages[idx + 1]); \
token->offset = (idx + 1) << PAGE_SHIFT; \
- read_extent_buffer(token->eb, &leres, member_offset, size); \
- return le##bits##_to_cpu(leres); \
+ memcpy(lebytes + part, token->kaddr, size - part); \
+ return get_unaligned_le##bits(lebytes); \
} \
u##bits btrfs_get_##bits(const struct extent_buffer *eb, \
const void *ptr, unsigned long off) \