diff mbox series

btrfs: add little-endian optimized key helpers

Message ID 20200609194926.9343-1-dsterba@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: add little-endian optimized key helpers | expand

Commit Message

David Sterba June 9, 2020, 7:49 p.m. UTC
The CPU and on-disk keys are mapped to two different structures because
of the endianity. There's an intermediate buffer used to do the
conversion, but this is not necessary when CPU and on-disk endianity
matches.

Add optimized versions of helpers that take disk_key and use the buffer
directly for CPU keys or drop the intermediate buffer and conversion.

This saves a lot of stack space accross many functions and removes about
6K of generated binary code:

   text    data     bss     dec     hex filename
1090439   17468   14912 1122819  112203 pre/btrfs.ko
1084613   17456   14912 1116981  110b35 post/btrfs.ko

Delta: -5826

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/ctree.c | 17 +++++++++++++++++
 fs/btrfs/ctree.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

Comments

Nikolay Borisov June 10, 2020, 7 a.m. UTC | #1
On 9.06.20 г. 22:49 ч., David Sterba wrote:
> The CPU and on-disk keys are mapped to two different structures because
> of the endianity. There's an intermediate buffer used to do the
> conversion, but this is not necessary when CPU and on-disk endianity
> matches.
> 
> Add optimized versions of helpers that take disk_key and use the buffer
> directly for CPU keys or drop the intermediate buffer and conversion.
> 
> This saves a lot of stack space accross many functions and removes about
> 6K of generated binary code:
> 
>    text    data     bss     dec     hex filename
> 1090439   17468   14912 1122819  112203 pre/btrfs.ko
> 1084613   17456   14912 1116981  110b35 post/btrfs.ko
> 
> Delta: -5826
> 
> Signed-off-by: David Sterba <dsterba@suse.com>

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Johannes Thumshirn June 10, 2020, 7:51 a.m. UTC | #2
One question, why endianity instead of endianess?
I think the latter is more common (in fact I had to google 
to see if the former even exists)

Otherwise
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
David Sterba June 10, 2020, 8:33 a.m. UTC | #3
On Wed, Jun 10, 2020 at 07:51:55AM +0000, Johannes Thumshirn wrote:
> One question, why endianity instead of endianess?
> I think the latter is more common (in fact I had to google 
> to see if the former even exists)

It exists but you're right that endianness (double n) is more common,
I'll fix it. Thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3a7648bff42c..de7ad39bcafd 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1501,6 +1501,22 @@  static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
 	return 0;
 }
 
+#ifdef __LITTLE_ENDIAN
+
+/*
+ * Compare two keys, on little-endian the disk order is same as CPU order and
+ * we can avoid the conversion.
+ */
+static int comp_keys(const struct btrfs_disk_key *disk_key,
+		     const struct btrfs_key *k2)
+{
+	const struct btrfs_key *k1 = (const struct btrfs_key *)disk_key;
+
+	return btrfs_comp_cpu_keys(k1, k2);
+}
+
+#else
+
 /*
  * compare two keys in a memcmp fashion
  */
@@ -1513,6 +1529,7 @@  static int comp_keys(const struct btrfs_disk_key *disk,
 
 	return btrfs_comp_cpu_keys(&k1, k2);
 }
+#endif
 
 /*
  * same as comp_keys only with two btrfs_key's
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 161533040978..5aa68119122f 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1894,6 +1894,52 @@  BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
 BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64);
 BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8);
 
+#ifdef __LITTLE_ENDIAN
+
+/*
+ * Optimized helpers for little-endian architectures where CPU and on-disk
+ * structures have the same endianity and we can skip conversions.
+ */
+
+static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu_key,
+					 const struct btrfs_disk_key *disk_key)
+{
+	memcpy(cpu_key, disk_key, sizeof(struct btrfs_key));
+}
+
+static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk_key,
+					 const struct btrfs_key *cpu_key)
+{
+	memcpy(disk_key, cpu_key, sizeof(struct btrfs_key));
+}
+
+static inline void btrfs_node_key_to_cpu(const struct extent_buffer *eb,
+					 struct btrfs_key *cpu_key, int nr)
+{
+	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;
+
+	btrfs_node_key(eb, disk_key, nr);
+}
+
+static inline void btrfs_item_key_to_cpu(const struct extent_buffer *eb,
+					 struct btrfs_key *cpu_key, int nr)
+{
+	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;
+
+	btrfs_item_key(eb, disk_key, nr);
+}
+
+static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb,
+					     const struct btrfs_dir_item *item,
+					     struct btrfs_key *cpu_key)
+{
+	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;
+
+	btrfs_dir_item_key(eb, item, disk_key);
+}
+
+#else
+
 static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
 					 const struct btrfs_disk_key *disk)
 {
@@ -1935,6 +1981,8 @@  static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb,
 	btrfs_disk_key_to_cpu(key, &disk_key);
 }
 
+#endif
+
 /* struct btrfs_header */
 BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,