[PATCH mptcp-next v6 04/10] mptcp: align struct mptcp_data_frag to 8 bytes on 32-bit
Geliang Tang <[email protected]> Thu, 16 Jul 2026 15:50:43 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <fde91a05b425374188400a291bd91058a5017217.1784188064.git.tanggeliang@kylinos.cn> |
From: Geliang Tang <[email protected]> mptcp_carve_data_frag() places a struct mptcp_data_frag inside a page-frag region, using ALIGN(orig_offset, sizeof(long)) to compute the offset where the struct lives. On 64-bit Linux sizeof(long) is 8 and this works as intended. On 32-bit Linux sizeof(long) is 4, which only guarantees 4-byte alignment for the struct. struct mptcp_data_frag contains a u64 data_seq member, which requires 8-byte alignment. 4-byte-aligned 64-bit loads fault on 32-bit architectures that do not handle unaligned 64-bit accesses in hardware (armv7, mips, sparc, ...). The in-source comment near BUILD_BUG_ON that states "ALIGN(1, sizeof(long)) - 1, so 8-1" is misleading because it implicitly assumes sizeof(long) is always 8. Switch both the ALIGN() and the matching BUILD_BUG_ON to sizeof(u64) so the 8-byte alignment is enforced on every architecture, and the overhead u8 budget still fits the worst-case 7-byte padding plus the struct size. This is a no-op on 64-bit and a correctness fix on 32-bit. Signed-off-by: Geliang Tang <[email protected]> --- net/mptcp/protocol.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 3acd61ae6160..7ad3a4a09e3b 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1237,7 +1237,7 @@ static struct mptcp_data_frag * mptcp_carve_data_frag(const struct mptcp_sock *msk, struct page_frag *pfrag, int orig_offset) { - int offset = ALIGN(orig_offset, sizeof(long)); + int offset = ALIGN(orig_offset, sizeof(u64)); struct mptcp_data_frag *dfrag; dfrag = (struct mptcp_data_frag *)(page_to_virt(pfrag->page) + offset); @@ -4789,9 +4789,9 @@ void __init mptcp_proto_init(void) BUILD_BUG_ON(sizeof(struct mptcp_skb_cb) > sizeof_field(struct sk_buff, cb)); /* struct mptcp_data_frag: 'overhead' corresponds to the alignment - * (ALIGN(1, sizeof(long)) - 1, so 8-1) + the struct's size + * (ALIGN(1, sizeof(u64)) - 1, so 8-1) + the struct's size */ - BUILD_BUG_ON(ALIGN(1, sizeof(long)) - 1 + sizeof(struct mptcp_data_frag) + BUILD_BUG_ON(ALIGN(1, sizeof(u64)) - 1 + sizeof(struct mptcp_data_frag) > U8_MAX); } -- 2.53.0