Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_hpts.c
Show First 20 Lines • Show All 1,209 Lines • ▼ Show 20 Lines | while ((inp = TAILQ_FIRST(&hpts->p_input)) != NULL) { | ||||
if (inp->inp_input_cpu_set == 0) { | if (inp->inp_input_cpu_set == 0) { | ||||
set_cpu = 1; | set_cpu = 1; | ||||
} else { | } else { | ||||
set_cpu = 0; | set_cpu = 0; | ||||
} | } | ||||
hpts->p_inp = inp; | hpts->p_inp = inp; | ||||
drop_reason = inp->inp_hpts_drop_reas; | drop_reason = inp->inp_hpts_drop_reas; | ||||
inp->inp_in_input = 0; | inp->inp_in_input = 0; | ||||
tp = intotcpcb(inp); | |||||
mtx_unlock(&hpts->p_mtx); | mtx_unlock(&hpts->p_mtx); | ||||
CURVNET_SET(tp->t_vnet); | |||||
if (drop_reason) { | if (drop_reason) { | ||||
INP_INFO_RLOCK(&V_tcbinfo); | INP_INFO_RLOCK(&V_tcbinfo); | ||||
ti_locked = TI_RLOCKED; | ti_locked = TI_RLOCKED; | ||||
} else { | } else { | ||||
ti_locked = TI_UNLOCKED; | ti_locked = TI_UNLOCKED; | ||||
} | } | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if ((inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) || | if ((inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) || | ||||
(inp->inp_flags2 & INP_FREED)) { | (inp->inp_flags2 & INP_FREED)) { | ||||
out: | out: | ||||
hpts->p_inp = NULL; | hpts->p_inp = NULL; | ||||
if (ti_locked == TI_RLOCKED) { | if (ti_locked == TI_RLOCKED) { | ||||
INP_INFO_RUNLOCK(&V_tcbinfo); | INP_INFO_RUNLOCK(&V_tcbinfo); | ||||
} | } | ||||
if (in_pcbrele_wlocked(inp) == 0) { | if (in_pcbrele_wlocked(inp) == 0) { | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
} | } | ||||
ti_locked = TI_UNLOCKED; | ti_locked = TI_UNLOCKED; | ||||
CURVNET_RESTORE(); | |||||
mtx_lock(&hpts->p_mtx); | mtx_lock(&hpts->p_mtx); | ||||
continue; | continue; | ||||
} | } | ||||
tp = intotcpcb(inp); | |||||
if ((tp == NULL) || (tp->t_inpcb == NULL)) { | if ((tp == NULL) || (tp->t_inpcb == NULL)) { | ||||
goto out; | goto out; | ||||
} | } | ||||
if (drop_reason) { | if (drop_reason) { | ||||
/* This tcb is being destroyed for drop_reason */ | /* This tcb is being destroyed for drop_reason */ | ||||
m = tp->t_in_pkt; | m = tp->t_in_pkt; | ||||
if (m) | if (m) | ||||
n = m->m_nextpkt; | n = m->m_nextpkt; | ||||
else | else | ||||
n = NULL; | n = NULL; | ||||
tp->t_in_pkt = NULL; | tp->t_in_pkt = NULL; | ||||
while (m) { | while (m) { | ||||
m_freem(m); | m_freem(m); | ||||
m = n; | m = n; | ||||
if (m) | if (m) | ||||
n = m->m_nextpkt; | n = m->m_nextpkt; | ||||
} | } | ||||
tp = tcp_drop(tp, drop_reason); | tp = tcp_drop(tp, drop_reason); | ||||
INP_INFO_RUNLOCK(&V_tcbinfo); | INP_INFO_RUNLOCK(&V_tcbinfo); | ||||
if (tp == NULL) { | if (tp == NULL) { | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
} | } | ||||
if (in_pcbrele_wlocked(inp) == 0) | if (in_pcbrele_wlocked(inp) == 0) | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
CURVNET_RESTORE(); | |||||
mtx_lock(&hpts->p_mtx); | mtx_lock(&hpts->p_mtx); | ||||
continue; | continue; | ||||
} | } | ||||
if (set_cpu) { | if (set_cpu) { | ||||
/* | /* | ||||
* Setup so the next time we will move to the right | * Setup so the next time we will move to the right | ||||
* CPU. This should be a rare event. It will | * CPU. This should be a rare event. It will | ||||
* sometimes happens when we are the client side | * sometimes happens when we are the client side | ||||
* (usually not the server). Somehow tcp_output() | * (usually not the server). Somehow tcp_output() | ||||
* gets called before the tcp_do_segment() sets the | * gets called before the tcp_do_segment() sets the | ||||
* intial state. This means the r_cpu and r_hpts_cpu | * intial state. This means the r_cpu and r_hpts_cpu | ||||
* is 0. We get on the hpts, and then tcp_input() | * is 0. We get on the hpts, and then tcp_input() | ||||
* gets called setting up the r_cpu to the correct | * gets called setting up the r_cpu to the correct | ||||
* value. The hpts goes off and sees the mis-match. | * value. The hpts goes off and sees the mis-match. | ||||
* We simply correct it here and the CPU will switch | * We simply correct it here and the CPU will switch | ||||
* to the new hpts nextime the tcb gets added to the | * to the new hpts nextime the tcb gets added to the | ||||
* the hpts (not this time) :-) | * the hpts (not this time) :-) | ||||
*/ | */ | ||||
tcp_set_hpts(inp); | tcp_set_hpts(inp); | ||||
} | } | ||||
CURVNET_SET(tp->t_vnet); | |||||
m = tp->t_in_pkt; | m = tp->t_in_pkt; | ||||
n = NULL; | n = NULL; | ||||
if (m != NULL && | if (m != NULL && | ||||
(m->m_pkthdr.pace_lock == TI_RLOCKED || | (m->m_pkthdr.pace_lock == TI_RLOCKED || | ||||
tp->t_state != TCPS_ESTABLISHED)) { | tp->t_state != TCPS_ESTABLISHED)) { | ||||
ti_locked = TI_RLOCKED; | ti_locked = TI_RLOCKED; | ||||
if (tcp_hptsi_lock_inpinfo(inp, &tp)) { | if (tcp_hptsi_lock_inpinfo(inp, &tp)) { | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | if ((m != NULL) && (m == tp->t_in_pkt)) { | ||||
(inp->inp_flags2 & INP_FREED)) { | (inp->inp_flags2 & INP_FREED)) { | ||||
out_free: | out_free: | ||||
while (m) { | while (m) { | ||||
m_freem(m); | m_freem(m); | ||||
m = n; | m = n; | ||||
if (m) | if (m) | ||||
n = m->m_nextpkt; | n = m->m_nextpkt; | ||||
} | } | ||||
CURVNET_RESTORE(); | |||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* Now that we hold the INP lock, check if | * Now that we hold the INP lock, check if | ||||
* we need to upgrade our lock. | * we need to upgrade our lock. | ||||
*/ | */ | ||||
if (ti_locked == TI_UNLOCKED && | if (ti_locked == TI_UNLOCKED && | ||||
(tp->t_state != TCPS_ESTABLISHED)) { | (tp->t_state != TCPS_ESTABLISHED)) { | ||||
▲ Show 20 Lines • Show All 586 Lines • Show Last 20 Lines |