serial: 8250: Reorder fields in 'struct plat_serial8250_port'

Message ID f3cb1efe1454e0615840fd331ee335bc441589a9.1676665358.git.christophe.jaillet@wanadoo.fr
State New
Headers
Series serial: 8250: Reorder fields in 'struct plat_serial8250_port' |

Commit Message

Christophe JAILLET Feb. 17, 2023, 8:22 p.m. UTC
  Group some variables based on their sizes to reduce hole and avoid padding.
On x86_64, this shrinks the size of 'struct plat_serial8250_port'
from 144 to 128 bytes.

It saves a few bytes of memory.

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

Before:
======
struct plat_serial8250_port {
	long unsigned int          iobase;               /*     0     8 */
	void *                     membase;              /*     8     8 */
	resource_size_t            mapbase;              /*    16     8 */
	unsigned int               irq;                  /*    24     4 */

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

	long unsigned int          irqflags;             /*    32     8 */
	unsigned int               uartclk;              /*    40     4 */

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

	void *                     private_data;         /*    48     8 */
	unsigned char              regshift;             /*    56     1 */
	unsigned char              iotype;               /*    57     1 */
	unsigned char              hub6;                 /*    58     1 */
	unsigned char              has_sysrq;            /*    59     1 */

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

	/* --- cacheline 1 boundary (64 bytes) --- */
	upf_t                      flags;                /*    64     8 */
	unsigned int               type;                 /*    72     4 */

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

	unsigned int               (*serial_in)(struct uart_port *, int); /*    80     8 */
	void                       (*serial_out)(struct uart_port *, int, int); /*    88     8 */
	void                       (*set_termios)(struct uart_port *, struct ktermios *, const struct ktermios  *); /*    96     8 */
	void                       (*set_ldisc)(struct uart_port *, struct ktermios *); /*   104     8 */
	unsigned int               (*get_mctrl)(struct uart_port *); /*   112     8 */
	int                        (*handle_irq)(struct uart_port *); /*   120     8 */
	/* --- cacheline 2 boundary (128 bytes) --- */
	void                       (*pm)(struct uart_port *, unsigned int, unsigned int); /*   128     8 */
	void                       (*handle_break)(struct uart_port *); /*   136     8 */

	/* size: 144, cachelines: 3, members: 21 */
	/* sum members: 128, holes: 4, sum holes: 16 */
	/* last cacheline: 16 bytes */
};

After:
=====
struct plat_serial8250_port {
	long unsigned int          iobase;               /*     0     8 */
	void *                     membase;              /*     8     8 */
	resource_size_t            mapbase;              /*    16     8 */
	unsigned int               uartclk;              /*    24     4 */
	unsigned int               irq;                  /*    28     4 */
	long unsigned int          irqflags;             /*    32     8 */
	void *                     private_data;         /*    40     8 */
	unsigned char              regshift;             /*    48     1 */
	unsigned char              iotype;               /*    49     1 */
	unsigned char              hub6;                 /*    50     1 */
	unsigned char              has_sysrq;            /*    51     1 */
	unsigned int               type;                 /*    52     4 */
	upf_t                      flags;                /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	unsigned int               (*serial_in)(struct uart_port *, int); /*    64     8 */
	void                       (*serial_out)(struct uart_port *, int, int); /*    72     8 */
	void                       (*set_termios)(struct uart_port *, struct ktermios *, const struct ktermios  *); /*    80     8 */
	void                       (*set_ldisc)(struct uart_port *, struct ktermios *); /*    88     8 */
	unsigned int               (*get_mctrl)(struct uart_port *); /*    96     8 */
	int                        (*handle_irq)(struct uart_port *); /*   104     8 */
	void                       (*pm)(struct uart_port *, unsigned int, unsigned int); /*   112     8 */
	void                       (*handle_break)(struct uart_port *); /*   120     8 */

	/* size: 128, cachelines: 2, members: 21 */
};
---
 include/linux/serial_8250.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
  

Patch

diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 19376bee9667..741ed4807a9c 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -18,16 +18,16 @@  struct plat_serial8250_port {
 	unsigned long	iobase;		/* io base address */
 	void __iomem	*membase;	/* ioremap cookie or NULL */
 	resource_size_t	mapbase;	/* resource base */
+	unsigned int	uartclk;	/* UART clock rate */
 	unsigned int	irq;		/* interrupt number */
 	unsigned long	irqflags;	/* request_irq flags */
-	unsigned int	uartclk;	/* UART clock rate */
 	void            *private_data;
 	unsigned char	regshift;	/* register shift */
 	unsigned char	iotype;		/* UPIO_* */
 	unsigned char	hub6;
 	unsigned char	has_sysrq;	/* supports magic SysRq */
-	upf_t		flags;		/* UPF_* flags */
 	unsigned int	type;		/* If UPF_FIXED_TYPE */
+	upf_t		flags;		/* UPF_* flags */
 	unsigned int	(*serial_in)(struct uart_port *, int);
 	void		(*serial_out)(struct uart_port *, int, int);
 	void		(*set_termios)(struct uart_port *,