mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mptcp: use get_retrans wrapper
This patch adds the multiple subflows support for __mptcp_retrans(). Use get_retrans() wrapper instead of mptcp_subflow_get_retrans() in it. Check the subflow scheduled flags to test which subflow or subflows are picked by the scheduler, use them to send data. Move msk_owned_by_me() and fallback checks into get_retrans() wrapper from mptcp_subflow_get_retrans(). Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Geliang Tang <geliang.tang@suse.com> Signed-off-by: Mat Martineau <martineau@kernel.org> Link: https://lore.kernel.org/r/20230821-upstream-net-next-20230818-v1-9-0c860fb256a8@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									0fa1b3783a
								
							
						
					
					
						commit
						ee2708aeda
					
				
					 2 changed files with 43 additions and 28 deletions
				
			
		| 
						 | 
					@ -2233,11 +2233,6 @@ struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk)
 | 
				
			||||||
	struct mptcp_subflow_context *subflow;
 | 
						struct mptcp_subflow_context *subflow;
 | 
				
			||||||
	int min_stale_count = INT_MAX;
 | 
						int min_stale_count = INT_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msk_owned_by_me(msk);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (__mptcp_check_fallback(msk))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mptcp_for_each_subflow(msk, subflow) {
 | 
						mptcp_for_each_subflow(msk, subflow) {
 | 
				
			||||||
		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 | 
							struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2515,16 +2510,17 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
 | 
				
			||||||
static void __mptcp_retrans(struct sock *sk)
 | 
					static void __mptcp_retrans(struct sock *sk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mptcp_sock *msk = mptcp_sk(sk);
 | 
						struct mptcp_sock *msk = mptcp_sk(sk);
 | 
				
			||||||
 | 
						struct mptcp_subflow_context *subflow;
 | 
				
			||||||
	struct mptcp_sendmsg_info info = {};
 | 
						struct mptcp_sendmsg_info info = {};
 | 
				
			||||||
	struct mptcp_data_frag *dfrag;
 | 
						struct mptcp_data_frag *dfrag;
 | 
				
			||||||
	size_t copied = 0;
 | 
					 | 
				
			||||||
	struct sock *ssk;
 | 
						struct sock *ssk;
 | 
				
			||||||
	int ret;
 | 
						int ret, err;
 | 
				
			||||||
 | 
						u16 len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mptcp_clean_una_wakeup(sk);
 | 
						mptcp_clean_una_wakeup(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* first check ssk: need to kick "stale" logic */
 | 
						/* first check ssk: need to kick "stale" logic */
 | 
				
			||||||
	ssk = mptcp_subflow_get_retrans(msk);
 | 
						err = mptcp_sched_get_retrans(msk);
 | 
				
			||||||
	dfrag = mptcp_rtx_head(sk);
 | 
						dfrag = mptcp_rtx_head(sk);
 | 
				
			||||||
	if (!dfrag) {
 | 
						if (!dfrag) {
 | 
				
			||||||
		if (mptcp_data_fin_enabled(msk)) {
 | 
							if (mptcp_data_fin_enabled(msk)) {
 | 
				
			||||||
| 
						 | 
					@ -2543,14 +2539,23 @@ static void __mptcp_retrans(struct sock *sk)
 | 
				
			||||||
		goto reset_timer;
 | 
							goto reset_timer;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ssk)
 | 
						if (err)
 | 
				
			||||||
		goto reset_timer;
 | 
							goto reset_timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mptcp_for_each_subflow(msk, subflow) {
 | 
				
			||||||
 | 
							if (READ_ONCE(subflow->scheduled)) {
 | 
				
			||||||
 | 
								u16 copied = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								mptcp_subflow_set_scheduled(subflow, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ssk = mptcp_subflow_tcp_sock(subflow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			lock_sock(ssk);
 | 
								lock_sock(ssk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* limit retransmission to the bytes already sent on some subflows */
 | 
								/* limit retransmission to the bytes already sent on some subflows */
 | 
				
			||||||
			info.sent = 0;
 | 
								info.sent = 0;
 | 
				
			||||||
	info.limit = READ_ONCE(msk->csum_enabled) ? dfrag->data_len : dfrag->already_sent;
 | 
								info.limit = READ_ONCE(msk->csum_enabled) ? dfrag->data_len :
 | 
				
			||||||
 | 
													    dfrag->already_sent;
 | 
				
			||||||
			while (info.sent < info.limit) {
 | 
								while (info.sent < info.limit) {
 | 
				
			||||||
				ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
 | 
									ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
 | 
				
			||||||
				if (ret <= 0)
 | 
									if (ret <= 0)
 | 
				
			||||||
| 
						 | 
					@ -2561,14 +2566,18 @@ static void __mptcp_retrans(struct sock *sk)
 | 
				
			||||||
				info.sent += ret;
 | 
									info.sent += ret;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (copied) {
 | 
								if (copied) {
 | 
				
			||||||
		dfrag->already_sent = max(dfrag->already_sent, info.sent);
 | 
									len = max(copied, len);
 | 
				
			||||||
		msk->bytes_retrans += copied;
 | 
					 | 
				
			||||||
				tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
 | 
									tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
 | 
				
			||||||
					 info.size_goal);
 | 
										 info.size_goal);
 | 
				
			||||||
				WRITE_ONCE(msk->allow_infinite_fallback, false);
 | 
									WRITE_ONCE(msk->allow_infinite_fallback, false);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			release_sock(ssk);
 | 
								release_sock(ssk);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msk->bytes_retrans += len;
 | 
				
			||||||
 | 
						dfrag->already_sent = max(dfrag->already_sent, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
reset_timer:
 | 
					reset_timer:
 | 
				
			||||||
	mptcp_check_and_set_pending(sk);
 | 
						mptcp_check_and_set_pending(sk);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,6 +136,12 @@ int mptcp_sched_get_retrans(struct mptcp_sock *msk)
 | 
				
			||||||
	struct mptcp_subflow_context *subflow;
 | 
						struct mptcp_subflow_context *subflow;
 | 
				
			||||||
	struct mptcp_sched_data data;
 | 
						struct mptcp_sched_data data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msk_owned_by_me(msk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* the following check is moved out of mptcp_subflow_get_retrans */
 | 
				
			||||||
 | 
						if (__mptcp_check_fallback(msk))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mptcp_for_each_subflow(msk, subflow) {
 | 
						mptcp_for_each_subflow(msk, subflow) {
 | 
				
			||||||
		if (READ_ONCE(subflow->scheduled))
 | 
							if (READ_ONCE(subflow->scheduled))
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue