Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: better packing of btrfs_delayed_extent_op

btrfs_delayed_extent_op can be packed in a better way, it's 40 bytes now
and has 8 unused bytes. Reducing the level type to u8 makes it possible
to squeeze it to the padding byte after key. The bitfields were switched
to bool as there's space to store the full byte without increasing the
whole structure, besides that the generated assembly is smaller.

struct btrfs_delayed_extent_op {
struct btrfs_disk_key key; /* 0 17 */
u8 level; /* 17 1 */
bool update_key; /* 18 1 */
bool update_flags; /* 19 1 */
bool is_data; /* 20 1 */

/* XXX 3 bytes hole, try to pack */

u64 flags_to_set; /* 24 8 */

/* size: 32, cachelines: 1, members: 6 */
/* sum members: 29, holes: 1, sum holes: 3 */
/* last cacheline: 32 bytes */
};

The final size is 32 bytes which gives +26 object per slab page.

text data bss dec hex filename
938811 43670 23144 1005625 f5839 fs/btrfs/btrfs.ko.before
938747 43670 23144 1005561 f57f9 fs/btrfs/btrfs.ko.after

Signed-off-by: David Sterba <dsterba@suse.com>

+12 -15
+2 -2
fs/btrfs/delayed-ref.c
··· 493 493 memcpy(&existing_ref->extent_op->key, 494 494 &ref->extent_op->key, 495 495 sizeof(ref->extent_op->key)); 496 - existing_ref->extent_op->update_key = 1; 496 + existing_ref->extent_op->update_key = true; 497 497 } 498 498 if (ref->extent_op->update_flags) { 499 499 existing_ref->extent_op->flags_to_set |= 500 500 ref->extent_op->flags_to_set; 501 - existing_ref->extent_op->update_flags = 1; 501 + existing_ref->extent_op->update_flags = true; 502 502 } 503 503 btrfs_free_delayed_extent_op(ref->extent_op); 504 504 }
+4 -4
fs/btrfs/delayed-ref.h
··· 75 75 76 76 struct btrfs_delayed_extent_op { 77 77 struct btrfs_disk_key key; 78 + u8 level; 79 + bool update_key; 80 + bool update_flags; 81 + bool is_data; 78 82 u64 flags_to_set; 79 - int level; 80 - unsigned int update_key:1; 81 - unsigned int update_flags:1; 82 - unsigned int is_data:1; 83 83 }; 84 84 85 85 /*
+6 -9
fs/btrfs/extent-tree.c
··· 2988 2988 return -ENOMEM; 2989 2989 2990 2990 extent_op->flags_to_set = flags; 2991 - extent_op->update_flags = 1; 2992 - extent_op->update_key = 0; 2993 - extent_op->is_data = is_data ? 1 : 0; 2991 + extent_op->update_flags = true; 2992 + extent_op->update_key = false; 2993 + extent_op->is_data = is_data ? true : false; 2994 2994 extent_op->level = level; 2995 2995 2996 2996 ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, ··· 7980 7980 else 7981 7981 memset(&extent_op->key, 0, sizeof(extent_op->key)); 7982 7982 extent_op->flags_to_set = flags; 7983 - if (skinny_metadata) 7984 - extent_op->update_key = 0; 7985 - else 7986 - extent_op->update_key = 1; 7987 - extent_op->update_flags = 1; 7988 - extent_op->is_data = 0; 7983 + extent_op->update_key = skinny_metadata ? false : true; 7984 + extent_op->update_flags = true; 7985 + extent_op->is_data = false; 7989 7986 extent_op->level = level; 7990 7987 7991 7988 ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
fs/btrfs/extent-tree.h