xref: /freebsd/sys/netinet/tcp_hpts.c (revision 5405b282e1f319b6f3597bb77f68be903e7f248c)
1 /*-
2  * Copyright (c) 2016-2018 Netflix, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  */
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28 
29 #include "opt_inet.h"
30 #include "opt_inet6.h"
31 #include "opt_tcpdebug.h"
32 /**
33  * Some notes about usage.
34  *
35  * The tcp_hpts system is designed to provide a high precision timer
36  * system for tcp. Its main purpose is to provide a mechanism for
37  * pacing packets out onto the wire. It can be used in two ways
38  * by a given TCP stack (and those two methods can be used simultaneously).
39  *
40  * First, and probably the main thing its used by Rack and BBR for, it can
41  * be used to call tcp_output() of a transport stack at some time in the future.
42  * The normal way this is done is that tcp_output() of the stack schedules
43  * itself to be called again by calling tcp_hpts_insert(tcpcb, slot). The
44  * slot is the time from now that the stack wants to be called but it
45  * must be converted to tcp_hpts's notion of slot. This is done with
46  * one of the macros HPTS_MS_TO_SLOTS or HPTS_USEC_TO_SLOTS. So a typical
47  * call from the tcp_output() routine might look like:
48  *
49  * tcp_hpts_insert(tp, HPTS_USEC_TO_SLOTS(550));
50  *
51  * The above would schedule tcp_ouput() to be called in 550 useconds.
52  * Note that if using this mechanism the stack will want to add near
53  * its top a check to prevent unwanted calls (from user land or the
54  * arrival of incoming ack's). So it would add something like:
55  *
56  * if (inp->inp_in_hpts)
57  *    return;
58  *
59  * to prevent output processing until the time alotted has gone by.
60  * Of course this is a bare bones example and the stack will probably
61  * have more consideration then just the above.
62  *
63  * Now the tcp_hpts system will call tcp_output in one of two forms,
64  * it will first check to see if the stack as defined a
65  * tfb_tcp_output_wtime() function, if so that is the routine it
66  * will call, if that function is not defined then it will call the
67  * tfb_tcp_output() function. The only difference between these
68  * two calls is that the former passes the time in to the function
69  * so the function does not have to access the time (which tcp_hpts
70  * already has). What these functions do is of course totally up
71  * to the individual tcp stack.
72  *
73  * Now the second function (actually two functions I guess :D)
74  * the tcp_hpts system provides is the  ability to either abort
75  * a connection (later) or process  input on a connection.
76  * Why would you want to do this? To keep processor locality.
77  *
78  * So in order to use the input redirection function the
79  * stack changes its tcp_do_segment() routine to instead
80  * of process the data call the function:
81  *
82  * tcp_queue_pkt_to_input()
83  *
84  * You will note that the arguments to this function look
85  * a lot like tcp_do_segments's arguments. This function
86  * will assure that the tcp_hpts system will
87  * call the functions tfb_tcp_hpts_do_segment() from the
88  * correct CPU. Note that multiple calls can get pushed
89  * into the tcp_hpts system this will be indicated by
90  * the next to last argument to tfb_tcp_hpts_do_segment()
91  * (nxt_pkt). If nxt_pkt is a 1 then another packet is
92  * coming. If nxt_pkt is a 0 then this is the last call
93  * that the tcp_hpts system has available for the tcp stack.
94  *
95  * The other point of the input system is to be able to safely
96  * drop a tcp connection without worrying about the recursive
97  * locking that may be occuring on the INP_WLOCK. So if
98  * a stack wants to drop a connection it calls:
99  *
100  *     tcp_set_inp_to_drop(tp, ETIMEDOUT)
101  *
102  * To schedule the tcp_hpts system to call
103  *
104  *    tcp_drop(tp, drop_reason)
105  *
106  * at a future point. This is quite handy to prevent locking
107  * issues when dropping connections.
108  *
109  */
110 
111 #include <sys/param.h>
112 #include <sys/bus.h>
113 #include <sys/interrupt.h>
114 #include <sys/module.h>
115 #include <sys/kernel.h>
116 #include <sys/hhook.h>
117 #include <sys/malloc.h>
118 #include <sys/mbuf.h>
119 #include <sys/proc.h>		/* for proc0 declaration */
120 #include <sys/socket.h>
121 #include <sys/socketvar.h>
122 #include <sys/sysctl.h>
123 #include <sys/systm.h>
124 #include <sys/refcount.h>
125 #include <sys/sched.h>
126 #include <sys/queue.h>
127 #include <sys/smp.h>
128 #include <sys/counter.h>
129 #include <sys/time.h>
130 #include <sys/kthread.h>
131 #include <sys/kern_prefetch.h>
132 
133 #include <vm/uma.h>
134 #include <vm/vm.h>
135 
136 #include <net/route.h>
137 #include <net/vnet.h>
138 
139 #define TCPSTATES		/* for logging */
140 
141 #include <netinet/in.h>
142 #include <netinet/in_kdtrace.h>
143 #include <netinet/in_pcb.h>
144 #include <netinet/ip.h>
145 #include <netinet/ip_icmp.h>	/* required for icmp_var.h */
146 #include <netinet/icmp_var.h>	/* for ICMP_BANDLIM */
147 #include <netinet/ip_var.h>
148 #include <netinet/ip6.h>
149 #include <netinet6/in6_pcb.h>
150 #include <netinet6/ip6_var.h>
151 #include <netinet/tcp.h>
152 #include <netinet/tcp_fsm.h>
153 #include <netinet/tcp_seq.h>
154 #include <netinet/tcp_timer.h>
155 #include <netinet/tcp_var.h>
156 #include <netinet/tcpip.h>
157 #include <netinet/cc/cc.h>
158 #include <netinet/tcp_hpts.h>
159 
160 #ifdef tcpdebug
161 #include <netinet/tcp_debug.h>
162 #endif				/* tcpdebug */
163 #ifdef tcp_offload
164 #include <netinet/tcp_offload.h>
165 #endif
166 
167 #include "opt_rss.h"
168 
169 MALLOC_DEFINE(M_TCPHPTS, "tcp_hpts", "TCP hpts");
170 #ifdef RSS
171 #include <net/netisr.h>
172 #include <net/rss_config.h>
173 static int tcp_bind_threads = 1;
174 #else
175 static int tcp_bind_threads = 2;
176 #endif
177 TUNABLE_INT("net.inet.tcp.bind_hptss", &tcp_bind_threads);
178 
179 static uint32_t tcp_hpts_logging_size = DEFAULT_HPTS_LOG;
180 
181 TUNABLE_INT("net.inet.tcp.hpts_logging_sz", &tcp_hpts_logging_size);
182 
183 static struct tcp_hptsi tcp_pace;
184 
185 static void tcp_wakehpts(struct tcp_hpts_entry *p);
186 static void tcp_wakeinput(struct tcp_hpts_entry *p);
187 static void tcp_input_data(struct tcp_hpts_entry *hpts, struct timeval *tv);
188 static void tcp_hptsi(struct tcp_hpts_entry *hpts, struct timeval *ctick);
189 static void tcp_hpts_thread(void *ctx);
190 static void tcp_init_hptsi(void *st);
191 
192 int32_t tcp_min_hptsi_time = DEFAULT_MIN_SLEEP;
193 static int32_t tcp_hpts_callout_skip_swi = 0;
194 
195 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hpts, CTLFLAG_RW, 0, "TCP Hpts controls");
196 
197 #define	timersub(tvp, uvp, vvp)						\
198 	do {								\
199 		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
200 		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
201 		if ((vvp)->tv_usec < 0) {				\
202 			(vvp)->tv_sec--;				\
203 			(vvp)->tv_usec += 1000000;			\
204 		}							\
205 	} while (0)
206 
207 static int32_t logging_on = 0;
208 static int32_t hpts_sleep_max = (NUM_OF_HPTSI_SLOTS - 2);
209 static int32_t tcp_hpts_precision = 120;
210 
211 struct hpts_domain_info {
212 	int count;
213 	int cpu[MAXCPU];
214 };
215 
216 struct hpts_domain_info hpts_domains[MAXMEMDOM];
217 
218 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, precision, CTLFLAG_RW,
219     &tcp_hpts_precision, 120,
220     "Value for PRE() precision of callout");
221 
222 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, logging, CTLFLAG_RW,
223     &logging_on, 0,
224     "Turn on logging if compiled in");
225 
226 counter_u64_t hpts_loops;
227 
228 SYSCTL_COUNTER_U64(_net_inet_tcp_hpts, OID_AUTO, loops, CTLFLAG_RD,
229     &hpts_loops, "Number of times hpts had to loop to catch up");
230 
231 counter_u64_t back_tosleep;
232 
233 SYSCTL_COUNTER_U64(_net_inet_tcp_hpts, OID_AUTO, no_tcbsfound, CTLFLAG_RD,
234     &back_tosleep, "Number of times hpts found no tcbs");
235 
236 static int32_t in_newts_every_tcb = 0;
237 
238 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, in_tsperpcb, CTLFLAG_RW,
239     &in_newts_every_tcb, 0,
240     "Do we have a new cts every tcb we process for input");
241 static int32_t in_ts_percision = 0;
242 
243 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, in_tspercision, CTLFLAG_RW,
244     &in_ts_percision, 0,
245     "Do we use percise timestamp for clients on input");
246 static int32_t out_newts_every_tcb = 0;
247 
248 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, out_tsperpcb, CTLFLAG_RW,
249     &out_newts_every_tcb, 0,
250     "Do we have a new cts every tcb we process for output");
251 static int32_t out_ts_percision = 0;
252 
253 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, out_tspercision, CTLFLAG_RW,
254     &out_ts_percision, 0,
255     "Do we use a percise timestamp for every output cts");
256 
257 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, maxsleep, CTLFLAG_RW,
258     &hpts_sleep_max, 0,
259     "The maximum time the hpts will sleep <1 - 254>");
260 
261 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, minsleep, CTLFLAG_RW,
262     &tcp_min_hptsi_time, 0,
263     "The minimum time the hpts must sleep before processing more slots");
264 
265 SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, skip_swi, CTLFLAG_RW,
266     &tcp_hpts_callout_skip_swi, 0,
267     "Do we have the callout call directly to the hpts?");
268 
269 static void
270 __tcp_hpts_log_it(struct tcp_hpts_entry *hpts, struct inpcb *inp, int event, uint32_t slot,
271     uint32_t ticknow, int32_t line)
272 {
273 	struct hpts_log *pl;
274 
275 	HPTS_MTX_ASSERT(hpts);
276 	if (hpts->p_log == NULL)
277 		return;
278 	pl = &hpts->p_log[hpts->p_log_at];
279 	hpts->p_log_at++;
280 	if (hpts->p_log_at >= hpts->p_logsize) {
281 		hpts->p_log_at = 0;
282 		hpts->p_log_wrapped = 1;
283 	}
284 	pl->inp = inp;
285 	if (inp) {
286 		pl->t_paceslot = inp->inp_hptsslot;
287 		pl->t_hptsreq = inp->inp_hpts_request;
288 		pl->p_onhpts = inp->inp_in_hpts;
289 		pl->p_oninput = inp->inp_in_input;
290 	} else {
291 		pl->t_paceslot = 0;
292 		pl->t_hptsreq = 0;
293 		pl->p_onhpts = 0;
294 		pl->p_oninput = 0;
295 	}
296 	pl->is_notempty = 1;
297 	pl->event = event;
298 	pl->line = line;
299 	pl->cts = tcp_get_usecs(NULL);
300 	pl->p_curtick = hpts->p_curtick;
301 	pl->p_prevtick = hpts->p_prevtick;
302 	pl->p_on_queue_cnt = hpts->p_on_queue_cnt;
303 	pl->ticknow = ticknow;
304 	pl->slot_req = slot;
305 	pl->p_nxt_slot = hpts->p_nxt_slot;
306 	pl->p_cur_slot = hpts->p_cur_slot;
307 	pl->p_hpts_sleep_time = hpts->p_hpts_sleep_time;
308 	pl->p_flags = (hpts->p_cpu & 0x7f);
309 	pl->p_flags <<= 7;
310 	pl->p_flags |= (hpts->p_num & 0x7f);
311 	pl->p_flags <<= 2;
312 	if (hpts->p_hpts_active) {
313 		pl->p_flags |= HPTS_HPTS_ACTIVE;
314 	}
315 }
316 
317 #define tcp_hpts_log_it(a, b, c, d, e) __tcp_hpts_log_it(a, b, c, d, e, __LINE__)
318 
319 static void
320 hpts_timeout_swi(void *arg)
321 {
322 	struct tcp_hpts_entry *hpts;
323 
324 	hpts = (struct tcp_hpts_entry *)arg;
325 	swi_sched(hpts->ie_cookie, 0);
326 }
327 
328 static void
329 hpts_timeout_dir(void *arg)
330 {
331 	tcp_hpts_thread(arg);
332 }
333 
334 static inline void
335 hpts_sane_pace_remove(struct tcp_hpts_entry *hpts, struct inpcb *inp, struct hptsh *head, int clear)
336 {
337 #ifdef INVARIANTS
338 	if (mtx_owned(&hpts->p_mtx) == 0) {
339 		/* We don't own the mutex? */
340 		panic("%s: hpts:%p inp:%p no hpts mutex", __FUNCTION__, hpts, inp);
341 	}
342 	if (hpts->p_cpu != inp->inp_hpts_cpu) {
343 		/* It is not the right cpu/mutex? */
344 		panic("%s: hpts:%p inp:%p incorrect CPU", __FUNCTION__, hpts, inp);
345 	}
346 	if (inp->inp_in_hpts == 0) {
347 		/* We are not on the hpts? */
348 		panic("%s: hpts:%p inp:%p not on the hpts?", __FUNCTION__, hpts, inp);
349 	}
350 	if (TAILQ_EMPTY(head) &&
351 	    (hpts->p_on_queue_cnt != 0)) {
352 		/* We should not be empty with a queue count */
353 		panic("%s hpts:%p hpts bucket empty but cnt:%d",
354 		    __FUNCTION__, hpts, hpts->p_on_queue_cnt);
355 	}
356 #endif
357 	TAILQ_REMOVE(head, inp, inp_hpts);
358 	hpts->p_on_queue_cnt--;
359 	if (hpts->p_on_queue_cnt < 0) {
360 		/* Count should not go negative .. */
361 #ifdef INVARIANTS
362 		panic("Hpts goes negative inp:%p hpts:%p",
363 		    inp, hpts);
364 #endif
365 		hpts->p_on_queue_cnt = 0;
366 	}
367 	if (clear) {
368 		inp->inp_hpts_request = 0;
369 		inp->inp_in_hpts = 0;
370 	}
371 }
372 
373 static inline void
374 hpts_sane_pace_insert(struct tcp_hpts_entry *hpts, struct inpcb *inp, struct hptsh *head, int line, int noref)
375 {
376 #ifdef INVARIANTS
377 	if (mtx_owned(&hpts->p_mtx) == 0) {
378 		/* We don't own the mutex? */
379 		panic("%s: hpts:%p inp:%p no hpts mutex", __FUNCTION__, hpts, inp);
380 	}
381 	if (hpts->p_cpu != inp->inp_hpts_cpu) {
382 		/* It is not the right cpu/mutex? */
383 		panic("%s: hpts:%p inp:%p incorrect CPU", __FUNCTION__, hpts, inp);
384 	}
385 	if ((noref == 0) && (inp->inp_in_hpts == 1)) {
386 		/* We are already on the hpts? */
387 		panic("%s: hpts:%p inp:%p already on the hpts?", __FUNCTION__, hpts, inp);
388 	}
389 #endif
390 	TAILQ_INSERT_TAIL(head, inp, inp_hpts);
391 	inp->inp_in_hpts = 1;
392 	hpts->p_on_queue_cnt++;
393 	if (noref == 0) {
394 		in_pcbref(inp);
395 	}
396 }
397 
398 static inline void
399 hpts_sane_input_remove(struct tcp_hpts_entry *hpts, struct inpcb *inp, int clear)
400 {
401 #ifdef INVARIANTS
402 	if (mtx_owned(&hpts->p_mtx) == 0) {
403 		/* We don't own the mutex? */
404 		panic("%s: hpts:%p inp:%p no hpts mutex", __FUNCTION__, hpts, inp);
405 	}
406 	if (hpts->p_cpu != inp->inp_input_cpu) {
407 		/* It is not the right cpu/mutex? */
408 		panic("%s: hpts:%p inp:%p incorrect CPU", __FUNCTION__, hpts, inp);
409 	}
410 	if (inp->inp_in_input == 0) {
411 		/* We are not on the input hpts? */
412 		panic("%s: hpts:%p inp:%p not on the input hpts?", __FUNCTION__, hpts, inp);
413 	}
414 #endif
415 	TAILQ_REMOVE(&hpts->p_input, inp, inp_input);
416 	hpts->p_on_inqueue_cnt--;
417 	if (hpts->p_on_inqueue_cnt < 0) {
418 #ifdef INVARIANTS
419 		panic("Hpts in goes negative inp:%p hpts:%p",
420 		    inp, hpts);
421 #endif
422 		hpts->p_on_inqueue_cnt = 0;
423 	}
424 #ifdef INVARIANTS
425 	if (TAILQ_EMPTY(&hpts->p_input) &&
426 	    (hpts->p_on_inqueue_cnt != 0)) {
427 		/* We should not be empty with a queue count */
428 		panic("%s hpts:%p in_hpts input empty but cnt:%d",
429 		    __FUNCTION__, hpts, hpts->p_on_inqueue_cnt);
430 	}
431 #endif
432 	if (clear)
433 		inp->inp_in_input = 0;
434 }
435 
436 static inline void
437 hpts_sane_input_insert(struct tcp_hpts_entry *hpts, struct inpcb *inp, int line)
438 {
439 #ifdef INVARIANTS
440 	if (mtx_owned(&hpts->p_mtx) == 0) {
441 		/* We don't own the mutex? */
442 		panic("%s: hpts:%p inp:%p no hpts mutex", __FUNCTION__, hpts, inp);
443 	}
444 	if (hpts->p_cpu != inp->inp_input_cpu) {
445 		/* It is not the right cpu/mutex? */
446 		panic("%s: hpts:%p inp:%p incorrect CPU", __FUNCTION__, hpts, inp);
447 	}
448 	if (inp->inp_in_input == 1) {
449 		/* We are already on the input hpts? */
450 		panic("%s: hpts:%p inp:%p already on the input hpts?", __FUNCTION__, hpts, inp);
451 	}
452 #endif
453 	TAILQ_INSERT_TAIL(&hpts->p_input, inp, inp_input);
454 	inp->inp_in_input = 1;
455 	hpts->p_on_inqueue_cnt++;
456 	in_pcbref(inp);
457 }
458 
459 static int
460 sysctl_tcp_hpts_log(SYSCTL_HANDLER_ARGS)
461 {
462 	struct tcp_hpts_entry *hpts;
463 	size_t sz;
464 	int32_t logging_was, i;
465 	int32_t error = 0;
466 
467 	/*
468 	 * HACK: Turn off logging so no locks are required this really needs
469 	 * a memory barrier :)
470 	 */
471 	logging_was = logging_on;
472 	logging_on = 0;
473 	if (!req->oldptr) {
474 		/* How much? */
475 		sz = 0;
476 		for (i = 0; i < tcp_pace.rp_num_hptss; i++) {
477 			hpts = tcp_pace.rp_ent[i];
478 			if (hpts->p_log == NULL)
479 				continue;
480 			sz += (sizeof(struct hpts_log) * hpts->p_logsize);
481 		}
482 		error = SYSCTL_OUT(req, 0, sz);
483 	} else {
484 		for (i = 0; i < tcp_pace.rp_num_hptss; i++) {
485 			hpts = tcp_pace.rp_ent[i];
486 			if (hpts->p_log == NULL)
487 				continue;
488 			if (hpts->p_log_wrapped)
489 				sz = (sizeof(struct hpts_log) * hpts->p_logsize);
490 			else
491 				sz = (sizeof(struct hpts_log) * hpts->p_log_at);
492 			error = SYSCTL_OUT(req, hpts->p_log, sz);
493 		}
494 	}
495 	logging_on = logging_was;
496 	return error;
497 }
498 
499 SYSCTL_PROC(_net_inet_tcp_hpts, OID_AUTO, log, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
500     0, 0, sysctl_tcp_hpts_log, "A", "tcp hptsi log");
501 
502 
503 static void
504 tcp_wakehpts(struct tcp_hpts_entry *hpts)
505 {
506 	HPTS_MTX_ASSERT(hpts);
507 	swi_sched(hpts->ie_cookie, 0);
508 	if (hpts->p_hpts_active == 2) {
509 		/* Rare sleeping on a ENOBUF */
510 		wakeup_one(hpts);
511 	}
512 }
513 
514 static void
515 tcp_wakeinput(struct tcp_hpts_entry *hpts)
516 {
517 	HPTS_MTX_ASSERT(hpts);
518 	swi_sched(hpts->ie_cookie, 0);
519 	if (hpts->p_hpts_active == 2) {
520 		/* Rare sleeping on a ENOBUF */
521 		wakeup_one(hpts);
522 	}
523 }
524 
525 struct tcp_hpts_entry *
526 tcp_cur_hpts(struct inpcb *inp)
527 {
528 	int32_t hpts_num;
529 	struct tcp_hpts_entry *hpts;
530 
531 	hpts_num = inp->inp_hpts_cpu;
532 	hpts = tcp_pace.rp_ent[hpts_num];
533 	return (hpts);
534 }
535 
536 struct tcp_hpts_entry *
537 tcp_hpts_lock(struct inpcb *inp)
538 {
539 	struct tcp_hpts_entry *hpts;
540 	int32_t hpts_num;
541 
542 again:
543 	hpts_num = inp->inp_hpts_cpu;
544 	hpts = tcp_pace.rp_ent[hpts_num];
545 #ifdef INVARIANTS
546 	if (mtx_owned(&hpts->p_mtx)) {
547 		panic("Hpts:%p owns mtx prior-to lock line:%d",
548 		    hpts, __LINE__);
549 	}
550 #endif
551 	mtx_lock(&hpts->p_mtx);
552 	if (hpts_num != inp->inp_hpts_cpu) {
553 		mtx_unlock(&hpts->p_mtx);
554 		goto again;
555 	}
556 	return (hpts);
557 }
558 
559 struct tcp_hpts_entry *
560 tcp_input_lock(struct inpcb *inp)
561 {
562 	struct tcp_hpts_entry *hpts;
563 	int32_t hpts_num;
564 
565 again:
566 	hpts_num = inp->inp_input_cpu;
567 	hpts = tcp_pace.rp_ent[hpts_num];
568 #ifdef INVARIANTS
569 	if (mtx_owned(&hpts->p_mtx)) {
570 		panic("Hpts:%p owns mtx prior-to lock line:%d",
571 		    hpts, __LINE__);
572 	}
573 #endif
574 	mtx_lock(&hpts->p_mtx);
575 	if (hpts_num != inp->inp_input_cpu) {
576 		mtx_unlock(&hpts->p_mtx);
577 		goto again;
578 	}
579 	return (hpts);
580 }
581 
582 static void
583 tcp_remove_hpts_ref(struct inpcb *inp, struct tcp_hpts_entry *hpts, int line)
584 {
585 	int32_t add_freed;
586 
587 	if (inp->inp_flags2 & INP_FREED) {
588 		/*
589 		 * Need to play a special trick so that in_pcbrele_wlocked
590 		 * does not return 1 when it really should have returned 0.
591 		 */
592 		add_freed = 1;
593 		inp->inp_flags2 &= ~INP_FREED;
594 	} else {
595 		add_freed = 0;
596 	}
597 #ifndef INP_REF_DEBUG
598 	if (in_pcbrele_wlocked(inp)) {
599 		/*
600 		 * This should not happen. We have the inpcb referred to by
601 		 * the main socket (why we are called) and the hpts. It
602 		 * should always return 0.
603 		 */
604 		panic("inpcb:%p release ret 1",
605 		    inp);
606 	}
607 #else
608 	if (__in_pcbrele_wlocked(inp, line)) {
609 		/*
610 		 * This should not happen. We have the inpcb referred to by
611 		 * the main socket (why we are called) and the hpts. It
612 		 * should always return 0.
613 		 */
614 		panic("inpcb:%p release ret 1",
615 		    inp);
616 	}
617 #endif
618 	if (add_freed) {
619 		inp->inp_flags2 |= INP_FREED;
620 	}
621 }
622 
623 static void
624 tcp_hpts_remove_locked_output(struct tcp_hpts_entry *hpts, struct inpcb *inp, int32_t flags, int32_t line)
625 {
626 	if (inp->inp_in_hpts) {
627 		hpts_sane_pace_remove(hpts, inp, &hpts->p_hptss[inp->inp_hptsslot], 1);
628 		tcp_remove_hpts_ref(inp, hpts, line);
629 	}
630 }
631 
632 static void
633 tcp_hpts_remove_locked_input(struct tcp_hpts_entry *hpts, struct inpcb *inp, int32_t flags, int32_t line)
634 {
635 	HPTS_MTX_ASSERT(hpts);
636 	if (inp->inp_in_input) {
637 		hpts_sane_input_remove(hpts, inp, 1);
638 		tcp_remove_hpts_ref(inp, hpts, line);
639 	}
640 }
641 
642 /*
643  * Called normally with the INP_LOCKED but it
644  * does not matter, the hpts lock is the key
645  * but the lock order allows us to hold the
646  * INP lock and then get the hpts lock.
647  *
648  * Valid values in the flags are
649  * HPTS_REMOVE_OUTPUT - remove from the output of the hpts.
650  * HPTS_REMOVE_INPUT - remove from the input of the hpts.
651  * Note that you can or both values together and get two
652  * actions.
653  */
654 void
655 __tcp_hpts_remove(struct inpcb *inp, int32_t flags, int32_t line)
656 {
657 	struct tcp_hpts_entry *hpts;
658 
659 	INP_WLOCK_ASSERT(inp);
660 	if (flags & HPTS_REMOVE_OUTPUT) {
661 		hpts = tcp_hpts_lock(inp);
662 		tcp_hpts_remove_locked_output(hpts, inp, flags, line);
663 		mtx_unlock(&hpts->p_mtx);
664 	}
665 	if (flags & HPTS_REMOVE_INPUT) {
666 		hpts = tcp_input_lock(inp);
667 		tcp_hpts_remove_locked_input(hpts, inp, flags, line);
668 		mtx_unlock(&hpts->p_mtx);
669 	}
670 }
671 
672 static inline int
673 hpts_tick(struct tcp_hpts_entry *hpts, int32_t plus)
674 {
675 	return ((hpts->p_prevtick + plus) % NUM_OF_HPTSI_SLOTS);
676 }
677 
678 static int
679 tcp_queue_to_hpts_immediate_locked(struct inpcb *inp, struct tcp_hpts_entry *hpts, int32_t line, int32_t noref)
680 {
681 	int32_t need_wake = 0;
682 	uint32_t ticknow = 0;
683 
684 	HPTS_MTX_ASSERT(hpts);
685 	if (inp->inp_in_hpts == 0) {
686 		/* Ok we need to set it on the hpts in the current slot */
687 		if (hpts->p_hpts_active == 0) {
688 			/* A sleeping hpts we want in next slot to run */
689 			if (logging_on) {
690 				tcp_hpts_log_it(hpts, inp, HPTSLOG_INSERT_SLEEPER, 0,
691 				    hpts_tick(hpts, 1));
692 			}
693 			inp->inp_hptsslot = hpts_tick(hpts, 1);
694 			inp->inp_hpts_request = 0;
695 			if (logging_on) {
696 				tcp_hpts_log_it(hpts, inp, HPTSLOG_SLEEP_BEFORE, 1, ticknow);
697 			}
698 			need_wake = 1;
699 		} else if ((void *)inp == hpts->p_inp) {
700 			/*
701 			 * We can't allow you to go into the same slot we
702 			 * are in. We must put you out.
703 			 */
704 			inp->inp_hptsslot = hpts->p_nxt_slot;
705 		} else
706 			inp->inp_hptsslot = hpts->p_cur_slot;
707 		hpts_sane_pace_insert(hpts, inp, &hpts->p_hptss[inp->inp_hptsslot], line, noref);
708 		inp->inp_hpts_request = 0;
709 		if (logging_on) {
710 			tcp_hpts_log_it(hpts, inp, HPTSLOG_IMMEDIATE, 0, 0);
711 		}
712 		if (need_wake) {
713 			/*
714 			 * Activate the hpts if it is sleeping and its
715 			 * timeout is not 1.
716 			 */
717 			if (logging_on) {
718 				tcp_hpts_log_it(hpts, inp, HPTSLOG_WAKEUP_HPTS, 0, ticknow);
719 			}
720 			hpts->p_direct_wake = 1;
721 			tcp_wakehpts(hpts);
722 		}
723 	}
724 	return (need_wake);
725 }
726 
727 int
728 __tcp_queue_to_hpts_immediate(struct inpcb *inp, int32_t line)
729 {
730 	int32_t ret;
731 	struct tcp_hpts_entry *hpts;
732 
733 	INP_WLOCK_ASSERT(inp);
734 	hpts = tcp_hpts_lock(inp);
735 	ret = tcp_queue_to_hpts_immediate_locked(inp, hpts, line, 0);
736 	mtx_unlock(&hpts->p_mtx);
737 	return (ret);
738 }
739 
740 static void
741 tcp_hpts_insert_locked(struct tcp_hpts_entry *hpts, struct inpcb *inp, uint32_t slot, uint32_t cts, int32_t line,
742     struct hpts_diag *diag, int32_t noref)
743 {
744 	int32_t need_new_to = 0;
745 	int32_t need_wakeup = 0;
746 	uint32_t largest_slot;
747 	uint32_t ticknow = 0;
748 	uint32_t slot_calc;
749 
750 	HPTS_MTX_ASSERT(hpts);
751 	if (diag) {
752 		memset(diag, 0, sizeof(struct hpts_diag));
753 		diag->p_hpts_active = hpts->p_hpts_active;
754 		diag->p_nxt_slot = hpts->p_nxt_slot;
755 		diag->p_cur_slot = hpts->p_cur_slot;
756 		diag->slot_req = slot;
757 	}
758 	if ((inp->inp_in_hpts == 0) || noref) {
759 		inp->inp_hpts_request = slot;
760 		if (slot == 0) {
761 			/* Immediate */
762 			tcp_queue_to_hpts_immediate_locked(inp, hpts, line, noref);
763 			return;
764 		}
765 		if (hpts->p_hpts_active) {
766 			/*
767 			 * Its slot - 1 since nxt_slot is the next tick that
768 			 * will go off since the hpts is awake
769 			 */
770 			if (logging_on) {
771 				tcp_hpts_log_it(hpts, inp, HPTSLOG_INSERT_NORMAL, slot, 0);
772 			}
773 			/*
774 			 * We want to make sure that we don't place a inp in
775 			 * the range of p_cur_slot <-> p_nxt_slot. If we
776 			 * take from p_nxt_slot to the end, plus p_cur_slot
777 			 * and then take away 2, we will know how many is
778 			 * the max slots we can use.
779 			 */
780 			if (hpts->p_nxt_slot > hpts->p_cur_slot) {
781 				/*
782 				 * Non-wrap case nxt_slot <-> cur_slot we
783 				 * don't want to land in. So the diff gives
784 				 * us what is taken away from the number of
785 				 * slots.
786 				 */
787 				largest_slot = NUM_OF_HPTSI_SLOTS - (hpts->p_nxt_slot - hpts->p_cur_slot);
788 			} else if (hpts->p_nxt_slot == hpts->p_cur_slot) {
789 				largest_slot = NUM_OF_HPTSI_SLOTS - 2;
790 			} else {
791 				/*
792 				 * Wrap case so the diff gives us the number
793 				 * of slots that we can land in.
794 				 */
795 				largest_slot = hpts->p_cur_slot - hpts->p_nxt_slot;
796 			}
797 			/*
798 			 * We take away two so we never have a problem (20
799 			 * usec's) out of 1024000 usecs
800 			 */
801 			largest_slot -= 2;
802 			if (inp->inp_hpts_request > largest_slot) {
803 				/*
804 				 * Restrict max jump of slots and remember
805 				 * leftover
806 				 */
807 				slot = largest_slot;
808 				inp->inp_hpts_request -= largest_slot;
809 			} else {
810 				/* This one will run when we hit it */
811 				inp->inp_hpts_request = 0;
812 			}
813 			if (hpts->p_nxt_slot == hpts->p_cur_slot)
814 				slot_calc = (hpts->p_nxt_slot + slot) % NUM_OF_HPTSI_SLOTS;
815 			else
816 				slot_calc = (hpts->p_nxt_slot + slot - 1) % NUM_OF_HPTSI_SLOTS;
817 			if (slot_calc == hpts->p_cur_slot) {
818 #ifdef INVARIANTS
819 				/* TSNH */
820 				panic("Hpts:%p impossible slot calculation slot_calc:%u slot:%u largest:%u\n",
821 				    hpts, slot_calc, slot, largest_slot);
822 #endif
823 				if (slot_calc)
824 					slot_calc--;
825 				else
826 					slot_calc = NUM_OF_HPTSI_SLOTS - 1;
827 			}
828 			inp->inp_hptsslot = slot_calc;
829 			if (diag) {
830 				diag->inp_hptsslot = inp->inp_hptsslot;
831 			}
832 		} else {
833 			/*
834 			 * The hpts is sleeping, we need to figure out where
835 			 * it will wake up at and if we need to reschedule
836 			 * its time-out.
837 			 */
838 			uint32_t have_slept, yet_to_sleep;
839 			uint32_t slot_now;
840 			struct timeval tv;
841 
842 			ticknow = tcp_gethptstick(&tv);
843 			slot_now = ticknow % NUM_OF_HPTSI_SLOTS;
844 			/*
845 			 * The user wants to be inserted at (slot_now +
846 			 * slot) % NUM_OF_HPTSI_SLOTS, so lets set that up.
847 			 */
848 			largest_slot = NUM_OF_HPTSI_SLOTS - 2;
849 			if (inp->inp_hpts_request > largest_slot) {
850 				/* Adjust the residual in inp_hpts_request */
851 				slot = largest_slot;
852 				inp->inp_hpts_request -= largest_slot;
853 			} else {
854 				/* No residual it all fits */
855 				inp->inp_hpts_request = 0;
856 			}
857 			inp->inp_hptsslot = (slot_now + slot) % NUM_OF_HPTSI_SLOTS;
858 			if (diag) {
859 				diag->slot_now = slot_now;
860 				diag->inp_hptsslot = inp->inp_hptsslot;
861 				diag->p_on_min_sleep = hpts->p_on_min_sleep;
862 			}
863 			if (logging_on) {
864 				tcp_hpts_log_it(hpts, inp, HPTSLOG_INSERT_SLEEPER, slot, ticknow);
865 			}
866 			/* Now do we need to restart the hpts's timer? */
867 			if (TSTMP_GT(ticknow, hpts->p_curtick))
868 				have_slept = ticknow - hpts->p_curtick;
869 			else
870 				have_slept = 0;
871 			if (have_slept < hpts->p_hpts_sleep_time) {
872 				/* This should be what happens */
873 				yet_to_sleep = hpts->p_hpts_sleep_time - have_slept;
874 			} else {
875 				/* We are over-due */
876 				yet_to_sleep = 0;
877 				need_wakeup = 1;
878 			}
879 			if (diag) {
880 				diag->have_slept = have_slept;
881 				diag->yet_to_sleep = yet_to_sleep;
882 				diag->hpts_sleep_time = hpts->p_hpts_sleep_time;
883 			}
884 			if ((hpts->p_on_min_sleep == 0) && (yet_to_sleep > slot)) {
885 				/*
886 				 * We need to reschedule the hptss time-out.
887 				 */
888 				hpts->p_hpts_sleep_time = slot;
889 				need_new_to = slot * HPTS_TICKS_PER_USEC;
890 			}
891 		}
892 		hpts_sane_pace_insert(hpts, inp, &hpts->p_hptss[inp->inp_hptsslot], line, noref);
893 		if (logging_on) {
894 			tcp_hpts_log_it(hpts, inp, HPTSLOG_INSERTED, slot, ticknow);
895 		}
896 		/*
897 		 * Now how far is the hpts sleeping to? if active is 1, its
898 		 * up and ticking we do nothing, otherwise we may need to
899 		 * reschedule its callout if need_new_to is set from above.
900 		 */
901 		if (need_wakeup) {
902 			if (logging_on) {
903 				tcp_hpts_log_it(hpts, inp, HPTSLOG_RESCHEDULE, 1, 0);
904 			}
905 			hpts->p_direct_wake = 1;
906 			tcp_wakehpts(hpts);
907 			if (diag) {
908 				diag->need_new_to = 0;
909 				diag->co_ret = 0xffff0000;
910 			}
911 		} else if (need_new_to) {
912 			int32_t co_ret;
913 			struct timeval tv;
914 			sbintime_t sb;
915 
916 			tv.tv_sec = 0;
917 			tv.tv_usec = 0;
918 			while (need_new_to > HPTS_USEC_IN_SEC) {
919 				tv.tv_sec++;
920 				need_new_to -= HPTS_USEC_IN_SEC;
921 			}
922 			tv.tv_usec = need_new_to;
923 			sb = tvtosbt(tv);
924 			if (tcp_hpts_callout_skip_swi == 0) {
925 				co_ret = callout_reset_sbt_on(&hpts->co, sb, 0,
926 				    hpts_timeout_swi, hpts, hpts->p_cpu,
927 				    (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision)));
928 			} else {
929 				co_ret = callout_reset_sbt_on(&hpts->co, sb, 0,
930 				    hpts_timeout_dir, hpts,
931 				    hpts->p_cpu,
932 				    C_PREL(tcp_hpts_precision));
933 			}
934 			if (diag) {
935 				diag->need_new_to = need_new_to;
936 				diag->co_ret = co_ret;
937 			}
938 		}
939 	} else {
940 #ifdef INVARIANTS
941 		panic("Hpts:%p tp:%p already on hpts and add?", hpts, inp);
942 #endif
943 	}
944 }
945 
946 uint32_t
947 tcp_hpts_insert_diag(struct inpcb *inp, uint32_t slot, int32_t line, struct hpts_diag *diag){
948 	struct tcp_hpts_entry *hpts;
949 	uint32_t slot_on, cts;
950 	struct timeval tv;
951 
952 	/*
953 	 * We now return the next-slot the hpts will be on, beyond its
954 	 * current run (if up) or where it was when it stopped if it is
955 	 * sleeping.
956 	 */
957 	INP_WLOCK_ASSERT(inp);
958 	hpts = tcp_hpts_lock(inp);
959 	if (in_ts_percision)
960 		microuptime(&tv);
961 	else
962 		getmicrouptime(&tv);
963 	cts = tcp_tv_to_usectick(&tv);
964 	tcp_hpts_insert_locked(hpts, inp, slot, cts, line, diag, 0);
965 	slot_on = hpts->p_nxt_slot;
966 	mtx_unlock(&hpts->p_mtx);
967 	return (slot_on);
968 }
969 
970 uint32_t
971 __tcp_hpts_insert(struct inpcb *inp, uint32_t slot, int32_t line){
972 	return (tcp_hpts_insert_diag(inp, slot, line, NULL));
973 }
974 
975 int
976 __tcp_queue_to_input_locked(struct inpcb *inp, struct tcp_hpts_entry *hpts, int32_t line)
977 {
978 	int32_t retval = 0;
979 
980 	HPTS_MTX_ASSERT(hpts);
981 	if (inp->inp_in_input == 0) {
982 		/* Ok we need to set it on the hpts in the current slot */
983 		hpts_sane_input_insert(hpts, inp, line);
984 		retval = 1;
985 		if (hpts->p_hpts_active == 0) {
986 			/*
987 			 * Activate the hpts if it is sleeping.
988 			 */
989 			if (logging_on) {
990 				tcp_hpts_log_it(hpts, inp, HPTSLOG_WAKEUP_INPUT, 0, 0);
991 			}
992 			retval = 2;
993 			hpts->p_direct_wake = 1;
994 			tcp_wakeinput(hpts);
995 		}
996 	} else if (hpts->p_hpts_active == 0) {
997 		retval = 4;
998 		hpts->p_direct_wake = 1;
999 		tcp_wakeinput(hpts);
1000 	}
1001 	return (retval);
1002 }
1003 
1004 void
1005 tcp_queue_pkt_to_input(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
1006     int32_t tlen, int32_t drop_hdrlen, uint8_t iptos)
1007 {
1008 	/* Setup packet for input first */
1009 	INP_WLOCK_ASSERT(tp->t_inpcb);
1010 	m->m_pkthdr.pace_thoff = (uint16_t) ((caddr_t)th - mtod(m, caddr_t));
1011 	m->m_pkthdr.pace_tlen = (uint16_t) tlen;
1012 	m->m_pkthdr.pace_drphdrlen = drop_hdrlen;
1013 	m->m_pkthdr.pace_tos = iptos;
1014 	m->m_pkthdr.pace_lock = (curthread->td_epochnest != 0);
1015 	if (tp->t_in_pkt == NULL) {
1016 		tp->t_in_pkt = m;
1017 		tp->t_tail_pkt = m;
1018 	} else {
1019 		tp->t_tail_pkt->m_nextpkt = m;
1020 		tp->t_tail_pkt = m;
1021 	}
1022 }
1023 
1024 
1025 int32_t
1026 __tcp_queue_to_input(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
1027     int32_t tlen, int32_t drop_hdrlen, uint8_t iptos, int32_t line){
1028 	struct tcp_hpts_entry *hpts;
1029 	int32_t ret;
1030 
1031 	tcp_queue_pkt_to_input(tp, m, th, tlen, drop_hdrlen, iptos);
1032 	hpts = tcp_input_lock(tp->t_inpcb);
1033 	ret = __tcp_queue_to_input_locked(tp->t_inpcb, hpts, line);
1034 	mtx_unlock(&hpts->p_mtx);
1035 	return (ret);
1036 }
1037 
1038 void
1039 __tcp_set_inp_to_drop(struct inpcb *inp, uint16_t reason, int32_t line)
1040 {
1041 	struct tcp_hpts_entry *hpts;
1042 	struct tcpcb *tp;
1043 
1044 	tp = intotcpcb(inp);
1045 	hpts = tcp_input_lock(tp->t_inpcb);
1046 	if (inp->inp_in_input == 0) {
1047 		/* Ok we need to set it on the hpts in the current slot */
1048 		hpts_sane_input_insert(hpts, inp, line);
1049 		if (hpts->p_hpts_active == 0) {
1050 			/*
1051 			 * Activate the hpts if it is sleeping.
1052 			 */
1053 			hpts->p_direct_wake = 1;
1054 			tcp_wakeinput(hpts);
1055 		}
1056 	} else if (hpts->p_hpts_active == 0) {
1057 		hpts->p_direct_wake = 1;
1058 		tcp_wakeinput(hpts);
1059 	}
1060 	inp->inp_hpts_drop_reas = reason;
1061 	mtx_unlock(&hpts->p_mtx);
1062 }
1063 
1064 static uint16_t
1065 hpts_random_cpu(struct inpcb *inp){
1066 	/*
1067 	 * No flow type set distribute the load randomly.
1068 	 */
1069 	uint16_t cpuid;
1070 	uint32_t ran;
1071 
1072 	/*
1073 	 * If one has been set use it i.e. we want both in and out on the
1074 	 * same hpts.
1075 	 */
1076 	if (inp->inp_input_cpu_set) {
1077 		return (inp->inp_input_cpu);
1078 	} else if (inp->inp_hpts_cpu_set) {
1079 		return (inp->inp_hpts_cpu);
1080 	}
1081 	/* Nothing set use a random number */
1082 	ran = arc4random();
1083 	cpuid = (ran & 0xffff) % mp_ncpus;
1084 	return (cpuid);
1085 }
1086 
1087 static uint16_t
1088 hpts_cpuid(struct inpcb *inp){
1089 	u_int cpuid;
1090 #ifdef NUMA
1091 	struct hpts_domain_info *di;
1092 #endif
1093 
1094 	/*
1095 	 * If one has been set use it i.e. we want both in and out on the
1096 	 * same hpts.
1097 	 */
1098 	if (inp->inp_input_cpu_set) {
1099 		return (inp->inp_input_cpu);
1100 	} else if (inp->inp_hpts_cpu_set) {
1101 		return (inp->inp_hpts_cpu);
1102 	}
1103 	/* If one is set the other must be the same */
1104 #ifdef	RSS
1105 	cpuid = rss_hash2cpuid(inp->inp_flowid, inp->inp_flowtype);
1106 	if (cpuid == NETISR_CPUID_NONE)
1107 		return (hpts_random_cpu(inp));
1108 	else
1109 		return (cpuid);
1110 #else
1111 	/*
1112 	 * We don't have a flowid -> cpuid mapping, so cheat and just map
1113 	 * unknown cpuids to curcpu.  Not the best, but apparently better
1114 	 * than defaulting to swi 0.
1115 	 */
1116 
1117 	if (inp->inp_flowtype == M_HASHTYPE_NONE)
1118 		return (hpts_random_cpu(inp));
1119 	/*
1120 	 * Hash to a thread based on the flowid.  If we are using numa,
1121 	 * then restrict the hash to the numa domain where the inp lives.
1122 	 */
1123 #ifdef NUMA
1124 	if (tcp_bind_threads == 2 && inp->inp_numa_domain != M_NODOM) {
1125 		di = &hpts_domains[inp->inp_numa_domain];
1126 		cpuid = di->cpu[inp->inp_flowid % di->count];
1127 	} else
1128 #endif
1129 		cpuid = inp->inp_flowid % mp_ncpus;
1130 
1131 	return (cpuid);
1132 #endif
1133 }
1134 
1135 /*
1136  * Do NOT try to optimize the processing of inp's
1137  * by first pulling off all the inp's into a temporary
1138  * list (e.g. TAILQ_CONCAT). If you do that the subtle
1139  * interactions of switching CPU's will kill because of
1140  * problems in the linked list manipulation. Basically
1141  * you would switch cpu's with the hpts mutex locked
1142  * but then while you were processing one of the inp's
1143  * some other one that you switch will get a new
1144  * packet on the different CPU. It will insert it
1145  * on the new hptss input list. Creating a temporary
1146  * link in the inp will not fix it either, since
1147  * the other hpts will be doing the same thing and
1148  * you will both end up using the temporary link.
1149  *
1150  * You will die in an ASSERT for tailq corruption if you
1151  * run INVARIANTS or you will die horribly without
1152  * INVARIANTS in some unknown way with a corrupt linked
1153  * list.
1154  */
1155 static void
1156 tcp_input_data(struct tcp_hpts_entry *hpts, struct timeval *tv)
1157 {
1158 	struct mbuf *m, *n;
1159 	struct tcpcb *tp;
1160 	struct inpcb *inp;
1161 	uint16_t drop_reason;
1162 	int16_t set_cpu;
1163 	uint32_t did_prefetch = 0;
1164 	int32_t ti_locked = TI_UNLOCKED;
1165 	struct epoch_tracker et;
1166 
1167 	HPTS_MTX_ASSERT(hpts);
1168 	while ((inp = TAILQ_FIRST(&hpts->p_input)) != NULL) {
1169 		HPTS_MTX_ASSERT(hpts);
1170 		hpts_sane_input_remove(hpts, inp, 0);
1171 		if (inp->inp_input_cpu_set == 0) {
1172 			set_cpu = 1;
1173 		} else {
1174 			set_cpu = 0;
1175 		}
1176 		hpts->p_inp = inp;
1177 		drop_reason = inp->inp_hpts_drop_reas;
1178 		inp->inp_in_input = 0;
1179 		mtx_unlock(&hpts->p_mtx);
1180 		CURVNET_SET(inp->inp_vnet);
1181 		if (drop_reason) {
1182 			INP_INFO_RLOCK_ET(&V_tcbinfo, et);
1183 			ti_locked = TI_RLOCKED;
1184 		} else {
1185 			ti_locked = TI_UNLOCKED;
1186 		}
1187 		INP_WLOCK(inp);
1188 		if ((inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) ||
1189 		    (inp->inp_flags2 & INP_FREED)) {
1190 out:
1191 			hpts->p_inp = NULL;
1192 			if (ti_locked == TI_RLOCKED) {
1193 				INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
1194 			}
1195 			if (in_pcbrele_wlocked(inp) == 0) {
1196 				INP_WUNLOCK(inp);
1197 			}
1198 			ti_locked = TI_UNLOCKED;
1199 			CURVNET_RESTORE();
1200 			mtx_lock(&hpts->p_mtx);
1201 			continue;
1202 		}
1203 		tp = intotcpcb(inp);
1204 		if ((tp == NULL) || (tp->t_inpcb == NULL)) {
1205 			goto out;
1206 		}
1207 		if (drop_reason) {
1208 			/* This tcb is being destroyed for drop_reason */
1209 			m = tp->t_in_pkt;
1210 			if (m)
1211 				n = m->m_nextpkt;
1212 			else
1213 				n = NULL;
1214 			tp->t_in_pkt = NULL;
1215 			while (m) {
1216 				m_freem(m);
1217 				m = n;
1218 				if (m)
1219 					n = m->m_nextpkt;
1220 			}
1221 			tp = tcp_drop(tp, drop_reason);
1222 			INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
1223 			if (tp == NULL) {
1224 				INP_WLOCK(inp);
1225 			}
1226 			if (in_pcbrele_wlocked(inp) == 0)
1227 				INP_WUNLOCK(inp);
1228 			CURVNET_RESTORE();
1229 			mtx_lock(&hpts->p_mtx);
1230 			continue;
1231 		}
1232 		if (set_cpu) {
1233 			/*
1234 			 * Setup so the next time we will move to the right
1235 			 * CPU. This should be a rare event. It will
1236 			 * sometimes happens when we are the client side
1237 			 * (usually not the server). Somehow tcp_output()
1238 			 * gets called before the tcp_do_segment() sets the
1239 			 * intial state. This means the r_cpu and r_hpts_cpu
1240 			 * is 0. We get on the hpts, and then tcp_input()
1241 			 * gets called setting up the r_cpu to the correct
1242 			 * value. The hpts goes off and sees the mis-match.
1243 			 * We simply correct it here and the CPU will switch
1244 			 * to the new hpts nextime the tcb gets added to the
1245 			 * the hpts (not this time) :-)
1246 			 */
1247 			tcp_set_hpts(inp);
1248 		}
1249 		m = tp->t_in_pkt;
1250 		n = NULL;
1251 		if (m != NULL &&
1252 		    (m->m_pkthdr.pace_lock == TI_RLOCKED ||
1253 		    tp->t_state != TCPS_ESTABLISHED)) {
1254 			ti_locked = TI_RLOCKED;
1255 			INP_INFO_RLOCK_ET(&V_tcbinfo, et);
1256 			m = tp->t_in_pkt;
1257 		}
1258 		if (in_newts_every_tcb) {
1259 			if (in_ts_percision)
1260 				microuptime(tv);
1261 			else
1262 				getmicrouptime(tv);
1263 		}
1264 		if (tp->t_fb_ptr != NULL) {
1265 			kern_prefetch(tp->t_fb_ptr, &did_prefetch);
1266 			did_prefetch = 1;
1267 		}
1268 		/* Any input work to do, if so do it first */
1269 		if ((m != NULL) && (m == tp->t_in_pkt)) {
1270 			struct tcphdr *th;
1271 			int32_t tlen, drop_hdrlen, nxt_pkt;
1272 			uint8_t iptos;
1273 
1274 			n = m->m_nextpkt;
1275 			tp->t_in_pkt = tp->t_tail_pkt = NULL;
1276 			while (m) {
1277 				th = (struct tcphdr *)(mtod(m, caddr_t)+m->m_pkthdr.pace_thoff);
1278 				tlen = m->m_pkthdr.pace_tlen;
1279 				drop_hdrlen = m->m_pkthdr.pace_drphdrlen;
1280 				iptos = m->m_pkthdr.pace_tos;
1281 				m->m_nextpkt = NULL;
1282 				if (n)
1283 					nxt_pkt = 1;
1284 				else
1285 					nxt_pkt = 0;
1286 				inp->inp_input_calls = 1;
1287 				if (tp->t_fb->tfb_tcp_hpts_do_segment) {
1288 					/* Use the hpts specific do_segment */
1289 					(*tp->t_fb->tfb_tcp_hpts_do_segment) (m, th, inp->inp_socket,
1290 					    tp, drop_hdrlen,
1291 					    tlen, iptos, nxt_pkt, tv);
1292 				} else {
1293 					/* Use the default do_segment */
1294 					(*tp->t_fb->tfb_tcp_do_segment) (m, th, inp->inp_socket,
1295 					    tp, drop_hdrlen,
1296 						tlen, iptos);
1297 				}
1298 				if (ti_locked == TI_RLOCKED)
1299 					INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
1300 				/*
1301 				 * Do segment returns unlocked we need the
1302 				 * lock again but we also need some kasserts
1303 				 * here.
1304 				 */
1305 				INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
1306 				INP_UNLOCK_ASSERT(inp);
1307 				m = n;
1308 				if (m)
1309 					n = m->m_nextpkt;
1310 				if (m != NULL &&
1311 				    m->m_pkthdr.pace_lock == TI_RLOCKED) {
1312 					INP_INFO_RLOCK_ET(&V_tcbinfo, et);
1313 					ti_locked = TI_RLOCKED;
1314 				} else
1315 					ti_locked = TI_UNLOCKED;
1316 				INP_WLOCK(inp);
1317 				/*
1318 				 * Since we have an opening here we must
1319 				 * re-check if the tcb went away while we
1320 				 * were getting the lock(s).
1321 				 */
1322 				if ((inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) ||
1323 				    (inp->inp_flags2 & INP_FREED)) {
1324 					while (m) {
1325 						m_freem(m);
1326 						m = n;
1327 						if (m)
1328 							n = m->m_nextpkt;
1329 					}
1330 					goto out;
1331 				}
1332 				/*
1333 				 * Now that we hold the INP lock, check if
1334 				 * we need to upgrade our lock.
1335 				 */
1336 				if (ti_locked == TI_UNLOCKED &&
1337 				    (tp->t_state != TCPS_ESTABLISHED)) {
1338 					ti_locked = TI_RLOCKED;
1339 					INP_INFO_RLOCK_ET(&V_tcbinfo, et);
1340 				}
1341 			}	/** end while(m) */
1342 		}		/** end if ((m != NULL)  && (m == tp->t_in_pkt)) */
1343 		if (in_pcbrele_wlocked(inp) == 0)
1344 			INP_WUNLOCK(inp);
1345 		if (ti_locked == TI_RLOCKED)
1346 			INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
1347 		INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
1348 		INP_UNLOCK_ASSERT(inp);
1349 		ti_locked = TI_UNLOCKED;
1350 		mtx_lock(&hpts->p_mtx);
1351 		hpts->p_inp = NULL;
1352 		CURVNET_RESTORE();
1353 	}
1354 }
1355 
1356 static int
1357 tcp_hpts_est_run(struct tcp_hpts_entry *hpts)
1358 {
1359 	int32_t ticks_to_run;
1360 
1361 	if (hpts->p_prevtick && (SEQ_GT(hpts->p_curtick, hpts->p_prevtick))) {
1362 		ticks_to_run = hpts->p_curtick - hpts->p_prevtick;
1363 		if (ticks_to_run >= (NUM_OF_HPTSI_SLOTS - 1)) {
1364 			ticks_to_run = NUM_OF_HPTSI_SLOTS - 2;
1365 		}
1366 	} else {
1367 		if (hpts->p_prevtick == hpts->p_curtick) {
1368 			/* This happens when we get woken up right away */
1369 			return (-1);
1370 		}
1371 		ticks_to_run = 1;
1372 	}
1373 	/* Set in where we will be when we catch up */
1374 	hpts->p_nxt_slot = (hpts->p_cur_slot + ticks_to_run) % NUM_OF_HPTSI_SLOTS;
1375 	if (hpts->p_nxt_slot == hpts->p_cur_slot) {
1376 		panic("Impossible math -- hpts:%p p_nxt_slot:%d p_cur_slot:%d ticks_to_run:%d",
1377 		    hpts, hpts->p_nxt_slot, hpts->p_cur_slot, ticks_to_run);
1378 	}
1379 	return (ticks_to_run);
1380 }
1381 
1382 static void
1383 tcp_hptsi(struct tcp_hpts_entry *hpts, struct timeval *ctick)
1384 {
1385 	struct tcpcb *tp;
1386 	struct inpcb *inp = NULL, *ninp;
1387 	struct timeval tv;
1388 	int32_t ticks_to_run, i, error, tick_now, interum_tick;
1389 	int32_t paced_cnt = 0;
1390 	int32_t did_prefetch = 0;
1391 	int32_t prefetch_ninp = 0;
1392 	int32_t prefetch_tp = 0;
1393 	uint32_t cts;
1394 	int16_t set_cpu;
1395 
1396 	HPTS_MTX_ASSERT(hpts);
1397 	hpts->p_curtick = tcp_tv_to_hptstick(ctick);
1398 	cts = tcp_tv_to_usectick(ctick);
1399 	memcpy(&tv, ctick, sizeof(struct timeval));
1400 	hpts->p_cur_slot = hpts_tick(hpts, 1);
1401 
1402 	/* Figure out if we had missed ticks */
1403 again:
1404 	HPTS_MTX_ASSERT(hpts);
1405 	ticks_to_run = tcp_hpts_est_run(hpts);
1406 	if (!TAILQ_EMPTY(&hpts->p_input)) {
1407 		tcp_input_data(hpts, &tv);
1408 	}
1409 #ifdef INVARIANTS
1410 	if (TAILQ_EMPTY(&hpts->p_input) &&
1411 	    (hpts->p_on_inqueue_cnt != 0)) {
1412 		panic("tp:%p in_hpts input empty but cnt:%d",
1413 		    hpts, hpts->p_on_inqueue_cnt);
1414 	}
1415 #endif
1416 	HPTS_MTX_ASSERT(hpts);
1417 	/* Reset the ticks to run and time if we need too */
1418 	interum_tick = tcp_gethptstick(&tv);
1419 	if (interum_tick != hpts->p_curtick) {
1420 		/* Save off the new time we execute to */
1421 		*ctick = tv;
1422 		hpts->p_curtick = interum_tick;
1423 		cts = tcp_tv_to_usectick(&tv);
1424 		hpts->p_cur_slot = hpts_tick(hpts, 1);
1425 		ticks_to_run = tcp_hpts_est_run(hpts);
1426 	}
1427 	if (ticks_to_run == -1) {
1428 		goto no_run;
1429 	}
1430 	if (logging_on) {
1431 		tcp_hpts_log_it(hpts, inp, HPTSLOG_SETTORUN, ticks_to_run, 0);
1432 	}
1433 	if (hpts->p_on_queue_cnt == 0) {
1434 		goto no_one;
1435 	}
1436 	HPTS_MTX_ASSERT(hpts);
1437 	for (i = 0; i < ticks_to_run; i++) {
1438 		/*
1439 		 * Calculate our delay, if there are no extra ticks there
1440 		 * was not any
1441 		 */
1442 		hpts->p_delayed_by = (ticks_to_run - (i + 1)) * HPTS_TICKS_PER_USEC;
1443 		HPTS_MTX_ASSERT(hpts);
1444 		while ((inp = TAILQ_FIRST(&hpts->p_hptss[hpts->p_cur_slot])) != NULL) {
1445 			/* For debugging */
1446 			if (logging_on) {
1447 				tcp_hpts_log_it(hpts, inp, HPTSLOG_HPTSI, ticks_to_run, i);
1448 			}
1449 			hpts->p_inp = inp;
1450 			paced_cnt++;
1451 			if (hpts->p_cur_slot != inp->inp_hptsslot) {
1452 				panic("Hpts:%p inp:%p slot mis-aligned %u vs %u",
1453 				    hpts, inp, hpts->p_cur_slot, inp->inp_hptsslot);
1454 			}
1455 			/* Now pull it */
1456 			if (inp->inp_hpts_cpu_set == 0) {
1457 				set_cpu = 1;
1458 			} else {
1459 				set_cpu = 0;
1460 			}
1461 			hpts_sane_pace_remove(hpts, inp, &hpts->p_hptss[hpts->p_cur_slot], 0);
1462 			if ((ninp = TAILQ_FIRST(&hpts->p_hptss[hpts->p_cur_slot])) != NULL) {
1463 				/* We prefetch the next inp if possible */
1464 				kern_prefetch(ninp, &prefetch_ninp);
1465 				prefetch_ninp = 1;
1466 			}
1467 			if (inp->inp_hpts_request) {
1468 				/*
1469 				 * This guy is deferred out further in time
1470 				 * then our wheel had on it. Push him back
1471 				 * on the wheel.
1472 				 */
1473 				int32_t remaining_slots;
1474 
1475 				remaining_slots = ticks_to_run - (i + 1);
1476 				if (inp->inp_hpts_request > remaining_slots) {
1477 					/*
1478 					 * Keep INVARIANTS happy by clearing
1479 					 * the flag
1480 					 */
1481 					tcp_hpts_insert_locked(hpts, inp, inp->inp_hpts_request, cts, __LINE__, NULL, 1);
1482 					hpts->p_inp = NULL;
1483 					continue;
1484 				}
1485 				inp->inp_hpts_request = 0;
1486 			}
1487 			/*
1488 			 * We clear the hpts flag here after dealing with
1489 			 * remaining slots. This way anyone looking with the
1490 			 * TCB lock will see its on the hpts until just
1491 			 * before we unlock.
1492 			 */
1493 			inp->inp_in_hpts = 0;
1494 			mtx_unlock(&hpts->p_mtx);
1495 			INP_WLOCK(inp);
1496 			if (in_pcbrele_wlocked(inp)) {
1497 				mtx_lock(&hpts->p_mtx);
1498 				if (logging_on)
1499 					tcp_hpts_log_it(hpts, hpts->p_inp, HPTSLOG_INP_DONE, 0, 1);
1500 				hpts->p_inp = NULL;
1501 				continue;
1502 			}
1503 			if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
1504 out_now:
1505 #ifdef INVARIANTS
1506 				if (mtx_owned(&hpts->p_mtx)) {
1507 					panic("Hpts:%p owns mtx prior-to lock line:%d",
1508 					    hpts, __LINE__);
1509 				}
1510 #endif
1511 				INP_WUNLOCK(inp);
1512 				mtx_lock(&hpts->p_mtx);
1513 				if (logging_on)
1514 					tcp_hpts_log_it(hpts, hpts->p_inp, HPTSLOG_INP_DONE, 0, 3);
1515 				hpts->p_inp = NULL;
1516 				continue;
1517 			}
1518 			tp = intotcpcb(inp);
1519 			if ((tp == NULL) || (tp->t_inpcb == NULL)) {
1520 				goto out_now;
1521 			}
1522 			if (set_cpu) {
1523 				/*
1524 				 * Setup so the next time we will move to
1525 				 * the right CPU. This should be a rare
1526 				 * event. It will sometimes happens when we
1527 				 * are the client side (usually not the
1528 				 * server). Somehow tcp_output() gets called
1529 				 * before the tcp_do_segment() sets the
1530 				 * intial state. This means the r_cpu and
1531 				 * r_hpts_cpu is 0. We get on the hpts, and
1532 				 * then tcp_input() gets called setting up
1533 				 * the r_cpu to the correct value. The hpts
1534 				 * goes off and sees the mis-match. We
1535 				 * simply correct it here and the CPU will
1536 				 * switch to the new hpts nextime the tcb
1537 				 * gets added to the the hpts (not this one)
1538 				 * :-)
1539 				 */
1540 				tcp_set_hpts(inp);
1541 			}
1542 			if (out_newts_every_tcb) {
1543 				struct timeval sv;
1544 
1545 				if (out_ts_percision)
1546 					microuptime(&sv);
1547 				else
1548 					getmicrouptime(&sv);
1549 				cts = tcp_tv_to_usectick(&sv);
1550 			}
1551 			CURVNET_SET(inp->inp_vnet);
1552 			/*
1553 			 * There is a hole here, we get the refcnt on the
1554 			 * inp so it will still be preserved but to make
1555 			 * sure we can get the INP we need to hold the p_mtx
1556 			 * above while we pull out the tp/inp,  as long as
1557 			 * fini gets the lock first we are assured of having
1558 			 * a sane INP we can lock and test.
1559 			 */
1560 #ifdef INVARIANTS
1561 			if (mtx_owned(&hpts->p_mtx)) {
1562 				panic("Hpts:%p owns mtx before tcp-output:%d",
1563 				    hpts, __LINE__);
1564 			}
1565 #endif
1566 			if (tp->t_fb_ptr != NULL) {
1567 				kern_prefetch(tp->t_fb_ptr, &did_prefetch);
1568 				did_prefetch = 1;
1569 			}
1570 			inp->inp_hpts_calls = 1;
1571 			if (tp->t_fb->tfb_tcp_output_wtime != NULL) {
1572 				error = (*tp->t_fb->tfb_tcp_output_wtime) (tp, &tv);
1573 			} else {
1574 				error = tp->t_fb->tfb_tcp_output(tp);
1575 			}
1576 			if (ninp && ninp->inp_ppcb) {
1577 				/*
1578 				 * If we have a nxt inp, see if we can
1579 				 * prefetch its ppcb. Note this may seem
1580 				 * "risky" since we have no locks (other
1581 				 * than the previous inp) and there no
1582 				 * assurance that ninp was not pulled while
1583 				 * we were processing inp and freed. If this
1584 				 * occured it could mean that either:
1585 				 *
1586 				 * a) Its NULL (which is fine we won't go
1587 				 * here) <or> b) Its valid (which is cool we
1588 				 * will prefetch it) <or> c) The inp got
1589 				 * freed back to the slab which was
1590 				 * reallocated. Then the piece of memory was
1591 				 * re-used and something else (not an
1592 				 * address) is in inp_ppcb. If that occurs
1593 				 * we don't crash, but take a TLB shootdown
1594 				 * performance hit (same as if it was NULL
1595 				 * and we tried to pre-fetch it).
1596 				 *
1597 				 * Considering that the likelyhood of <c> is
1598 				 * quite rare we will take a risk on doing
1599 				 * this. If performance drops after testing
1600 				 * we can always take this out. NB: the
1601 				 * kern_prefetch on amd64 actually has
1602 				 * protection against a bad address now via
1603 				 * the DMAP_() tests. This will prevent the
1604 				 * TLB hit, and instead if <c> occurs just
1605 				 * cause us to load cache with a useless
1606 				 * address (to us).
1607 				 */
1608 				kern_prefetch(ninp->inp_ppcb, &prefetch_tp);
1609 				prefetch_tp = 1;
1610 			}
1611 			INP_WUNLOCK(inp);
1612 			INP_UNLOCK_ASSERT(inp);
1613 			CURVNET_RESTORE();
1614 #ifdef INVARIANTS
1615 			if (mtx_owned(&hpts->p_mtx)) {
1616 				panic("Hpts:%p owns mtx prior-to lock line:%d",
1617 				    hpts, __LINE__);
1618 			}
1619 #endif
1620 			mtx_lock(&hpts->p_mtx);
1621 			if (logging_on)
1622 				tcp_hpts_log_it(hpts, hpts->p_inp, HPTSLOG_INP_DONE, 0, 4);
1623 			hpts->p_inp = NULL;
1624 		}
1625 		HPTS_MTX_ASSERT(hpts);
1626 		hpts->p_inp = NULL;
1627 		hpts->p_cur_slot++;
1628 		if (hpts->p_cur_slot >= NUM_OF_HPTSI_SLOTS) {
1629 			hpts->p_cur_slot = 0;
1630 		}
1631 	}
1632 no_one:
1633 	HPTS_MTX_ASSERT(hpts);
1634 	hpts->p_prevtick = hpts->p_curtick;
1635 	hpts->p_delayed_by = 0;
1636 	/*
1637 	 * Check to see if we took an excess amount of time and need to run
1638 	 * more ticks (if we did not hit eno-bufs).
1639 	 */
1640 	/* Re-run any input that may be there */
1641 	(void)tcp_gethptstick(&tv);
1642 	if (!TAILQ_EMPTY(&hpts->p_input)) {
1643 		tcp_input_data(hpts, &tv);
1644 	}
1645 #ifdef INVARIANTS
1646 	if (TAILQ_EMPTY(&hpts->p_input) &&
1647 	    (hpts->p_on_inqueue_cnt != 0)) {
1648 		panic("tp:%p in_hpts input empty but cnt:%d",
1649 		    hpts, hpts->p_on_inqueue_cnt);
1650 	}
1651 #endif
1652 	tick_now = tcp_gethptstick(&tv);
1653 	if (SEQ_GT(tick_now, hpts->p_prevtick)) {
1654 		struct timeval res;
1655 
1656 		/* Did we really spend a full tick or more in here? */
1657 		timersub(&tv, ctick, &res);
1658 		if (res.tv_sec || (res.tv_usec >= HPTS_TICKS_PER_USEC)) {
1659 			counter_u64_add(hpts_loops, 1);
1660 			if (logging_on) {
1661 				tcp_hpts_log_it(hpts, inp, HPTSLOG_TOLONG, (uint32_t) res.tv_usec, tick_now);
1662 			}
1663 			*ctick = res;
1664 			hpts->p_curtick = tick_now;
1665 			goto again;
1666 		}
1667 	}
1668 no_run:
1669 	{
1670 		uint32_t t = 0, i, fnd = 0;
1671 
1672 		if (hpts->p_on_queue_cnt) {
1673 
1674 
1675 			/*
1676 			 * Find next slot that is occupied and use that to
1677 			 * be the sleep time.
1678 			 */
1679 			for (i = 1, t = hpts->p_nxt_slot; i < NUM_OF_HPTSI_SLOTS; i++) {
1680 				if (TAILQ_EMPTY(&hpts->p_hptss[t]) == 0) {
1681 					fnd = 1;
1682 					break;
1683 				}
1684 				t = (t + 1) % NUM_OF_HPTSI_SLOTS;
1685 			}
1686 			if (fnd) {
1687 				hpts->p_hpts_sleep_time = i;
1688 			} else {
1689 				counter_u64_add(back_tosleep, 1);
1690 #ifdef INVARIANTS
1691 				panic("Hpts:%p cnt:%d but non found", hpts, hpts->p_on_queue_cnt);
1692 #endif
1693 				hpts->p_on_queue_cnt = 0;
1694 				goto non_found;
1695 			}
1696 			t++;
1697 		} else {
1698 			/* No one on the wheel sleep for all but 2 slots  */
1699 non_found:
1700 			if (hpts_sleep_max == 0)
1701 				hpts_sleep_max = 1;
1702 			hpts->p_hpts_sleep_time = min((NUM_OF_HPTSI_SLOTS - 2), hpts_sleep_max);
1703 			t = 0;
1704 		}
1705 		if (logging_on) {
1706 			tcp_hpts_log_it(hpts, inp, HPTSLOG_SLEEPSET, t, (hpts->p_hpts_sleep_time * HPTS_TICKS_PER_USEC));
1707 		}
1708 	}
1709 }
1710 
1711 void
1712 __tcp_set_hpts(struct inpcb *inp, int32_t line)
1713 {
1714 	struct tcp_hpts_entry *hpts;
1715 
1716 	INP_WLOCK_ASSERT(inp);
1717 	hpts = tcp_hpts_lock(inp);
1718 	if ((inp->inp_in_hpts == 0) &&
1719 	    (inp->inp_hpts_cpu_set == 0)) {
1720 		inp->inp_hpts_cpu = hpts_cpuid(inp);
1721 		inp->inp_hpts_cpu_set = 1;
1722 	}
1723 	mtx_unlock(&hpts->p_mtx);
1724 	hpts = tcp_input_lock(inp);
1725 	if ((inp->inp_input_cpu_set == 0) &&
1726 	    (inp->inp_in_input == 0)) {
1727 		inp->inp_input_cpu = hpts_cpuid(inp);
1728 		inp->inp_input_cpu_set = 1;
1729 	}
1730 	mtx_unlock(&hpts->p_mtx);
1731 }
1732 
1733 uint16_t
1734 tcp_hpts_delayedby(struct inpcb *inp){
1735 	return (tcp_pace.rp_ent[inp->inp_hpts_cpu]->p_delayed_by);
1736 }
1737 
1738 static void
1739 tcp_hpts_thread(void *ctx)
1740 {
1741 	struct tcp_hpts_entry *hpts;
1742 	struct timeval tv;
1743 	sbintime_t sb;
1744 
1745 	hpts = (struct tcp_hpts_entry *)ctx;
1746 	mtx_lock(&hpts->p_mtx);
1747 	if (hpts->p_direct_wake) {
1748 		/* Signaled by input */
1749 		if (logging_on)
1750 			tcp_hpts_log_it(hpts, NULL, HPTSLOG_AWAKE, 1, 1);
1751 		callout_stop(&hpts->co);
1752 	} else {
1753 		/* Timed out */
1754 		if (callout_pending(&hpts->co) ||
1755 		    !callout_active(&hpts->co)) {
1756 			if (logging_on)
1757 				tcp_hpts_log_it(hpts, NULL, HPTSLOG_AWAKE, 2, 2);
1758 			mtx_unlock(&hpts->p_mtx);
1759 			return;
1760 		}
1761 		callout_deactivate(&hpts->co);
1762 		if (logging_on)
1763 			tcp_hpts_log_it(hpts, NULL, HPTSLOG_AWAKE, 3, 3);
1764 	}
1765 	hpts->p_hpts_active = 1;
1766 	(void)tcp_gethptstick(&tv);
1767 	tcp_hptsi(hpts, &tv);
1768 	HPTS_MTX_ASSERT(hpts);
1769 	tv.tv_sec = 0;
1770 	tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_USEC;
1771 	if (tcp_min_hptsi_time && (tv.tv_usec < tcp_min_hptsi_time)) {
1772 		tv.tv_usec = tcp_min_hptsi_time;
1773 		hpts->p_on_min_sleep = 1;
1774 	} else {
1775 		/* Clear the min sleep flag */
1776 		hpts->p_on_min_sleep = 0;
1777 	}
1778 	hpts->p_hpts_active = 0;
1779 	sb = tvtosbt(tv);
1780 	if (tcp_hpts_callout_skip_swi == 0) {
1781 		callout_reset_sbt_on(&hpts->co, sb, 0,
1782 		    hpts_timeout_swi, hpts, hpts->p_cpu,
1783 		    (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision)));
1784 	} else {
1785 		callout_reset_sbt_on(&hpts->co, sb, 0,
1786 		    hpts_timeout_dir, hpts,
1787 		    hpts->p_cpu,
1788 		    C_PREL(tcp_hpts_precision));
1789 	}
1790 	hpts->p_direct_wake = 0;
1791 	mtx_unlock(&hpts->p_mtx);
1792 }
1793 
1794 #undef	timersub
1795 
1796 static void
1797 tcp_init_hptsi(void *st)
1798 {
1799 	int32_t i, j, error, bound = 0, created = 0;
1800 	size_t sz, asz;
1801 	struct timeval tv;
1802 	sbintime_t sb;
1803 	struct tcp_hpts_entry *hpts;
1804 	struct pcpu *pc;
1805 	cpuset_t cs;
1806 	char unit[16];
1807 	uint32_t ncpus = mp_ncpus ? mp_ncpus : MAXCPU;
1808 	int count, domain;
1809 
1810 	tcp_pace.rp_proc = NULL;
1811 	tcp_pace.rp_num_hptss = ncpus;
1812 	hpts_loops = counter_u64_alloc(M_WAITOK);
1813 	back_tosleep = counter_u64_alloc(M_WAITOK);
1814 
1815 	sz = (tcp_pace.rp_num_hptss * sizeof(struct tcp_hpts_entry *));
1816 	tcp_pace.rp_ent = malloc(sz, M_TCPHPTS, M_WAITOK | M_ZERO);
1817 	asz = sizeof(struct hptsh) * NUM_OF_HPTSI_SLOTS;
1818 	for (i = 0; i < tcp_pace.rp_num_hptss; i++) {
1819 		tcp_pace.rp_ent[i] = malloc(sizeof(struct tcp_hpts_entry),
1820 		    M_TCPHPTS, M_WAITOK | M_ZERO);
1821 		tcp_pace.rp_ent[i]->p_hptss = malloc(asz,
1822 		    M_TCPHPTS, M_WAITOK);
1823 		hpts = tcp_pace.rp_ent[i];
1824 		/*
1825 		 * Init all the hpts structures that are not specifically
1826 		 * zero'd by the allocations. Also lets attach them to the
1827 		 * appropriate sysctl block as well.
1828 		 */
1829 		mtx_init(&hpts->p_mtx, "tcp_hpts_lck",
1830 		    "hpts", MTX_DEF | MTX_DUPOK);
1831 		TAILQ_INIT(&hpts->p_input);
1832 		for (j = 0; j < NUM_OF_HPTSI_SLOTS; j++) {
1833 			TAILQ_INIT(&hpts->p_hptss[j]);
1834 		}
1835 		sysctl_ctx_init(&hpts->hpts_ctx);
1836 		sprintf(unit, "%d", i);
1837 		hpts->hpts_root = SYSCTL_ADD_NODE(&hpts->hpts_ctx,
1838 		    SYSCTL_STATIC_CHILDREN(_net_inet_tcp_hpts),
1839 		    OID_AUTO,
1840 		    unit,
1841 		    CTLFLAG_RW, 0,
1842 		    "");
1843 		SYSCTL_ADD_INT(&hpts->hpts_ctx,
1844 		    SYSCTL_CHILDREN(hpts->hpts_root),
1845 		    OID_AUTO, "in_qcnt", CTLFLAG_RD,
1846 		    &hpts->p_on_inqueue_cnt, 0,
1847 		    "Count TCB's awaiting input processing");
1848 		SYSCTL_ADD_INT(&hpts->hpts_ctx,
1849 		    SYSCTL_CHILDREN(hpts->hpts_root),
1850 		    OID_AUTO, "out_qcnt", CTLFLAG_RD,
1851 		    &hpts->p_on_queue_cnt, 0,
1852 		    "Count TCB's awaiting output processing");
1853 		SYSCTL_ADD_UINT(&hpts->hpts_ctx,
1854 		    SYSCTL_CHILDREN(hpts->hpts_root),
1855 		    OID_AUTO, "active", CTLFLAG_RD,
1856 		    &hpts->p_hpts_active, 0,
1857 		    "Is the hpts active");
1858 		SYSCTL_ADD_UINT(&hpts->hpts_ctx,
1859 		    SYSCTL_CHILDREN(hpts->hpts_root),
1860 		    OID_AUTO, "curslot", CTLFLAG_RD,
1861 		    &hpts->p_cur_slot, 0,
1862 		    "What the current slot is if active");
1863 		SYSCTL_ADD_UINT(&hpts->hpts_ctx,
1864 		    SYSCTL_CHILDREN(hpts->hpts_root),
1865 		    OID_AUTO, "curtick", CTLFLAG_RD,
1866 		    &hpts->p_curtick, 0,
1867 		    "What the current tick on if active");
1868 		SYSCTL_ADD_UINT(&hpts->hpts_ctx,
1869 		    SYSCTL_CHILDREN(hpts->hpts_root),
1870 		    OID_AUTO, "logsize", CTLFLAG_RD,
1871 		    &hpts->p_logsize, 0,
1872 		    "Hpts logging buffer size");
1873 		hpts->p_hpts_sleep_time = NUM_OF_HPTSI_SLOTS - 2;
1874 		hpts->p_num = i;
1875 		hpts->p_prevtick = hpts->p_curtick = tcp_gethptstick(&tv);
1876 		hpts->p_prevtick -= 1;
1877 		hpts->p_prevtick %= NUM_OF_HPTSI_SLOTS;
1878 		hpts->p_cpu = 0xffff;
1879 		hpts->p_nxt_slot = 1;
1880 		hpts->p_logsize = tcp_hpts_logging_size;
1881 		if (hpts->p_logsize) {
1882 			sz = (sizeof(struct hpts_log) * hpts->p_logsize);
1883 			hpts->p_log = malloc(sz, M_TCPHPTS, M_WAITOK | M_ZERO);
1884 		}
1885 		callout_init(&hpts->co, 1);
1886 	}
1887 
1888 	/* Don't try to bind to NUMA domains if we don't have any */
1889 	if (vm_ndomains == 1 && tcp_bind_threads == 2)
1890 		tcp_bind_threads = 0;
1891 
1892 	/*
1893 	 * Now lets start ithreads to handle the hptss.
1894 	 */
1895 	CPU_FOREACH(i) {
1896 		hpts = tcp_pace.rp_ent[i];
1897 		hpts->p_cpu = i;
1898 		error = swi_add(&hpts->ie, "hpts",
1899 		    tcp_hpts_thread, (void *)hpts,
1900 		    SWI_NET, INTR_MPSAFE, &hpts->ie_cookie);
1901 		if (error) {
1902 			panic("Can't add hpts:%p i:%d err:%d",
1903 			    hpts, i, error);
1904 		}
1905 		created++;
1906 		if (tcp_bind_threads == 1) {
1907 			if (intr_event_bind(hpts->ie, i) == 0)
1908 				bound++;
1909 		} else if (tcp_bind_threads == 2) {
1910 			pc = pcpu_find(i);
1911 			domain = pc->pc_domain;
1912 			CPU_COPY(&cpuset_domain[domain], &cs);
1913 			if (intr_event_bind_ithread_cpuset(hpts->ie, &cs)
1914 			    == 0) {
1915 				bound++;
1916 				count = hpts_domains[domain].count;
1917 				hpts_domains[domain].cpu[count] = i;
1918 				hpts_domains[domain].count++;
1919 			}
1920 		}
1921 		tv.tv_sec = 0;
1922 		tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_USEC;
1923 		sb = tvtosbt(tv);
1924 		if (tcp_hpts_callout_skip_swi == 0) {
1925 			callout_reset_sbt_on(&hpts->co, sb, 0,
1926 			    hpts_timeout_swi, hpts, hpts->p_cpu,
1927 			    (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision)));
1928 		} else {
1929 			callout_reset_sbt_on(&hpts->co, sb, 0,
1930 			    hpts_timeout_dir, hpts,
1931 			    hpts->p_cpu,
1932 			    C_PREL(tcp_hpts_precision));
1933 		}
1934 	}
1935 	/*
1936 	 * If we somehow have an empty domain, fall back to choosing
1937 	 * among all htps threads.
1938 	 */
1939 	for (i = 0; i < vm_ndomains; i++) {
1940 		if (hpts_domains[i].count == 0) {
1941 			tcp_bind_threads = 0;
1942 			break;
1943 		}
1944 	}
1945 
1946 	printf("TCP Hpts created %d swi interrupt threads and bound %d to %s\n",
1947 	    created, bound,
1948 	    tcp_bind_threads == 2 ? "NUMA domains" : "cpus");
1949 }
1950 
1951 SYSINIT(tcphptsi, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, tcp_init_hptsi, NULL);
1952 MODULE_VERSION(tcphpts, 1);
1953