Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'mptcp-support-msg_eor-and-small-cleanups'

Matthieu Baerts says:

====================
mptcp: support MSG_EOR and small cleanups

This series contains various unrelated patches:

- Patches 1 & 2: support MSG_EOR instead of ignoring it.

- Patch 3: avoid duplicated code in TCP and MPTCP by using a new helper.

- Patch 4: adapt test to reproduce bug and increase code coverage.
====================

Link: https://patch.msgid.link/20260403-net-next-mptcp-msg_eor-misc-v1-0-b0b33bea3fed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+44 -21
+8
include/net/tcp.h
··· 3077 3077 const void *saddr, const void *daddr, 3078 3078 int family, int dif, int sdif); 3079 3079 3080 + static inline int tcp_recv_should_stop(struct sock *sk) 3081 + { 3082 + return sk->sk_err || 3083 + sk->sk_state == TCP_CLOSE || 3084 + (sk->sk_shutdown & RCV_SHUTDOWN) || 3085 + signal_pending(current); 3086 + } 3087 + 3080 3088 #endif /* _TCP_H */
+2 -7
net/ipv4/tcp.c
··· 888 888 release_sock(sk); 889 889 lock_sock(sk); 890 890 891 - if (sk->sk_err || sk->sk_state == TCP_CLOSE || 892 - (sk->sk_shutdown & RCV_SHUTDOWN) || 893 - signal_pending(current)) 891 + if (tcp_recv_should_stop(sk)) 894 892 break; 895 893 } 896 894 ··· 2753 2755 2754 2756 if (copied) { 2755 2757 if (!timeo || 2756 - sk->sk_err || 2757 - sk->sk_state == TCP_CLOSE || 2758 - (sk->sk_shutdown & RCV_SHUTDOWN) || 2759 - signal_pending(current)) 2758 + tcp_recv_should_stop(sk)) 2760 2759 break; 2761 2760 } else { 2762 2761 if (sock_flag(sk, SOCK_DONE))
+30 -11
net/mptcp/protocol.c
··· 1005 1005 const struct page_frag *pfrag, 1006 1006 const struct mptcp_data_frag *df) 1007 1007 { 1008 - return df && pfrag->page == df->page && 1008 + return df && !df->eor && 1009 + pfrag->page == df->page && 1009 1010 pfrag->size - pfrag->offset > 0 && 1010 1011 pfrag->offset == (df->offset + df->data_len) && 1011 1012 df->data_seq + df->data_len == msk->write_seq; ··· 1148 1147 dfrag->offset = offset + sizeof(struct mptcp_data_frag); 1149 1148 dfrag->already_sent = 0; 1150 1149 dfrag->page = pfrag->page; 1150 + dfrag->eor = 0; 1151 1151 1152 1152 return dfrag; 1153 1153 } ··· 1410 1408 mptcp_update_infinite_map(msk, ssk, mpext); 1411 1409 trace_mptcp_sendmsg_frag(mpext); 1412 1410 mptcp_subflow_ctx(ssk)->rel_write_seq += copy; 1411 + 1412 + /* if this is the last chunk of a dfrag with MSG_EOR set, 1413 + * mark the skb to prevent coalescing with subsequent data. 1414 + */ 1415 + if (dfrag->eor && info->sent + copy >= dfrag->data_len) 1416 + TCP_SKB_CB(skb)->eor = 1; 1417 + 1413 1418 return copy; 1414 1419 } 1415 1420 ··· 1877 1868 long timeo; 1878 1869 1879 1870 /* silently ignore everything else */ 1880 - msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_FASTOPEN; 1871 + msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | 1872 + MSG_FASTOPEN | MSG_EOR; 1881 1873 1882 1874 lock_sock(sk); 1883 1875 ··· 1985 1975 goto do_error; 1986 1976 } 1987 1977 1988 - if (copied) 1978 + if (copied) { 1979 + /* mark the last dfrag with EOR if MSG_EOR was set */ 1980 + if (msg->msg_flags & MSG_EOR) { 1981 + struct mptcp_data_frag *dfrag = mptcp_pending_tail(sk); 1982 + 1983 + if (dfrag) 1984 + dfrag->eor = 1; 1985 + } 1989 1986 __mptcp_push_pending(sk, msg->msg_flags); 1987 + } 1990 1988 1991 1989 out: 1992 1990 release_sock(sk); ··· 2333 2315 break; 2334 2316 2335 2317 if (copied) { 2336 - if (sk->sk_err || 2337 - sk->sk_state == TCP_CLOSE || 2338 - (sk->sk_shutdown & RCV_SHUTDOWN) || 2339 - !timeo || 2340 - signal_pending(current)) 2318 + if (tcp_recv_should_stop(sk) || 2319 + !timeo) 2341 2320 break; 2342 2321 } else { 2343 2322 if (sk->sk_err) { ··· 4517 4502 release_sock(sk); 4518 4503 lock_sock(sk); 4519 4504 4520 - if (sk->sk_err || sk->sk_state == TCP_CLOSE || 4521 - (sk->sk_shutdown & RCV_SHUTDOWN) || 4522 - signal_pending(current)) 4505 + if (tcp_recv_should_stop(sk)) 4523 4506 break; 4524 4507 } 4525 4508 ··· 4629 4616 inet_register_protosw(&mptcp_protosw); 4630 4617 4631 4618 BUILD_BUG_ON(sizeof(struct mptcp_skb_cb) > sizeof_field(struct sk_buff, cb)); 4619 + 4620 + /* struct mptcp_data_frag: 'overhead' corresponds to the alignment 4621 + * (ALIGN(1, sizeof(long)) - 1, so 8-1) + the struct's size 4622 + */ 4623 + BUILD_BUG_ON(ALIGN(1, sizeof(long)) - 1 + sizeof(struct mptcp_data_frag) 4624 + > U8_MAX); 4632 4625 } 4633 4626 4634 4627 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+2 -1
net/mptcp/protocol.h
··· 263 263 u64 data_seq; 264 264 u16 data_len; 265 265 u16 offset; 266 - u16 overhead; 266 + u8 overhead; 267 + u8 eor; /* currently using 1 bit */ 267 268 u16 already_sent; 268 269 struct page *page; 269 270 };
+2 -2
tools/testing/selftests/net/mptcp/mptcp_join.sh
··· 4343 4343 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 4344 4344 [ ${ipt} = 1 ] && ip netns exec "${ns1}" ${iptables} -D OUTPUT 1 4345 4345 4346 - pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal 4346 + pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal 4347 4347 wait_mpj 4 4348 4348 chk_subflow_nr "after re-add ID 0" 3 4349 4349 chk_mptcp_info subflows 3 subflows 3 4350 4350 chk_mptcp_info add_addr_signal 3 add_addr_accepted 2 4351 4351 4352 - pm_nl_del_endpoint $ns1 99 10.0.1.1 4352 + pm_nl_del_endpoint $ns1 42 10.0.1.1 4353 4353 sleep 0.5 4354 4354 chk_subflow_nr "after re-delete ID 0" 2 4355 4355 chk_mptcp_info subflows 2 subflows 2