From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97B01367B8E for ; Thu, 16 Jul 2026 07:51:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188288; cv=none; b=ud/jslQazt3Qp7sE0ib80AadczCsCuuRIdokQZf6wkQHiaSVNVb0QMwAMf8v7g7NQTSnN3g4SRGtD8q23S85umTfJkZfYDHE1id/O/r06D4EH4Okgsi3N7GpPB1VA4CMYvAgVKszzqh2a1QyNhrzmxH9zW+jGH0Gkk7E4ix0K+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188288; c=relaxed/simple; bh=phbrK9CKbaX/jza/2ybdzrTHMLm34AsBjKs9vxqW4aQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IgKLULpg9yKJLDkUtZ9y5F68E20F6BZuvy566FNI4Rf3Z21veSLqusfOWCkEBckSjdiLGg+8MhXKLBLPvwfk5UA/0qUlv4tAbiTSUE8O9fuly0/nHM9d+Fx3cYqXZPKE63MnfpuJDqlZ9bmIUyFBYH7dUoYavXrBZCw3o6cjdDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KilayO48; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KilayO48" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26BCF1F000E9; Thu, 16 Jul 2026 07:51:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188287; bh=XtFWhmYdsPFoAA4a9XBCiFdmlUrhnXPg5kmRlJYXFxI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=KilayO48/HQ2UTtNNQVn/MTkS1tYrFMNe1ZsEb2As92t6PTUFdPyCUOtN/cJ+fjZC qtbB15L3ydk0iDDrRwCp9x3VtalaDLtUqqG3xWeT3/QBuV/ZDqFrKnOZ2PKJVD0UUB pzDWzdJTyE5QVCElAqk2kK1/Yes0Gjy1fSfurpOI0kKkSfDEyKV6cudtYOpPs+E2NA Y3T6hgoEYcVQ1DgNPFSty3Ji8ZcWJMStazx47Nq+VuSnb+qc0YGTPedFFpD4LcyauN 6KuR7xeLT0YVr9l5N1AELETBD0l+I5NB+dahiOZeI8woi4el/VEqRH3t5aPxEtWi7Y zty9WKeaZcocQ== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 01/10] ipv4: fix uninitialized memory in zerocopy cmsg Date: Thu, 16 Jul 2026 15:50:40 +0800 Message-ID: <95c4e348a1a222f83b143a4f526d0458f9d278af.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang When SOF_TIMESTAMPING_OPT_CMSG is enabled and applications read MSG_ZEROCOPY completion notifications from the error queue, the ipv4_datagram_support_cmsg() function attempts to read ip_hdr(skb)->saddr to populate IP_PKTINFO cmsg data. However, zerocopy completion notification skbs don't have IP headers, causing this read to access uninitialized memory which is then leaked to userspace via put_cmsg(). The issue occurs because the function checks PKTINFO_SKB_CB(skb)->ipi_ifind= ex (which aliases the ops pointer in ubuf_info_msgzc stored in skb->cb), and if non-NULL, proceeds to read ip_hdr(skb)->saddr without verifying that the skb actually has an IP header. Fix this by adding an early check for SO_EE_ORIGIN_ZEROCOPY and returning false, since zerocopy completion notifications don't have IP headers and IP_PKTINFO cmsg is not applicable to them. Fixes: f2457533c4d3 ("ipv4: support IP_PKTINFO cmsg for SO_TIMESTAMPING") Signed-off-by: Geliang Tang --- net/ipv4/ip_sockglue.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a55ef327ec93..59513f15e522 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -504,6 +504,12 @@ static bool ipv4_datagram_support_cmsg(const struct so= ck *sk, if (ee_origin =3D=3D SO_EE_ORIGIN_LOCAL) return false; =20 + /* Zerocopy completion notifications don't have IP headers, + * so IP_PKTINFO cmsg is not applicable. + */ + if (ee_origin =3D=3D SO_EE_ORIGIN_ZEROCOPY) + return false; + /* Support IP_PKTINFO on tstamp packets if requested, to correlate * timestamp with egress dev. Not possible for packets without iif * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F29102DAFA9 for ; Thu, 16 Jul 2026 07:51:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188290; cv=none; b=grLGn64dXluZ6ggCw98iwcDYS+DiP3Ah+3BAIs0a7cOc5Jsh+k9oUCJu62cZgrf40dxJQo6gyuYdLkMDiXDLzTpDVIpzrHiDdZh0//d0MiMKZe1HxRAP14iDNweBMBMkqAxt/1DDHogbVN8UEZH34OoweJFq46M5wvOp8h9/nlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188290; c=relaxed/simple; bh=jME7UwAhFGdpy0DC+LD1XLRwwMwYlVOX++7xseGcuGo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u8qv0EGbkW8oNuJDdXVgoidF/t6gay2nnsCoi0vSFHsyScOzVvmUT9MJsb8DTahtC1G/OEUQbTIx5lPnaQeYtZgFB/2AmTDrpU/GjSA88mSRiCOhPu+Tuy4Y6GS27xTKQV3306fBBSRyrIjPg0AgeOoDVM/C8IFIKy0TnIpLdEU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H6zFIZUh; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="H6zFIZUh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C95461F00A3D; Thu, 16 Jul 2026 07:51:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188288; bh=EYeyAMGYwgrEvRqPliDbY8/sG7cAJUpla97WO7oBIDM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=H6zFIZUhJzolP0YruYg7I6UbTO9VfTl1xNNaOgP/5FeDN1LmlzXJwnUO6SN/TVccg 3WSNLJfgQ8gGRjODzphS83mQC2rPpXt/kopBVZrN01prKwyz+mz4JPTByF7bSd1ev7 WyXsortBCIiy/cgPVDzJpRxwwqr9Pv+U2OaXIqX6FuL6sNecOIntOU5TZZQUUWqxkQ bY9KD8DJ+7SkSjk7y6qamergGiZpyZdnxms5H73CEWOzVv7zpo9GlRtoh697UxUhx6 0XW54H2ao50QbUVyoMCEagijqYEkk9MSNGEFLPqMnF1dwC6TYPZNY/nqxVKxUuzdMR qDdoghKxNFQ8g== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Paolo Abeni Subject: [PATCH mptcp-next v6 02/10] mptcp: use local variable tp in sendmsg_frag Date: Thu, 16 Jul 2026 15:50:41 +0800 Message-ID: <0ce0387fd4af494a5edd63730f8f1323da560ee9.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang In mptcp_sendmsg_frag(), tcp_sk(ssk) is called multiple times. Introduce a local variable 'tp' to hold the tcp_sock pointer and use it throughout the function. This avoids repeated dereferencing and improves code readability, with no functional change. Suggested-by: Paolo Abeni Signed-off-by: Geliang Tang --- net/mptcp/protocol.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index ffcf5a1788f6..1cab07b1b9b1 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1375,6 +1375,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct= sock *ssk, u64 data_seq =3D dfrag->data_seq + info->sent; int offset =3D dfrag->offset + info->sent; struct mptcp_sock *msk =3D mptcp_sk(sk); + struct tcp_sock *tp =3D tcp_sk(ssk); bool zero_window_probe =3D false; struct mptcp_ext *mpext =3D NULL; bool can_coalesce =3D false; @@ -1410,14 +1411,14 @@ static int mptcp_sendmsg_frag(struct sock *sk, stru= ct sock *ssk, mpext =3D mptcp_get_ext(skb); if (!mptcp_skb_can_collapse_to(data_seq, skb, mpext)) { TCP_SKB_CB(skb)->eor =3D 1; - tcp_mark_push(tcp_sk(ssk), skb); + tcp_mark_push(tp, skb); goto alloc_skb; } =20 i =3D skb_shinfo(skb)->nr_frags; can_coalesce =3D skb_can_coalesce(skb, i, dfrag->page, offset); if (!can_coalesce && i >=3D READ_ONCE(net_hotdata.sysctl_max_skb_frags))= { - tcp_mark_push(tcp_sk(ssk), skb); + tcp_mark_push(tp, skb); goto alloc_skb; } =20 @@ -1471,7 +1472,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct= sock *ssk, skb->truesize +=3D copy; sk_wmem_queued_add(ssk, copy); sk_mem_charge(ssk, copy); - WRITE_ONCE(tcp_sk(ssk)->write_seq, tcp_sk(ssk)->write_seq + copy); + WRITE_ONCE(tp->write_seq, tp->write_seq + copy); TCP_SKB_CB(skb)->end_seq +=3D copy; tcp_skb_pcount_set(skb, 0); =20 --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D302373BF1 for ; Thu, 16 Jul 2026 07:51:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188291; cv=none; b=kP4FRoshelZcTO3CAf/6tNr6q6nmxjsdA7Ll7+ItuO2tgJr9fN1Nb4RgJhJrmxzv044VZAroOZ+xCgQIWFrKXx0D6+Roig6p+gAA8WYi1rZbUVw9WHICALLiVQavPXz07OhQuYFEI2YBrWySDudLx79Lwiy6wo9+tkOUr8QWoTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188291; c=relaxed/simple; bh=ToNk3YwEnu0/41Bz65Jhmf7mP/kp7FtOhl033CMxfSc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=afTWahVVdUGm6GLx+ZNAT64K05PNet0fd4Jz1pJDG+x/auj6jlMrz7txee3hKIB85KvCmia25/Xo8JQSzu2uD5XEr2Y3+xiuiaKsMM8Lr6nSe9Q8nVYVwAdCn79bOHPe1a3X91yRTuFFRlNtTJH6B5oHrJmzFUc4KJBYS+TcPqo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BTrAH/qM; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BTrAH/qM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 438291F00A3A; Thu, 16 Jul 2026 07:51:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188290; bh=OJdlqIFmjbfcUmGYRyfiS4f033WFHYwhVddD91ohe94=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=BTrAH/qM+uJa4LlmwoYPbEZJBOWnLp7QJPJ/EF2CvGebmE2Y5OC2vXrCra2btCGCZ zUOK7hb8cI4t8ueDohNLwzHlfxy5LUPuxf6vPrDBwBR6O5YmRhE73BVZKEeXaA0esJ JlsIc57EGYkk1Acqve+beoHRPMG9ZBF4x/edG2MHb8+4zxasnRrpt6B5YE3/gCpKS8 SornGGGqJeoz1CwcRAMY+BKWUERZ6S3Utdb5hVnKPmxpOZA9ieKfwO8o3ZRiu1fHjk CheQA2r7JhJZMHH8y6uoPMNz8I/kMyroNePy5IOcshslxQ9Wv//DHk8W8nSiJmfbAU dMBX+UJ9A+bLg== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 03/10] mptcp: widen offset field in mptcp_data_frag to u32 Date: Thu, 16 Jul 2026 15:50:42 +0800 Message-ID: <8b39801c46b80523ee71dfab667117030d2ccdfc.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang The offset field in struct mptcp_data_frag is declared as u16, which can only represent values up to 65535. On architectures with page sizes larger than 64KB (such as 256KB on PowerPC and Hexagon), the offset calculation in mptcp_carve_data_frag() can exceed this limit, causing the u16 field to wrap around. When offset wraps, mptcp_sendmsg() calculates the destination address using the wrapped value: offset =3D dfrag->offset + dfrag->data_len; page_address(dfrag->page) + offset This could cause the function to write new network payload into the start of the page fragment, potentially overwriting the previously allocated struct mptcp_data_frag and corrupting kernel memory. Widen the offset field from u16 to u32 to support page sizes up to 4GB. Also change the corresponding local variable in mptcp_sendmsg_frag() from int to size_t to prevent overflow when adding offset and data_len. This is a correctness fix for architectures with 256KB pages and has no effect on systems with smaller page sizes. Signed-off-by: Geliang Tang --- net/mptcp/protocol.c | 2 +- net/mptcp/protocol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 1cab07b1b9b1..3acd61ae6160 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1373,7 +1373,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct= sock *ssk, struct mptcp_sendmsg_info *info) { u64 data_seq =3D dfrag->data_seq + info->sent; - int offset =3D dfrag->offset + info->sent; + size_t offset =3D dfrag->offset + info->sent; struct mptcp_sock *msk =3D mptcp_sk(sk); struct tcp_sock *tp =3D tcp_sk(ssk); bool zero_window_probe =3D false; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index da40c6f3705f..7d624cb0fa7d 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -263,7 +263,7 @@ struct mptcp_data_frag { struct list_head list; u64 data_seq; u16 data_len; - u16 offset; + u32 offset; /* u16 wraps on 256KB-page kernels */ u8 overhead; u8 eor; /* currently using 1 bit */ u16 already_sent; --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FDE4357CEB for ; Thu, 16 Jul 2026 07:51:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188292; cv=none; b=LbErlfDackwmXB1ggV9kbMKO3A9plnfINAkcQ7ny3EnanwhqXB9IgVOD4ZmF41j0CWN3ivOn+JnqvP6A702ZiTnpaGlqpo7W3bupBEuiRiBhRqynazi3/2Hr2gAHlaZHguPig/qssrFadkcG2KRb1XL27WyVft7lGXxPMRwDh5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188292; c=relaxed/simple; bh=yy/4/NGgVfbFhP3r00OaG89OolxyJLVTIEBTNQDZpsI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OwKjjnDmilijL1LX/WWjfPVTLPO4T+yaLoP/aqYBc7/O6d6tFprXnos38faU418jjqgmiX2UOWQ9afOUEmgll+Wfu+hT1Hs5z57Rb79h2sBbCXhq93vrFt/FDBZgNZvH1btYm3QnZeIsfF4ViV4eOTc41lL4V2V8RgUw5aGybQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cgBV4//M; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cgBV4//M" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 830F31F000E9; Thu, 16 Jul 2026 07:51:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188291; bh=Jep9UZlxM4FIDz9E1VeMkNUfTC1ZyZqyVsPSt4aOL5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cgBV4//MgacfPjL8Bx0Sn6dnfSSP0attcD/A5ltsSyUlnlKeJRwL3Pk3QhrL4GoYO gn4P0wle2RsTP3HHhWUwy9I1RmRGZGhb5XTtvg9DKOL4w+LO0a8OEJYkj/olgmb7dU H0jyMujsBREbbcTcFiJGHHrEUxd4srbFd3G63BfrLTiMs6rzwIazml2pYwwopPoakj eJOufXIaObYYG4ITuW7kgpJf/v1uPOLVmz37Lv11Ay4GvcFCvqBsWtkTNMMekcOMrv vo1Zc94PZfXWaoi3BrYIvYZXxKF8fjoTHgZt6vFkElG+ev/aR1q0rGiXTTnJ5bV+bl AFFC0OjvJAwGQ== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 04/10] mptcp: align struct mptcp_data_frag to 8 bytes on 32-bit Date: Thu, 16 Jul 2026 15:50:43 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 --- 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 *pfra= g, int orig_offset) { - int offset =3D ALIGN(orig_offset, sizeof(long)); + int offset =3D ALIGN(orig_offset, sizeof(u64)); struct mptcp_data_frag *dfrag; =20 dfrag =3D (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, c= b)); =20 /* 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); } =20 --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 033AA3382CB for ; Thu, 16 Jul 2026 07:51:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188294; cv=none; b=f52/4b3FS5HCaqyNIq9E4ENJ92kX+1uqjzEGqqB3wj6X2rnahzT65yiHVKgziqkUa7T3rZ+uSJqdu81fk0m74SkEnWOSHmSj9a8Vwf/XVxFO/82s/oE5qIXewiDRAE6CYOaszSl82HMclk3lE/IHdbYqzD1XioXMgN7lAc0/SZc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188294; c=relaxed/simple; bh=ulWILUpb3pw4luElom6jkwqXrUv025UseXHFuQyY6KI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RUWRNmljyvuH731kpF1jHY7arE8Tud/VVI58iW4QYW7/4p2HYIa5zzE+YdAdAysK5X6q6S83np4W0OjC91zJ1kSiGUeBgGrf+vFJGewBDvUeWavpYnkQQGFPjgtYssHx8anugL+AiIENk45hhCNBNKDmem9EIo9dvnisTf3pRt0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F+ye6Ts0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F+ye6Ts0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C4AA01F00A3A; Thu, 16 Jul 2026 07:51:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188292; bh=mFe+EhieCAIFPeIzQNDJVSmkrrIOqPnGJ4ZYpTKuG6I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=F+ye6Ts0FKRDZ6jga+ml1nj60pNo53C7HEaY0mizyEOhGPjsCZzfwhuz95Mm3VrFC RenFZZceGYGCDtZTGNEYaA2Q3VTE1zOhfaH6TEMM3otX0xkAZygoM2Y39Nif0DuroV CgC0kn7PzIc5aSGKWeHOZkoPmcDOu6kkiLr9S1Z1zaszFnVUKjCjRYoFFMfzoV1EvD H1RT/0FMvYQFKMXkSPgDTYh/r4ccxbMr0ZxN0tEl140yf7wHVh7I5ihMm2SmVJANSn OZNTjBJiE5odoGarXwOm5M/SAGYq17pAgrr+NU3Lt6pRc8CSZ4xabwmw1aaL6UNXCz uFaLJs33nUTyA== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 05/10] mptcp: remove redundant orig_offset in carve_data_frag Date: Thu, 16 Jul 2026 15:50:44 +0800 Message-ID: <26a440ab536462e9618b4f10f86197657c712608.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang mptcp_carve_data_frag() already receives struct page_frag via its 'pfrag' parameter, making the separate 'orig_offset' parameter redundant since it merely duplicates pfrag->offset. Simplify the function signature by removing this unnecessary parameter and directly accessing the offset from struct pfrag internally. Signed-off-by: Geliang Tang --- net/mptcp/protocol.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 7ad3a4a09e3b..85bbcb16c87e 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1234,12 +1234,13 @@ static bool mptcp_page_frag_refill(struct sock *sk,= struct page_frag *pfrag) } =20 static struct mptcp_data_frag * -mptcp_carve_data_frag(const struct mptcp_sock *msk, struct page_frag *pfra= g, - int orig_offset) +mptcp_carve_data_frag(const struct mptcp_sock *msk, struct page_frag *pfra= g) { - int offset =3D ALIGN(orig_offset, sizeof(u64)); + int orig_offset =3D pfrag->offset; struct mptcp_data_frag *dfrag; + int offset; =20 + offset =3D ALIGN(orig_offset, sizeof(u64)); dfrag =3D (struct mptcp_data_frag *)(page_to_virt(pfrag->page) + offset); dfrag->data_len =3D 0; dfrag->data_seq =3D msk->write_seq; @@ -2031,7 +2032,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msgh= dr *msg, size_t len) if (!mptcp_page_frag_refill(sk, pfrag)) goto wait_for_memory; =20 - dfrag =3D mptcp_carve_data_frag(msk, pfrag, pfrag->offset); + dfrag =3D mptcp_carve_data_frag(msk, pfrag); frag_truesize =3D dfrag->overhead; } =20 --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D14B37E5E9 for ; Thu, 16 Jul 2026 07:51:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188296; cv=none; b=pCueY9+lwJYFh5NcCG8uTTuyvwzS1z6Le+TVEshSoYfrr5GDi852GkRSJWFYDLoo1l6zpUDPjmyZzyxF8KtxMlUmObIsiCv3bkbX6EoUCInhgEP9GQOxTeWzvC8JIHDo7jxafh0sitT021KOiW7UcBdQekHra0UO2fL6aTE54RA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188296; c=relaxed/simple; bh=rQS5DMDkDbhNw+9xnhwVGPKgOZnj19ljRvfGpV14O/s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I22oasZbVbiFRYW03o+qLh4Fuvgs16ZPakXK6iiKZy7sQ6AKg11emkNny7vou5B6KSa1iV3vPKHCMPUkRgAJy6B4w20BhHghLbquZjgf0mhUoHTVavyTDiJt41LNK3Sd1/CPtGbVlF0931e7++dV8loAtdab/OjMDy4d1ebvgw0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aIs23Cbr; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aIs23Cbr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D4DB1F000E9; Thu, 16 Jul 2026 07:51:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188293; bh=FLEMHYXPlFidL7CwAfPUWWiB8daapXlFpiOz0Ru+r3Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=aIs23CbrkYfJta/WSSb076vA6PW1gJ/1Hvswx0nOstT/fOalrshClMZRocdqrev4i g0xW2TiKzafF8uGYwL8JnCeFDqoxs4O9IKOzVCrOr+k0/i21c59LRM/Q9/KSZkwqj8 y7B5DSlTgKM1QDVfridfnEbGCEF6UmEs+F6qFkn1iSuDigH5YTWQ5LhurwFseRGiin ieZbv1EaPWah90YDl8s6gtrYQOV1UV+zFr6mtCUgQDxQ6P3D0Z9InmDZ1XdRTvIQtO 7XPMqqaopZHaE2ue3l8JwF4iKEAtlxSTyz3ORQapZuullYn3XDizzoJ4YyDfB6exoI F2UPKDCunPYyA== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 06/10] mptcp: add MSG_ZEROCOPY support Date: Thu, 16 Jul 2026 15:50:45 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang This patch enables MSG_ZEROCOPY support for MPTCP sockets, allowing user-space to transmit data without intermediate kernel copies. The implementation follows the same lifecycle model as TCP: A single ubuf_info_msgzc is allocated per sendmsg via msg_zerocopy_realloc(). Its reference count consists of three parts: one 'caller' reference held until sendmsg returns, one reference per MPTCP dfrag in the retransmission queue (released when the dfrag is acked and cleared), and one reference per subflow skb that consumes dfrag bytes (released by TCP's skb_zcopy_clear() when the skb is acked). Completion is reported only after all bytes are acknowledged at both MPTCP and subflow levels. User pages are pinned via iov_iter_get_pages2() and stored directly in a newly allocated mptcp_data_frag. The dfrag takes one reference on the ubuf_info and one on the page. Subflow skbs take additional page references via get_page() and are marked with skb_zcopy_set() and SKBFL_PURE_ZEROCOPY, mirroring TCP's behavior and bypassing kernel memory accounting for those pages. The feature is silently downgraded to regular copy when MSG_FASTOPEN is set or the application has not opted in via setsockopt(SO_ZEROCOPY). If msg_zerocopy_realloc() fails (e.g. RLIMIT_MEMLOCK pressure), sendmsg(2) aborts with -ENOBUFS. The implementation prevents coalescing of dfrags with different ubuf instances into the same subflow skb to avoid premature completion notifications. The data_len field is widened from u16 to u32 to prevent truncation on 64KB-page kernels (ARM64, PPC64). The dfrag metadata overhead is accounted for in sk_wmem_queued_add() to prevent bypassing socket memory limits. When iov_iter_get_pages2() returns 0, the function returns -EFAULT to properly signal iterator exhaustion. Signed-off-by: Geliang Tang --- net/mptcp/protocol.c | 117 +++++++++++++++++++++++++++++++++++++++---- net/mptcp/protocol.h | 5 +- 2 files changed, 111 insertions(+), 11 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 85bbcb16c87e..9cb32bcfa58b 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1118,9 +1118,11 @@ static bool mptcp_frag_can_collapse_to(const struct = mptcp_sock *msk, df->data_seq + df->data_len =3D=3D msk->write_seq; } =20 -static void dfrag_uncharge(struct sock *sk, int len) +static void dfrag_uncharge(struct sock *sk, int len, + struct mptcp_data_frag *dfrag) { - sk_mem_uncharge(sk, len); + if (!dfrag->ubuf) + sk_mem_uncharge(sk, len); sk_wmem_queued_add(sk, -len); } =20 @@ -1129,7 +1131,13 @@ static void dfrag_clear(struct sock *sk, struct mptc= p_data_frag *dfrag) int len =3D dfrag->data_len + dfrag->overhead; =20 list_del(&dfrag->list); - dfrag_uncharge(sk, len); + dfrag_uncharge(sk, len, dfrag); + if (dfrag->ubuf) { + net_zcopy_put(dfrag->ubuf); + put_page(dfrag->page); + kfree(dfrag); + return; + } put_page(dfrag->page); } =20 @@ -1174,7 +1182,7 @@ static void __mptcp_clean_una(struct sock *sk) dfrag->data_len -=3D delta; dfrag->already_sent -=3D delta; =20 - dfrag_uncharge(sk, delta); + dfrag_uncharge(sk, delta, dfrag); } =20 /* all retransmitted data acked, recovery completed */ @@ -1249,6 +1257,7 @@ mptcp_carve_data_frag(const struct mptcp_sock *msk, s= truct page_frag *pfrag) dfrag->already_sent =3D 0; dfrag->page =3D pfrag->page; dfrag->eor =3D 0; + dfrag->ubuf =3D NULL; =20 return dfrag; } @@ -1257,7 +1266,7 @@ struct mptcp_sendmsg_info { int mss_now; int size_goal; u16 limit; - u16 sent; + u32 sent; /* matches dfrag->already_sent width */ unsigned int flags; bool data_lock_held; }; @@ -1416,6 +1425,16 @@ static int mptcp_sendmsg_frag(struct sock *sk, struc= t sock *ssk, goto alloc_skb; } =20 + if (skb_zcopy_pure(skb) !=3D !!dfrag->ubuf) { + tcp_mark_push(tp, skb); + goto alloc_skb; + } + if (dfrag->ubuf && skb_zcopy(skb) && + skb_zcopy(skb) !=3D dfrag->ubuf) { + tcp_mark_push(tp, skb); + goto alloc_skb; + } + i =3D skb_shinfo(skb)->nr_frags; can_coalesce =3D skb_can_coalesce(skb, i, dfrag->page, offset); if (!can_coalesce && i >=3D READ_ONCE(net_hotdata.sysctl_max_skb_frags))= { @@ -1456,7 +1475,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct= sock *ssk, } =20 copy =3D min_t(size_t, copy, info->limit - info->sent); - if (!sk_wmem_schedule(ssk, copy)) { + if (!dfrag->ubuf && !sk_wmem_schedule(ssk, copy)) { tcp_remove_empty_skb(ssk); return -ENOMEM; } @@ -1466,13 +1485,19 @@ static int mptcp_sendmsg_frag(struct sock *sk, stru= ct sock *ssk, } else { get_page(dfrag->page); skb_fill_page_desc(skb, i, dfrag->page, offset, copy); + + if (dfrag->ubuf && !skb_zcopy(skb)) { + skb_zcopy_set(skb, dfrag->ubuf, NULL); + skb_shinfo(skb)->flags |=3D SKBFL_PURE_ZEROCOPY; + } } =20 skb->len +=3D copy; skb->data_len +=3D copy; skb->truesize +=3D copy; sk_wmem_queued_add(ssk, copy); - sk_mem_charge(ssk, copy); + if (!skb_zcopy_pure(skb)) + sk_mem_charge(ssk, copy); WRITE_ONCE(tp->write_seq, tp->write_seq + copy); TCP_SKB_CB(skb)->end_seq +=3D copy; tcp_skb_pcount_set(skb, 0); @@ -1969,22 +1994,81 @@ static void mptcp_rps_record_subflows(const struct = mptcp_sock *msk) } } =20 +static int mptcp_sendmsg_zerocopy_iter(struct sock *sk, struct msghdr *msg, + struct ubuf_info *ubuf, u32 copy_limit, + ssize_t *copied, long *timeo) +{ + struct mptcp_sock *msk =3D mptcp_sk(sk); + struct mptcp_data_frag *dfrag; + struct page *pages[1] =3D {}; + size_t pg_off =3D 0; + ssize_t pg_len; + + pg_len =3D iov_iter_get_pages2(&msg->msg_iter, pages, + copy_limit, 1, &pg_off); + if (pg_len < 0) + return pg_len; + /* pg_len =3D=3D 0 means the iterator is exhausted */ + if (pg_len =3D=3D 0) + return -EFAULT; + + dfrag =3D kzalloc_obj(*dfrag, GFP_KERNEL_ACCOUNT); + if (!dfrag) { + iov_iter_revert(&msg->msg_iter, pg_len); + put_page(pages[0]); + return -ENOMEM; + } + dfrag->data_len =3D pg_len; + dfrag->data_seq =3D msk->write_seq; + dfrag->offset =3D pg_off; + dfrag->page =3D pages[0]; + dfrag->ubuf =3D ubuf; + dfrag->overhead =3D sizeof(struct mptcp_data_frag); + + /* one ref for the dfrag; released in dfrag_clear */ + net_zcopy_get(ubuf); + + *copied +=3D pg_len; + WRITE_ONCE(msk->write_seq, msk->write_seq + pg_len); + sk_wmem_queued_add(sk, pg_len + dfrag->overhead); + + list_add_tail(&dfrag->list, &msk->rtx_queue); + if (!msk->first_pending) + msk->first_pending =3D dfrag; + + return 0; +} + static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) { struct mptcp_sock *msk =3D mptcp_sk(sk); + struct ubuf_info *ubuf =3D NULL; struct page_frag *pfrag; size_t copied =3D 0; + bool zc =3D false; int ret =3D 0; long timeo; =20 /* silently ignore everything else */ msg->msg_flags &=3D MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_FASTOPEN | MSG_EOR; + MSG_FASTOPEN | MSG_EOR | MSG_ZEROCOPY; =20 lock_sock(sk); =20 mptcp_rps_record_subflows(msk); =20 + if (msg->msg_flags & MSG_FASTOPEN || !sock_flag(sk, SOCK_ZEROCOPY)) + msg->msg_flags &=3D ~MSG_ZEROCOPY; + + if ((msg->msg_flags & MSG_ZEROCOPY) && len) { + ubuf =3D msg_zerocopy_realloc(sk, len, NULL, false); + if (!ubuf) { + ret =3D -ENOBUFS; + goto do_error; + } + zc =3D true; + } + if (unlikely(inet_test_bit(DEFER_CONNECT, sk) || msg->msg_flags & MSG_FASTOPEN)) { int copied_syn =3D 0; @@ -2023,6 +2107,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msg= hdr *msg, size_t len) if (!copy_limit) goto wait_for_memory; =20 + if (zc) { + ret =3D mptcp_sendmsg_zerocopy_iter(sk, msg, + ubuf, copy_limit, + &copied, &timeo); + if (ret) + goto do_error; + continue; + } + /* reuse tail pfrag, if possible, or carve a new one from the * page allocator */ @@ -2098,6 +2191,8 @@ static int mptcp_sendmsg(struct sock *sk, struct msgh= dr *msg, size_t len) } =20 out: + if (zc) + net_zcopy_put(ubuf); release_sock(sk); return copied; =20 @@ -2106,6 +2201,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msg= hdr *msg, size_t len) goto out; =20 copied =3D sk_stream_error(sk, msg->msg_flags, ret); + if (zc) { + net_zcopy_put_abort(ubuf, true); + zc =3D false; + } goto out; } =20 @@ -2960,7 +3059,7 @@ static void __mptcp_retrans(struct sock *sk) =20 retrans_seq +=3D len; msk->bytes_retrans +=3D len; - dfrag->already_sent =3D max_t(u16, dfrag->already_sent, + dfrag->already_sent =3D max_t(u32, dfrag->already_sent, retrans_seq - dfrag->data_seq); =20 /* With csum enabled retransmission can send new data. */ diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 7d624cb0fa7d..830733327e66 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -262,12 +262,13 @@ struct mptcp_pm_addr_entry { struct mptcp_data_frag { struct list_head list; u64 data_seq; - u16 data_len; + u32 data_len; /* u16 truncates on 64KB-page kernels */ u32 offset; /* u16 wraps on 256KB-page kernels */ u8 overhead; u8 eor; /* currently using 1 bit */ - u16 already_sent; + u32 already_sent; /* u16 overflows when data_len > 65535 */ struct page *page; + struct ubuf_info *ubuf; }; =20 /* Arbitrary compromise between as low as possible to react timely to subf= low --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 259432DAFA9 for ; Thu, 16 Jul 2026 07:51:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188297; cv=none; b=i34cXHtuiKap3OjJmbajEdpO7/GaoQpl0O9bRPTW1+ramYNG7OViRIDppLiA6qJPAXc7GFkBQlkN/Oh8DKOMnFSFw0fWXaLu20Oo6HhO14DZMDbj8ZbDcpWMTOjZJX2ybttlT6PxUEHvSphBgKd5Lo8kHVktRCD6FPLfvfu13JY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188297; c=relaxed/simple; bh=h0KHbTdRLXfAQDlm+Mzn4sOSwJyxsp1fPSLu/6K0DEU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UwcGS+edsD36ipxZpEmfysq713TDof+hoAo/bNsPhN4HIYCCQeXn2suI0G67RgBmCaPkZ2Y8xB3Q746QdrK/2ot2x/Nnz6h7kFTrITHYpjYAxYFWiThhO9/ClNkulRK7afD+HFocBcopGSMtneijZI2rp1JmZ8tyJjFu12Pu0UE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IiB3Rb49; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IiB3Rb49" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4AC4C1F00A3A; Thu, 16 Jul 2026 07:51:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188295; bh=1aL2W8PM3bCKMiZfqkj5j62ROsq0aloJ4VBeqLorDFw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=IiB3Rb49senw6bTCgRsunEY2u4XdzS4gVt3AHZkZfkV5f4CyZdczHbTUHxPtW35AG ROmM3yT1Ax7RBM8AfM/uiuDisKEbDRC8tm1+9xPqYfrJ0ts4GDP1Mft+ReXVu02c7i c8bro76kB62iBXTTCH8H87ecOv6cRFNKXLmouj97Zn51U6+fxVw/JyC1+bb3rv7Llw f0cCZAHwTisHyg6E1xZYGn/CdBFZ8vTQ2Jsj6xBXfZ38BN4P24LS4twGaH/r8fmKPx dJW/nnsIhJJjZcbh02GRpLQX9ZnGNARNQl12A+FEyXV+ufYywNtSt/zJ+6iaRUKwk8 lolDUQJYUDSgw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 07/10] mptcp: handle SO_ZEROCOPY in setsockopt Date: Thu, 16 Jul 2026 15:50:46 +0800 Message-ID: <1653984889e352b7f366f26a8fe4145cc94ddaa7.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang SO_ZEROCOPY is currently rejected by MPTCP setsockopt with -EOPNOTSUPP, even though the matching MSG_ZEROCOPY path in mptcp_sendmsg() is wired up. As a result MSG_ZEROCOPY silently falls back to a copy on MPTCP sockets because the opt-in flag is never set. Expose SO_ZEROCOPY through the SOL_SOCKET setsockopt dispatcher. The new mptcp_setsockopt_sol_socket_zerocopy() helper validates that val is 0 or 1 (matching standard TCP sk_setsockopt) and flips SOCK_ZEROCOPY on the msk only. mptcp_sendmsg() consults the same flag directly, so opt-in is honoured on every data path without any cross-socket propagation. Signed-off-by: Geliang Tang --- net/mptcp/sockopt.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index fcf6feb2a9eb..abcc7d4452b4 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -175,6 +175,19 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct m= ptcp_sock *msk, int optnam return 0; } =20 +static int mptcp_setsockopt_sol_socket_zerocopy(struct mptcp_sock *msk, in= t val) +{ + struct sock *sk =3D (struct sock *)msk; + + if (val !=3D 0 && val !=3D 1) + return -EINVAL; + + lock_sock(sk); + sock_valbool_flag(sk, SOCK_ZEROCOPY, val); + release_sock(sk); + return 0; +} + static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int opt= name, sockptr_t optval, unsigned int optlen) @@ -203,6 +216,8 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp= _sock *msk, int optname, case SO_TIMESTAMPNS_OLD: case SO_TIMESTAMPNS_NEW: return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val); + case SO_ZEROCOPY: + return mptcp_setsockopt_sol_socket_zerocopy(msk, val); } =20 return -ENOPROTOOPT; @@ -342,6 +357,7 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_soc= k *msk, int optname, case SO_TIMESTAMP_NEW: case SO_TIMESTAMPNS_OLD: case SO_TIMESTAMPNS_NEW: + case SO_ZEROCOPY: return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen); case SO_TIMESTAMPING_OLD: @@ -387,7 +403,6 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_soc= k *msk, int optname, * SO_CNX_ADVICE is currently unsupported, could possibly be relevant, * but likely needs careful design * - * SO_ZEROCOPY is currently unsupported, TODO in sndmsg * SO_TXTIME is currently unsupported */ =20 --=20 2.53.0 From nobody Sat Jul 25 07:27:10 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 402B8372EF7 for ; Thu, 16 Jul 2026 07:51:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188300; cv=none; b=uHiXsZjZEa+QNgoQXFFUfr/EkpEqvkYnQUlz4ubO5tOAnWdhNBOAiikgt7BiXBTmZc0WaQRxP84ksMhZ+pPOXnhiH894cvfkImrrUrO4xD4ICY8260i/QSvxIhfXcwLxo+Nc+6bV8nhU6907DBkdWfng4RZZqmtM23FHjYoHMN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784188300; c=relaxed/simple; bh=HOTdH8eDacRqdEhZeGM23y42Ik5dXxC+sdAjGuwFoWg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S4RJi5PbKvWwxuqhkQQdN03gKjCj1P0TaHc3oBHVAhRB6C1zUTuRFgq/3MMvnelHJdhaXucs993wVd7ke3LAlXBiYRWJnb8FE7f4XyDt6BU56TrbIZE0rl7arWiiDAsbaefuo36b3SN/PtVHR+QtBnh0fMKXCDEuBu2pdKZgUgc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BXHf5h1n; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BXHf5h1n" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88E221F00A3D; Thu, 16 Jul 2026 07:51:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784188296; bh=z6NW5f2phGegZI7fpAJVzxrInrAxJqY9VH6SPTM/vto=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=BXHf5h1nambMEaCXylLVaJd708sygqmvb+byyYV1VS9B5omBJNU8HECkyPfefT9cG PRZZzLp7zq6C/z7PpmvSFoyy7O0JvXxwODPt7nEQFMZGKg3okGoIhjQSbPgURFw8FG ld8uCe5xnAPOAExZiIV7hHhDL54e0FpWU/tEZpbqj/cGETVExKiw/SG2Dbw7dsWqA0 ksw5HBASZ1EuPHewwWc9bLl1copuy+Vlu8f6erIb0TO2cvNnUErhxBPVsBtk3vvnH/ D6NKGXZ79B7La5LImVpVefmjSiMc2mH/gZFnumaZficE5S1NUuyK+G0Cadb0EMurhr K4++0zB8zyHNw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v6 08/10] selftests: mptcp: connect: add zerocopy io mode Date: Thu, 16 Jul 2026 15:50:47 +0800 Message-ID: <30b29493ed5bdb1862c3a8d227149ecc25ce63fd.1784188064.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang Add a new I/O mode 'zerocopy' to the mptcp_connect selftest, which uses sendmsg() with the MSG_ZEROCOPY flag to transmit data. This enables testing and performance validation of the zero-copy send path for both TCP and MPTCP connections. This mode is useful for benchmarking and for verifying correctness of MSG_ZEROCOPY handling in the MPTCP stack. The completion notification draining uses batched polling to handle large transfers that may generate multiple completion events across different TCP segments. Signed-off-by: Geliang Tang --- .../selftests/net/mptcp/mptcp_connect.c | 179 +++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/test= ing/selftests/net/mptcp/mptcp_connect.c index ea4cb6c1bd5e..63eb6e4dd4a7 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c @@ -33,6 +33,7 @@ #include #include #include +#include #include =20 extern int optind; @@ -53,6 +54,7 @@ enum cfg_mode { CFG_MODE_MMAP, CFG_MODE_SENDFILE, CFG_MODE_SPLICE, + CFG_MODE_ZEROCOPY, }; =20 enum cfg_peek { @@ -125,7 +127,7 @@ static void die_usage(void) fprintf(stderr, "\t-j -- add additional sleep at connection start and= tear down " "-- for MPJ tests\n"); fprintf(stderr, "\t-l -- listens mode, accepts incoming connection\n"= ); - fprintf(stderr, "\t-m [poll|mmap|sendfile|splice] -- use poll(default)/mm= ap+write/sendfile/splice\n"); + fprintf(stderr, "\t-m [poll|mmap|sendfile|splice|zerocopy] -- use poll(de= fault)/mmap+write/sendfile/splice/zerocopy\n"); fprintf(stderr, "\t-M mark -- set socket packet mark\n"); fprintf(stderr, "\t-o option -- test sockopt