[PATCH] nvmet: Reorder fields in 'struct nvmet_ns'

From: Christophe JAILLET
Date: Thu Apr 27 2023 - 15:47:58 EST


Group some variables based on their sizes to reduce holes.
On x86_64, this shrinks the size of 'struct nvmet_ns' from 520 to 512
bytes.

When such a structure is allocated in nvmet_ns_alloc(), because of the way
memory allocation works, when 520 bytes were requested, 1024 bytes were
allocated.

So, on x86_64, this change saves 512 bytes per allocation.

Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx>
---
More aggressive grouping could be done to be more future proof, but the
way the struct nvmet_ns is written suggest that some fields should be
kept together. So keep grouping as-is.


Using pahole

Before:
======
struct nvmet_ns {
struct percpu_ref ref; /* 0 16 */
struct block_device * bdev; /* 16 8 */
struct file * file; /* 24 8 */
bool readonly; /* 32 1 */

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

u32 nsid; /* 36 4 */
u32 blksize_shift; /* 40 4 */

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

loff_t size; /* 48 8 */
u8 nguid[16]; /* 56 16 */
/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
uuid_t uuid; /* 72 16 */
u32 anagrpid; /* 88 4 */
bool buffered_io; /* 92 1 */
bool enabled; /* 93 1 */

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

struct nvmet_subsys * subsys; /* 96 8 */
const char * device_path; /* 104 8 */
struct config_group device_group; /* 112 136 */
/* --- cacheline 3 boundary (192 bytes) was 56 bytes ago --- */
struct config_group group; /* 248 136 */
/* --- cacheline 6 boundary (384 bytes) --- */
struct completion disable_done; /* 384 96 */
/* --- cacheline 7 boundary (448 bytes) was 32 bytes ago --- */
mempool_t * bvec_pool; /* 480 8 */
int use_p2pmem; /* 488 4 */

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

struct pci_dev * p2p_dev; /* 496 8 */
int pi_type; /* 504 4 */
int metadata_size; /* 508 4 */
/* --- cacheline 8 boundary (512 bytes) --- */
u8 csi; /* 512 1 */

/* size: 520, cachelines: 9, members: 23 */
/* sum members: 500, holes: 4, sum holes: 13 */
/* padding: 7 */
/* last cacheline: 8 bytes */
};

After:
=====
struct nvmet_ns {
struct percpu_ref ref; /* 0 16 */
struct block_device * bdev; /* 16 8 */
struct file * file; /* 24 8 */
bool readonly; /* 32 1 */

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

u32 nsid; /* 36 4 */
u32 blksize_shift; /* 40 4 */

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

loff_t size; /* 48 8 */
u8 nguid[16]; /* 56 16 */
/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
uuid_t uuid; /* 72 16 */
u32 anagrpid; /* 88 4 */
bool buffered_io; /* 92 1 */
bool enabled; /* 93 1 */

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

struct nvmet_subsys * subsys; /* 96 8 */
const char * device_path; /* 104 8 */
struct config_group device_group; /* 112 136 */
/* --- cacheline 3 boundary (192 bytes) was 56 bytes ago --- */
struct config_group group; /* 248 136 */
/* --- cacheline 6 boundary (384 bytes) --- */
struct completion disable_done; /* 384 96 */
/* --- cacheline 7 boundary (448 bytes) was 32 bytes ago --- */
mempool_t * bvec_pool; /* 480 8 */
struct pci_dev * p2p_dev; /* 488 8 */
int use_p2pmem; /* 496 4 */
int pi_type; /* 500 4 */
int metadata_size; /* 504 4 */
u8 csi; /* 508 1 */

/* size: 512, cachelines: 8, members: 23 */
/* sum members: 500, holes: 3, sum holes: 9 */
/* padding: 3 */
};
---
drivers/nvme/target/nvmet.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index dc60a22646f7..c50146085fb5 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -79,8 +79,8 @@ struct nvmet_ns {
struct completion disable_done;
mempool_t *bvec_pool;

- int use_p2pmem;
struct pci_dev *p2p_dev;
+ int use_p2pmem;
int pi_type;
int metadata_size;
u8 csi;
--
2.34.1