From 1ed0f75d57aef3c447fbc78885c90421e40c1755 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 1 Jul 2025 19:23:52 +0200 Subject: [PATCH] btrfs: accessors: compile-time fast path for u16 Reading/writing 2 bytes (u16) may need 2 folios to be written to, each time it's just one byte so using memcpy for that is an overkill. Add a branch for the split case so that memcpy is now used for u32 and u64. Another side effect is that the u16 types now don't need additional stack space, everything fits to registers. Stack usage is reduced: btrfs_get_16 -8 (32 -> 24) btrfs_set_16 -16 (32 -> 16) Code size reduction: text data bss dec hex filename 1454691 115665 16088 1586444 18350c pre/btrfs.ko 1454459 115665 16088 1586212 183424 post/btrfs.ko DELTA: -232 Reviewed-by: Boris Burkov Signed-off-by: David Sterba --- fs/btrfs/accessors.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/accessors.c b/fs/btrfs/accessors.c index 547e9f8fb87d6..8df404b5f6a33 100644 --- a/fs/btrfs/accessors.c +++ b/fs/btrfs/accessors.c @@ -59,9 +59,15 @@ u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ likely(sizeof(u##bits) <= part)) \ return get_unaligned_le##bits(kaddr + oil); \ \ - memcpy(lebytes, kaddr + oil, part); \ - kaddr = folio_address(eb->folios[idx + 1]); \ - memcpy(lebytes + part, kaddr, sizeof(u##bits) - part); \ + if (sizeof(u##bits) == 2) { \ + lebytes[0] = *(kaddr + oil); \ + kaddr = folio_address(eb->folios[idx + 1]); \ + lebytes[1] = *kaddr; \ + } else { \ + memcpy(lebytes, kaddr + oil, part); \ + kaddr = folio_address(eb->folios[idx + 1]); \ + memcpy(lebytes + part, kaddr, sizeof(u##bits) - part); \ + } \ return get_unaligned_le##bits(lebytes); \ } \ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \ @@ -84,11 +90,16 @@ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \ put_unaligned_le##bits(val, kaddr + oil); \ return; \ } \ - \ put_unaligned_le##bits(val, lebytes); \ - memcpy(kaddr + oil, lebytes, part); \ - kaddr = folio_address(eb->folios[idx + 1]); \ - memcpy(kaddr, lebytes + part, sizeof(u##bits) - part); \ + if (sizeof(u##bits) == 2) { \ + *(kaddr + oil) = lebytes[0]; \ + kaddr = folio_address(eb->folios[idx + 1]); \ + *kaddr = lebytes[1]; \ + } else { \ + memcpy(kaddr + oil, lebytes, part); \ + kaddr = folio_address(eb->folios[idx + 1]); \ + memcpy(kaddr, lebytes + part, sizeof(u##bits) - part); \ + } \ } DEFINE_BTRFS_SETGET_BITS(8) -- 2.47.2