xref: /xnu-8020.140.41/bsd/netinet/mptcp_timer.c (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1*27b03b36SApple OSS Distributions /*
2*27b03b36SApple OSS Distributions  * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
3*27b03b36SApple OSS Distributions  *
4*27b03b36SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*27b03b36SApple OSS Distributions  *
6*27b03b36SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*27b03b36SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*27b03b36SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*27b03b36SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*27b03b36SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*27b03b36SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*27b03b36SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*27b03b36SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*27b03b36SApple OSS Distributions  *
15*27b03b36SApple OSS Distributions  * Please obtain a copy of the License at
16*27b03b36SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*27b03b36SApple OSS Distributions  *
18*27b03b36SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*27b03b36SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*27b03b36SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*27b03b36SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*27b03b36SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*27b03b36SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*27b03b36SApple OSS Distributions  * limitations under the License.
25*27b03b36SApple OSS Distributions  *
26*27b03b36SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*27b03b36SApple OSS Distributions  */
28*27b03b36SApple OSS Distributions 
29*27b03b36SApple OSS Distributions #include <sys/param.h>
30*27b03b36SApple OSS Distributions #include <sys/systm.h>
31*27b03b36SApple OSS Distributions #include <sys/kernel.h>
32*27b03b36SApple OSS Distributions #include <sys/mcache.h>
33*27b03b36SApple OSS Distributions #include <sys/socket.h>
34*27b03b36SApple OSS Distributions #include <sys/socketvar.h>
35*27b03b36SApple OSS Distributions #include <sys/syslog.h>
36*27b03b36SApple OSS Distributions #include <sys/protosw.h>
37*27b03b36SApple OSS Distributions #include <sys/sysctl.h>
38*27b03b36SApple OSS Distributions 
39*27b03b36SApple OSS Distributions #include <mach/sdt.h>
40*27b03b36SApple OSS Distributions 
41*27b03b36SApple OSS Distributions #include <netinet/mp_pcb.h>
42*27b03b36SApple OSS Distributions #include <netinet/mptcp_var.h>
43*27b03b36SApple OSS Distributions #include <netinet/mptcp_timer.h>
44*27b03b36SApple OSS Distributions #include <netinet/mptcp_seq.h>
45*27b03b36SApple OSS Distributions 
46*27b03b36SApple OSS Distributions #include <kern/locks.h>
47*27b03b36SApple OSS Distributions 
48*27b03b36SApple OSS Distributions /*
49*27b03b36SApple OSS Distributions  * MPTCP Retransmission Timer comes into play only when subflow level
50*27b03b36SApple OSS Distributions  * data is acked, but Data ACK is not received. Time is in seconds.
51*27b03b36SApple OSS Distributions  */
52*27b03b36SApple OSS Distributions static u_int32_t mptcp_rto = 3;
53*27b03b36SApple OSS Distributions SYSCTL_INT(_net_inet_mptcp, OID_AUTO, rto, CTLFLAG_RW | CTLFLAG_LOCKED,
54*27b03b36SApple OSS Distributions     &mptcp_rto, 0, "MPTCP Retransmission Timeout");
55*27b03b36SApple OSS Distributions 
56*27b03b36SApple OSS Distributions static int mptcp_nrtos = 3;
57*27b03b36SApple OSS Distributions SYSCTL_INT(_net_inet_mptcp, OID_AUTO, nrto, CTLFLAG_RW | CTLFLAG_LOCKED,
58*27b03b36SApple OSS Distributions     &mptcp_rto, 0, "MPTCP Retransmissions");
59*27b03b36SApple OSS Distributions 
60*27b03b36SApple OSS Distributions /*
61*27b03b36SApple OSS Distributions  * MPTCP connections timewait interval in seconds.
62*27b03b36SApple OSS Distributions  */
63*27b03b36SApple OSS Distributions static u_int32_t mptcp_tw = 60;
64*27b03b36SApple OSS Distributions SYSCTL_INT(_net_inet_mptcp, OID_AUTO, tw, CTLFLAG_RW | CTLFLAG_LOCKED,
65*27b03b36SApple OSS Distributions     &mptcp_tw, 0, "MPTCP Timewait Period");
66*27b03b36SApple OSS Distributions 
67*27b03b36SApple OSS Distributions #define TIMEVAL_TO_HZ(_tv_)     ((_tv_).tv_sec * hz + (_tv_).tv_usec / hz)
68*27b03b36SApple OSS Distributions 
69*27b03b36SApple OSS Distributions static int mptcp_cancel_urgency_timer(struct mptses *mpte);
70*27b03b36SApple OSS Distributions 
71*27b03b36SApple OSS Distributions static int
mptcp_timer_demux(struct mptses * mpte,uint64_t now_msecs)72*27b03b36SApple OSS Distributions mptcp_timer_demux(struct mptses *mpte, uint64_t now_msecs)
73*27b03b36SApple OSS Distributions {
74*27b03b36SApple OSS Distributions 	struct mptcb *mp_tp = NULL;
75*27b03b36SApple OSS Distributions 	mp_tp = mpte->mpte_mptcb;
76*27b03b36SApple OSS Distributions 	int resched_timer = 0;
77*27b03b36SApple OSS Distributions 
78*27b03b36SApple OSS Distributions 	DTRACE_MPTCP2(timer, struct mptses *, mpte, struct mptcb *, mp_tp);
79*27b03b36SApple OSS Distributions 
80*27b03b36SApple OSS Distributions 	switch (mp_tp->mpt_timer_vals) {
81*27b03b36SApple OSS Distributions 	case MPTT_REXMT:
82*27b03b36SApple OSS Distributions 		if (mp_tp->mpt_rxtstart == 0) {
83*27b03b36SApple OSS Distributions 			break;
84*27b03b36SApple OSS Distributions 		}
85*27b03b36SApple OSS Distributions 		if ((now_msecs - mp_tp->mpt_rxtstart) > (mptcp_rto * hz)) {
86*27b03b36SApple OSS Distributions 			if (MPTCP_SEQ_GT(mp_tp->mpt_snduna, mp_tp->mpt_rtseq)) {
87*27b03b36SApple OSS Distributions 				mp_tp->mpt_timer_vals = 0;
88*27b03b36SApple OSS Distributions 				mp_tp->mpt_rtseq = 0;
89*27b03b36SApple OSS Distributions 				break;
90*27b03b36SApple OSS Distributions 			}
91*27b03b36SApple OSS Distributions 			mp_tp->mpt_rxtshift++;
92*27b03b36SApple OSS Distributions 			if (mp_tp->mpt_rxtshift > mptcp_nrtos) {
93*27b03b36SApple OSS Distributions 				mp_tp->mpt_softerror = ETIMEDOUT;
94*27b03b36SApple OSS Distributions 				DTRACE_MPTCP1(error, struct mptcb *, mp_tp);
95*27b03b36SApple OSS Distributions 			} else {
96*27b03b36SApple OSS Distributions 				mp_tp->mpt_sndnxt = mp_tp->mpt_rtseq;
97*27b03b36SApple OSS Distributions 				os_log_info(mptcp_log_handle,
98*27b03b36SApple OSS Distributions 				    "%s: REXMT %d sndnxt %u\n",
99*27b03b36SApple OSS Distributions 				    __func__, mp_tp->mpt_rxtshift,
100*27b03b36SApple OSS Distributions 				    (uint32_t)mp_tp->mpt_sndnxt);
101*27b03b36SApple OSS Distributions 				mptcp_output(mpte);
102*27b03b36SApple OSS Distributions 			}
103*27b03b36SApple OSS Distributions 		} else {
104*27b03b36SApple OSS Distributions 			resched_timer = 1;
105*27b03b36SApple OSS Distributions 		}
106*27b03b36SApple OSS Distributions 		break;
107*27b03b36SApple OSS Distributions 	case MPTT_TW:
108*27b03b36SApple OSS Distributions 		/* Allows for break before make XXX */
109*27b03b36SApple OSS Distributions 		if (mp_tp->mpt_timewait == 0) {
110*27b03b36SApple OSS Distributions 			VERIFY(0);
111*27b03b36SApple OSS Distributions 		}
112*27b03b36SApple OSS Distributions 		if ((now_msecs - mp_tp->mpt_timewait) >
113*27b03b36SApple OSS Distributions 		    (mptcp_tw * hz)) {
114*27b03b36SApple OSS Distributions 			mp_tp->mpt_softerror = ETIMEDOUT;
115*27b03b36SApple OSS Distributions 			DTRACE_MPTCP1(error, struct mptcb *, mp_tp);
116*27b03b36SApple OSS Distributions 		} else {
117*27b03b36SApple OSS Distributions 			resched_timer = 1;
118*27b03b36SApple OSS Distributions 		}
119*27b03b36SApple OSS Distributions 		break;
120*27b03b36SApple OSS Distributions 	case MPTT_FASTCLOSE:
121*27b03b36SApple OSS Distributions 		/* TODO XXX */
122*27b03b36SApple OSS Distributions 		break;
123*27b03b36SApple OSS Distributions 	default:
124*27b03b36SApple OSS Distributions 		break;
125*27b03b36SApple OSS Distributions 	}
126*27b03b36SApple OSS Distributions 
127*27b03b36SApple OSS Distributions 	return resched_timer;
128*27b03b36SApple OSS Distributions }
129*27b03b36SApple OSS Distributions 
130*27b03b36SApple OSS Distributions uint32_t
mptcp_timer(struct mppcbinfo * mppi)131*27b03b36SApple OSS Distributions mptcp_timer(struct mppcbinfo *mppi)
132*27b03b36SApple OSS Distributions {
133*27b03b36SApple OSS Distributions 	struct mppcb *mpp, *tmpp;
134*27b03b36SApple OSS Distributions 	struct timeval now;
135*27b03b36SApple OSS Distributions 	uint32_t resched_timer = 0;
136*27b03b36SApple OSS Distributions 	uint64_t now_msecs;
137*27b03b36SApple OSS Distributions 
138*27b03b36SApple OSS Distributions 	LCK_MTX_ASSERT(&mppi->mppi_lock, LCK_MTX_ASSERT_OWNED);
139*27b03b36SApple OSS Distributions 
140*27b03b36SApple OSS Distributions 	microuptime(&now);
141*27b03b36SApple OSS Distributions 	now_msecs = TIMEVAL_TO_HZ(now);
142*27b03b36SApple OSS Distributions 	TAILQ_FOREACH_SAFE(mpp, &mppi->mppi_pcbs, mpp_entry, tmpp) {
143*27b03b36SApple OSS Distributions 		struct socket *mp_so;
144*27b03b36SApple OSS Distributions 		struct mptses *mpte;
145*27b03b36SApple OSS Distributions 
146*27b03b36SApple OSS Distributions 		mp_so = mpp->mpp_socket;
147*27b03b36SApple OSS Distributions 		mpte = mptompte(mpp);
148*27b03b36SApple OSS Distributions 		socket_lock(mp_so, 1);
149*27b03b36SApple OSS Distributions 
150*27b03b36SApple OSS Distributions 		VERIFY(mpp->mpp_flags & MPP_ATTACHED);
151*27b03b36SApple OSS Distributions 
152*27b03b36SApple OSS Distributions 		if (mptcp_timer_demux(mpte, now_msecs)) {
153*27b03b36SApple OSS Distributions 			resched_timer = 1;
154*27b03b36SApple OSS Distributions 		}
155*27b03b36SApple OSS Distributions 		socket_unlock(mp_so, 1);
156*27b03b36SApple OSS Distributions 	}
157*27b03b36SApple OSS Distributions 
158*27b03b36SApple OSS Distributions 	return resched_timer;
159*27b03b36SApple OSS Distributions }
160*27b03b36SApple OSS Distributions 
161*27b03b36SApple OSS Distributions void
mptcp_start_timer(struct mptses * mpte,int timer_type)162*27b03b36SApple OSS Distributions mptcp_start_timer(struct mptses *mpte, int timer_type)
163*27b03b36SApple OSS Distributions {
164*27b03b36SApple OSS Distributions 	struct timeval now;
165*27b03b36SApple OSS Distributions 	struct mptcb *mp_tp = mpte->mpte_mptcb;
166*27b03b36SApple OSS Distributions 
167*27b03b36SApple OSS Distributions 	microuptime(&now);
168*27b03b36SApple OSS Distributions 
169*27b03b36SApple OSS Distributions 	DTRACE_MPTCP2(start__timer, struct mptcb *, mp_tp, int, timer_type);
170*27b03b36SApple OSS Distributions 	mptcplog((LOG_DEBUG, "MPTCP Socket: %s: %d\n", __func__, timer_type),
171*27b03b36SApple OSS Distributions 	    MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
172*27b03b36SApple OSS Distributions 
173*27b03b36SApple OSS Distributions 	socket_lock_assert_owned(mptetoso(mpte));
174*27b03b36SApple OSS Distributions 
175*27b03b36SApple OSS Distributions 	switch (timer_type) {
176*27b03b36SApple OSS Distributions 	case MPTT_REXMT:
177*27b03b36SApple OSS Distributions 		mp_tp->mpt_timer_vals |= MPTT_REXMT;
178*27b03b36SApple OSS Distributions 		mp_tp->mpt_rxtstart = TIMEVAL_TO_HZ(now);
179*27b03b36SApple OSS Distributions 		mp_tp->mpt_rxtshift = 0;
180*27b03b36SApple OSS Distributions 		mp_tp->mpt_rtseq = mp_tp->mpt_sndnxt;
181*27b03b36SApple OSS Distributions 		break;
182*27b03b36SApple OSS Distributions 	case MPTT_TW:
183*27b03b36SApple OSS Distributions 		/* XXX: Not implemented yet */
184*27b03b36SApple OSS Distributions 		mp_tp->mpt_timer_vals |= MPTT_TW;
185*27b03b36SApple OSS Distributions 		mp_tp->mpt_timewait = TIMEVAL_TO_HZ(now);
186*27b03b36SApple OSS Distributions 		break;
187*27b03b36SApple OSS Distributions 	case MPTT_FASTCLOSE:
188*27b03b36SApple OSS Distributions 		/* NO-OP */
189*27b03b36SApple OSS Distributions 		break;
190*27b03b36SApple OSS Distributions 	default:
191*27b03b36SApple OSS Distributions 		VERIFY(0);
192*27b03b36SApple OSS Distributions 		/* NOTREACHED */
193*27b03b36SApple OSS Distributions 	}
194*27b03b36SApple OSS Distributions 	mptcp_timer_sched();
195*27b03b36SApple OSS Distributions }
196*27b03b36SApple OSS Distributions 
197*27b03b36SApple OSS Distributions void
mptcp_cancel_timer(struct mptcb * mp_tp,int timer_type)198*27b03b36SApple OSS Distributions mptcp_cancel_timer(struct mptcb *mp_tp, int timer_type)
199*27b03b36SApple OSS Distributions {
200*27b03b36SApple OSS Distributions 	socket_lock_assert_owned(mptetoso(mp_tp->mpt_mpte));
201*27b03b36SApple OSS Distributions 
202*27b03b36SApple OSS Distributions 	switch (timer_type) {
203*27b03b36SApple OSS Distributions 	case MPTT_REXMT:
204*27b03b36SApple OSS Distributions 		mp_tp->mpt_rxtstart = 0;
205*27b03b36SApple OSS Distributions 		mp_tp->mpt_rxtshift = 0;
206*27b03b36SApple OSS Distributions 		mp_tp->mpt_timer_vals = 0;
207*27b03b36SApple OSS Distributions 		break;
208*27b03b36SApple OSS Distributions 	case MPTT_TW:
209*27b03b36SApple OSS Distributions 		/* NO-OP */
210*27b03b36SApple OSS Distributions 		break;
211*27b03b36SApple OSS Distributions 	case MPTT_FASTCLOSE:
212*27b03b36SApple OSS Distributions 		/* NO-OP */
213*27b03b36SApple OSS Distributions 		break;
214*27b03b36SApple OSS Distributions 	default:
215*27b03b36SApple OSS Distributions 		break;
216*27b03b36SApple OSS Distributions 	}
217*27b03b36SApple OSS Distributions }
218*27b03b36SApple OSS Distributions 
219*27b03b36SApple OSS Distributions void
mptcp_cancel_all_timers(struct mptcb * mp_tp)220*27b03b36SApple OSS Distributions mptcp_cancel_all_timers(struct mptcb *mp_tp)
221*27b03b36SApple OSS Distributions {
222*27b03b36SApple OSS Distributions 	struct mptses *mpte = mp_tp->mpt_mpte;
223*27b03b36SApple OSS Distributions 
224*27b03b36SApple OSS Distributions 	mptcp_cancel_urgency_timer(mpte);
225*27b03b36SApple OSS Distributions 
226*27b03b36SApple OSS Distributions 	mptcp_cancel_timer(mp_tp, MPTT_REXMT);
227*27b03b36SApple OSS Distributions 	mptcp_cancel_timer(mp_tp, MPTT_TW);
228*27b03b36SApple OSS Distributions 	mptcp_cancel_timer(mp_tp, MPTT_FASTCLOSE);
229*27b03b36SApple OSS Distributions }
230*27b03b36SApple OSS Distributions 
231*27b03b36SApple OSS Distributions static void
mptcp_urgency_timer(void * param0,__unused void * param1)232*27b03b36SApple OSS Distributions mptcp_urgency_timer(void *param0, __unused void *param1)
233*27b03b36SApple OSS Distributions {
234*27b03b36SApple OSS Distributions 	struct mptses *mpte = (struct mptses *)param0;
235*27b03b36SApple OSS Distributions 	struct socket *mp_so = mptetoso(mpte);
236*27b03b36SApple OSS Distributions 	uint64_t time_now;
237*27b03b36SApple OSS Distributions 
238*27b03b36SApple OSS Distributions 	socket_lock(mp_so, 1);
239*27b03b36SApple OSS Distributions 
240*27b03b36SApple OSS Distributions 	time_now = mach_continuous_time();
241*27b03b36SApple OSS Distributions 	VERIFY(mp_so->so_usecount >= 0);
242*27b03b36SApple OSS Distributions 
243*27b03b36SApple OSS Distributions 	os_log(mptcp_log_handle, "%s - %lx: timer at %llu now %llu usecount %u\n",
244*27b03b36SApple OSS Distributions 	    __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte), mpte->mpte_time_target, time_now, mp_so->so_usecount);
245*27b03b36SApple OSS Distributions 
246*27b03b36SApple OSS Distributions 	mptcp_check_subflows_and_add(mpte);
247*27b03b36SApple OSS Distributions 
248*27b03b36SApple OSS Distributions 	mp_so->so_usecount--;
249*27b03b36SApple OSS Distributions 
250*27b03b36SApple OSS Distributions 	socket_unlock(mp_so, 1);
251*27b03b36SApple OSS Distributions }
252*27b03b36SApple OSS Distributions 
253*27b03b36SApple OSS Distributions static void
mptcp_urgency_stop(void * param0,__unused void * param1)254*27b03b36SApple OSS Distributions mptcp_urgency_stop(void *param0, __unused void *param1)
255*27b03b36SApple OSS Distributions {
256*27b03b36SApple OSS Distributions 	struct mptses *mpte = (struct mptses *)param0;
257*27b03b36SApple OSS Distributions 	struct socket *mp_so = mptetoso(mpte);
258*27b03b36SApple OSS Distributions 
259*27b03b36SApple OSS Distributions 	socket_lock(mp_so, 1);
260*27b03b36SApple OSS Distributions 
261*27b03b36SApple OSS Distributions 	VERIFY(mp_so->so_usecount >= 0);
262*27b03b36SApple OSS Distributions 
263*27b03b36SApple OSS Distributions 	os_log(mptcp_log_handle, "%s - %lx: usecount %u\n",
264*27b03b36SApple OSS Distributions 	    __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte), mp_so->so_usecount);
265*27b03b36SApple OSS Distributions 
266*27b03b36SApple OSS Distributions 	mptcp_check_subflows_and_remove(mpte);
267*27b03b36SApple OSS Distributions 
268*27b03b36SApple OSS Distributions 	mp_so->so_usecount--;
269*27b03b36SApple OSS Distributions 
270*27b03b36SApple OSS Distributions 	socket_unlock(mp_so, 1);
271*27b03b36SApple OSS Distributions }
272*27b03b36SApple OSS Distributions 
273*27b03b36SApple OSS Distributions void
mptcp_init_urgency_timer(struct mptses * mpte)274*27b03b36SApple OSS Distributions mptcp_init_urgency_timer(struct mptses *mpte)
275*27b03b36SApple OSS Distributions {
276*27b03b36SApple OSS Distributions 	/* thread_call_allocate never fails */
277*27b03b36SApple OSS Distributions 	mpte->mpte_time_thread = thread_call_allocate(mptcp_urgency_timer, mpte);
278*27b03b36SApple OSS Distributions 	mpte->mpte_stop_urgency = thread_call_allocate(mptcp_urgency_stop, mpte);
279*27b03b36SApple OSS Distributions }
280*27b03b36SApple OSS Distributions 
281*27b03b36SApple OSS Distributions void
mptcp_set_urgency_timer(struct mptses * mpte)282*27b03b36SApple OSS Distributions mptcp_set_urgency_timer(struct mptses *mpte)
283*27b03b36SApple OSS Distributions {
284*27b03b36SApple OSS Distributions 	struct socket *mp_so = mptetoso(mpte);
285*27b03b36SApple OSS Distributions 	uint64_t time_now = 0;
286*27b03b36SApple OSS Distributions 	boolean_t ret = FALSE;
287*27b03b36SApple OSS Distributions 
288*27b03b36SApple OSS Distributions 	socket_lock_assert_owned(mp_so);
289*27b03b36SApple OSS Distributions 
290*27b03b36SApple OSS Distributions 	VERIFY(mp_so->so_usecount >= 0);
291*27b03b36SApple OSS Distributions 	if (mp_so->so_usecount == 0) {
292*27b03b36SApple OSS Distributions 		goto exit_log;
293*27b03b36SApple OSS Distributions 	}
294*27b03b36SApple OSS Distributions 
295*27b03b36SApple OSS Distributions 	if (mpte->mpte_time_target == 0) {
296*27b03b36SApple OSS Distributions 		/* Close subflows right now */
297*27b03b36SApple OSS Distributions 
298*27b03b36SApple OSS Distributions 		ret = thread_call_enter(mpte->mpte_stop_urgency);
299*27b03b36SApple OSS Distributions 
300*27b03b36SApple OSS Distributions 		if (!ret) {
301*27b03b36SApple OSS Distributions 			mp_so->so_usecount++;
302*27b03b36SApple OSS Distributions 		}
303*27b03b36SApple OSS Distributions 
304*27b03b36SApple OSS Distributions 		goto exit_log;
305*27b03b36SApple OSS Distributions 	}
306*27b03b36SApple OSS Distributions 
307*27b03b36SApple OSS Distributions 	time_now = mach_continuous_time();
308*27b03b36SApple OSS Distributions 
309*27b03b36SApple OSS Distributions 	if ((int64_t)(mpte->mpte_time_target - time_now) > 0) {
310*27b03b36SApple OSS Distributions 		ret = thread_call_enter(mpte->mpte_stop_urgency);
311*27b03b36SApple OSS Distributions 
312*27b03b36SApple OSS Distributions 		if (!ret) {
313*27b03b36SApple OSS Distributions 			mp_so->so_usecount++;
314*27b03b36SApple OSS Distributions 		}
315*27b03b36SApple OSS Distributions 
316*27b03b36SApple OSS Distributions 		ret = thread_call_enter_delayed_with_leeway(mpte->mpte_time_thread, NULL,
317*27b03b36SApple OSS Distributions 		    mpte->mpte_time_target, 0, THREAD_CALL_CONTINUOUS);
318*27b03b36SApple OSS Distributions 
319*27b03b36SApple OSS Distributions 		if (!ret) {
320*27b03b36SApple OSS Distributions 			mp_so->so_usecount++;
321*27b03b36SApple OSS Distributions 		}
322*27b03b36SApple OSS Distributions 	} else if ((int64_t)(mpte->mpte_time_target - time_now) <= 0) {
323*27b03b36SApple OSS Distributions 		/* Already passed the deadline, trigger subflows now */
324*27b03b36SApple OSS Distributions 		ret = thread_call_enter(mpte->mpte_time_thread);
325*27b03b36SApple OSS Distributions 
326*27b03b36SApple OSS Distributions 		if (!ret) {
327*27b03b36SApple OSS Distributions 			mp_so->so_usecount++;
328*27b03b36SApple OSS Distributions 		}
329*27b03b36SApple OSS Distributions 	}
330*27b03b36SApple OSS Distributions 
331*27b03b36SApple OSS Distributions exit_log:
332*27b03b36SApple OSS Distributions 	os_log(mptcp_log_handle, "%s - %lx: timer at %llu now %llu usecount %u ret %u\n",
333*27b03b36SApple OSS Distributions 	    __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte), mpte->mpte_time_target, time_now,
334*27b03b36SApple OSS Distributions 	    mp_so->so_usecount, ret);
335*27b03b36SApple OSS Distributions }
336*27b03b36SApple OSS Distributions 
337*27b03b36SApple OSS Distributions static int
mptcp_cancel_urgency_timer(struct mptses * mpte)338*27b03b36SApple OSS Distributions mptcp_cancel_urgency_timer(struct mptses *mpte)
339*27b03b36SApple OSS Distributions {
340*27b03b36SApple OSS Distributions 	struct socket *mp_so = mptetoso(mpte);
341*27b03b36SApple OSS Distributions 	boolean_t ret;
342*27b03b36SApple OSS Distributions 
343*27b03b36SApple OSS Distributions 	ret = thread_call_cancel(mpte->mpte_time_thread);
344*27b03b36SApple OSS Distributions 
345*27b03b36SApple OSS Distributions 	os_log(mptcp_log_handle, "%s - %lx: Canceled timer thread usecount %u ret %u\n",
346*27b03b36SApple OSS Distributions 	    __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte), mp_so->so_usecount, ret);
347*27b03b36SApple OSS Distributions 
348*27b03b36SApple OSS Distributions 	mptcp_check_subflows_and_remove(mpte);
349*27b03b36SApple OSS Distributions 
350*27b03b36SApple OSS Distributions 	if (ret) {
351*27b03b36SApple OSS Distributions 		mp_so->so_usecount--;
352*27b03b36SApple OSS Distributions 	}
353*27b03b36SApple OSS Distributions 
354*27b03b36SApple OSS Distributions 	ret = thread_call_cancel(mpte->mpte_stop_urgency);
355*27b03b36SApple OSS Distributions 	if (ret) {
356*27b03b36SApple OSS Distributions 		mp_so->so_usecount--;
357*27b03b36SApple OSS Distributions 	}
358*27b03b36SApple OSS Distributions 
359*27b03b36SApple OSS Distributions 	return 0;
360*27b03b36SApple OSS Distributions }
361