[PATCH] serial: 8250: Reorder fields in 'struct plat_serial8250_port'

From: Christophe JAILLET
Date: Fri Feb 17 2023 - 15:23:10 EST


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@xxxxxxxxxx>
---
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(-)

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 *,
--
2.34.1