Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_subr.c
Show First 20 Lines • Show All 1,951 Lines • ▼ Show 20 Lines | |||||
* the socket if we hold the only reference. | * the socket if we hold the only reference. | ||||
*/ | */ | ||||
struct tcpcb * | struct tcpcb * | ||||
tcp_close(struct tcpcb *tp) | tcp_close(struct tcpcb *tp) | ||||
{ | { | ||||
struct inpcb *inp = tp->t_inpcb; | struct inpcb *inp = tp->t_inpcb; | ||||
struct socket *so; | struct socket *so; | ||||
INP_INFO_LOCK_ASSERT(&V_tcbinfo); | INP_INFO_LOCK_ASSERT(&V_tcbinfo); | ||||
rwatson: I'm cautious about naming a variable "listen" -- historically, this would have shadowed a… | |||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
#ifdef TCP_OFFLOAD | #ifdef TCP_OFFLOAD | ||||
if (tp->t_state == TCPS_LISTEN) | if (tp->t_state == TCPS_LISTEN) | ||||
tcp_offload_listen_stop(tp); | tcp_offload_listen_stop(tp); | ||||
#endif | #endif | ||||
/* | /* | ||||
* This releases the TFO pending counter resource for TFO listen | * This releases the TFO pending counter resource for TFO listen | ||||
* sockets as well as passively-created TFO sockets that transition | * sockets as well as passively-created TFO sockets that transition | ||||
* from SYN_RECEIVED to CLOSED. | * from SYN_RECEIVED to CLOSED. | ||||
Done Inline ActionsThe line wrapping here is funky. Make it consistently 78 characters wide. rwatson: The line wrapping here is funky. Make it consistently 78 characters wide. | |||||
*/ | */ | ||||
if (tp->t_tfo_pending) { | if (tp->t_tfo_pending) { | ||||
tcp_fastopen_decrement_counter(tp->t_tfo_pending); | tcp_fastopen_decrement_counter(tp->t_tfo_pending); | ||||
tp->t_tfo_pending = NULL; | tp->t_tfo_pending = NULL; | ||||
} | } | ||||
in_pcbdrop(inp); | in_pcbdrop(inp); | ||||
TCPSTAT_INC(tcps_closed); | TCPSTAT_INC(tcps_closed); | ||||
if (tp->t_state != TCPS_CLOSED) | if (tp->t_state != TCPS_CLOSED) | ||||
tcp_state_change(tp, TCPS_CLOSED); | tcp_state_change(tp, TCPS_CLOSED); | ||||
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL")); | KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL")); | ||||
so = inp->inp_socket; | so = inp->inp_socket; | ||||
soisdisconnected(so); | soisdisconnected(so); | ||||
Done Inline ActionsThis vertical whitespace is not required. rwatson: This vertical whitespace is not required. | |||||
Done Inline Actionstcp_subr.c diff looks now unrelated, that is, only whitespace change here pluknet: tcp_subr.c diff looks now unrelated, that is, only whitespace change here | |||||
Not Done Inline ActionsGood catch! Will fix that. johalun0_gmail.com: Good catch! Will fix that. | |||||
if (inp->inp_flags & INP_SOCKREF) { | if (inp->inp_flags & INP_SOCKREF) { | ||||
KASSERT(so->so_state & SS_PROTOREF, | KASSERT(so->so_state & SS_PROTOREF, | ||||
Not Done Inline ActionsHow about this locking? Is it needed for access to the socket and if so, is it safe to lock another inpcb here? johalun0_gmail.com: How about this locking? Is it needed for access to the socket and if so, is it safe to lock… | |||||
Not Done Inline ActionsThe INP lock is needed to check inp_socket and ensure it doesn't change while you are messing with the socket. (Actually, it could probably be a read lock.) Its safe to lock the inpcb first, and then lock that inpcb's socket while you hold the INP lock. If you want to lock two inpcbs, you will need to define a deadlock-free ordering. (See, for example, the way sched_ule.c does this in sched_switch_migrate().) jtl: The INP lock is needed to check inp_socket and ensure it doesn't change while you are messing… | |||||
("tcp_close: !SS_PROTOREF")); | ("tcp_close: !SS_PROTOREF")); | ||||
inp->inp_flags &= ~INP_SOCKREF; | inp->inp_flags &= ~INP_SOCKREF; | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
SOCK_LOCK(so); | SOCK_LOCK(so); | ||||
so->so_state &= ~SS_PROTOREF; | so->so_state &= ~SS_PROTOREF; | ||||
sofree(so); | sofree(so); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,227 Lines • Show Last 20 Lines |
I'm cautious about naming a variable "listen" -- historically, this would have shadowed a global symbol (listen()). I wonder if another name might be a better idea.