[PATCH] spi: Reorder fields in 'struct spi_transfer'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Group some variables based on their sizes to reduce hole and avoid padding.
On x86_64, this shrinks the size from 144 to 128 bytes.

Turn 'timestamped' into a bitfield so that it can be easily merged with
some other bifields and move 'error'.

This should have no real impact on memory allocation because 'struct
spi_transfer' is mostly used on stack, but it can save a few cycles
when the structure is initialized or copied.

Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx>
---
Using pahole

Before:
======
struct spi_transfer {
	const void  *              tx_buf;               /*     0     8 */
	void *                     rx_buf;               /*     8     8 */
	unsigned int               len;                  /*    16     4 */

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

	dma_addr_t                 tx_dma;               /*    24     8 */
	dma_addr_t                 rx_dma;               /*    32     8 */
	struct sg_table            tx_sg;                /*    40    16 */
	struct sg_table            rx_sg;                /*    56    16 */
	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
	unsigned int               dummy_data:1;         /*    72: 0  4 */
	unsigned int               cs_off:1;             /*    72: 1  4 */
	unsigned int               cs_change:1;          /*    72: 2  4 */
	unsigned int               tx_nbits:3;           /*    72: 3  4 */
	unsigned int               rx_nbits:3;           /*    72: 6  4 */

	/* XXX 7 bits hole, try to pack */
	/* Bitfield combined with next fields */

	u8                         bits_per_word;        /*    74     1 */

	/* XXX 1 byte hole, try to pack */

	struct spi_delay           delay;                /*    76     4 */

	/* XXX last struct has 1 byte of padding */

	struct spi_delay           cs_change_delay;      /*    80     4 */

	/* XXX last struct has 1 byte of padding */

	struct spi_delay           word_delay;           /*    84     4 */

	/* XXX last struct has 1 byte of padding */

	u32                        speed_hz;             /*    88     4 */
	u32                        effective_speed_hz;   /*    92     4 */
	unsigned int               ptp_sts_word_pre;     /*    96     4 */
	unsigned int               ptp_sts_word_post;    /*   100     4 */
	struct ptp_system_timestamp * ptp_sts;           /*   104     8 */
	bool                       timestamped;          /*   112     1 */

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

	struct list_head           transfer_list;        /*   120    16 */
	/* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
	u16                        error;                /*   136     2 */

	/* size: 144, cachelines: 3, members: 24 */
	/* sum members: 124, holes: 3, sum holes: 12 */
	/* sum bitfield members: 9 bits, bit holes: 1, sum bit holes: 7 bits */
	/* padding: 6 */
	/* paddings: 3, sum paddings: 3 */
	/* last cacheline: 16 bytes */
};


After:
=====
struct spi_transfer {
	const void  *              tx_buf;               /*     0     8 */
	void *                     rx_buf;               /*     8     8 */
	unsigned int               len;                  /*    16     4 */
	u16                        error;                /*    20     2 */

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

	dma_addr_t                 tx_dma;               /*    24     8 */
	dma_addr_t                 rx_dma;               /*    32     8 */
	struct sg_table            tx_sg;                /*    40    16 */
	struct sg_table            rx_sg;                /*    56    16 */
	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
	unsigned int               dummy_data:1;         /*    72: 0  4 */
	unsigned int               cs_off:1;             /*    72: 1  4 */
	unsigned int               cs_change:1;          /*    72: 2  4 */
	unsigned int               tx_nbits:3;           /*    72: 3  4 */
	unsigned int               rx_nbits:3;           /*    72: 6  4 */
	unsigned int               timestamped:1;        /*    72: 9  4 */

	/* XXX 6 bits hole, try to pack */
	/* Bitfield combined with next fields */

	u8                         bits_per_word;        /*    74     1 */

	/* XXX 1 byte hole, try to pack */

	struct spi_delay           delay;                /*    76     4 */

	/* XXX last struct has 1 byte of padding */

	struct spi_delay           cs_change_delay;      /*    80     4 */

	/* XXX last struct has 1 byte of padding */

	struct spi_delay           word_delay;           /*    84     4 */

	/* XXX last struct has 1 byte of padding */

	u32                        speed_hz;             /*    88     4 */
	u32                        effective_speed_hz;   /*    92     4 */
	unsigned int               ptp_sts_word_pre;     /*    96     4 */
	unsigned int               ptp_sts_word_post;    /*   100     4 */
	struct ptp_system_timestamp * ptp_sts;           /*   104     8 */
	struct list_head           transfer_list;        /*   112    16 */

	/* size: 128, cachelines: 2, members: 24 */
	/* sum members: 123, holes: 2, sum holes: 3 */
	/* sum bitfield members: 10 bits, bit holes: 1, sum bit holes: 6 bits */
	/* paddings: 3, sum paddings: 3 */
};
---
 drivers/spi/spi.c       | 2 +-
 include/linux/spi/spi.h | 9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 9f5c6b9f5135..44b85a8d47f1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1927,7 +1927,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr,
 	/* Capture the resolution of the timestamp */
 	xfer->ptp_sts_word_post = progress;
 
-	xfer->timestamped = true;
+	xfer->timestamped = 1;
 }
 EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 988aabc31871..4fa26b9a3572 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1022,6 +1022,9 @@ struct spi_transfer {
 	void		*rx_buf;
 	unsigned	len;
 
+#define SPI_TRANS_FAIL_NO_START	BIT(0)
+	u16		error;
+
 	dma_addr_t	tx_dma;
 	dma_addr_t	rx_dma;
 	struct sg_table tx_sg;
@@ -1032,6 +1035,7 @@ struct spi_transfer {
 	unsigned	cs_change:1;
 	unsigned	tx_nbits:3;
 	unsigned	rx_nbits:3;
+	unsigned	timestamped:1;
 #define	SPI_NBITS_SINGLE	0x01 /* 1bit transfer */
 #define	SPI_NBITS_DUAL		0x02 /* 2bits transfer */
 #define	SPI_NBITS_QUAD		0x04 /* 4bits transfer */
@@ -1048,12 +1052,7 @@ struct spi_transfer {
 
 	struct ptp_system_timestamp *ptp_sts;
 
-	bool		timestamped;
-
 	struct list_head transfer_list;
-
-#define SPI_TRANS_FAIL_NO_START	BIT(0)
-	u16		error;
 };
 
 /**
-- 
2.34.1




[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux