tcp: avoid call to soisconnected() on transition to ESTABLISHED
This call existed since pre-FreeBSD times, and it is hard to understand why it was there in the first place. After6f3caa6d81
it definitely became necessary always and commit message fromf1ee30ccd6
confirms that. Now that6f3caa6d81
is effectively backed out by07285bb4c2
, the call appears to be useful only for sockets that landed on the incomplete queue, e.g. sockets that have accept_filter(9) enabled on them. Provide a new TCP flag to mark connections that are known to be on the incomplete queue, and call soisconnected() only for those connections. Reviewed by: rrs, tuexen Differential revision: https://reviews.freebsd.org/D36488
This commit is contained in:
parent
72291cee07
commit
e80062a2d4
@ -800,7 +800,7 @@ sonewconn(struct socket *head, int connstatus)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
solisten_enqueue(so, connstatus);
|
||||
(void)solisten_enqueue(so, connstatus);
|
||||
|
||||
return (so);
|
||||
}
|
||||
@ -808,8 +808,10 @@ sonewconn(struct socket *head, int connstatus)
|
||||
/*
|
||||
* Enqueue socket cloned by solisten_clone() to the listen queue of the
|
||||
* listener it has been cloned from.
|
||||
*
|
||||
* Return 'true' if socket landed on complete queue, otherwise 'false'.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
solisten_enqueue(struct socket *so, int connstatus)
|
||||
{
|
||||
struct socket *head = so->so_listen;
|
||||
@ -827,6 +829,7 @@ solisten_enqueue(struct socket *so, int connstatus)
|
||||
so->so_qstate = SQ_COMP;
|
||||
head->sol_qlen++;
|
||||
solisten_wakeup(head); /* unlocks */
|
||||
return (true);
|
||||
} else {
|
||||
/*
|
||||
* Keep removing sockets from the head until there's room for
|
||||
@ -853,6 +856,7 @@ solisten_enqueue(struct socket *so, int connstatus)
|
||||
so->so_qstate = SQ_INCOMP;
|
||||
head->sol_incqlen++;
|
||||
SOLISTEN_UNLOCK(head);
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2433,7 +2433,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
case TCPS_SYN_RECEIVED:
|
||||
|
||||
TCPSTAT_INC(tcps_connects);
|
||||
soisconnected(so);
|
||||
if (tp->t_flags & TF_INCQUEUE) {
|
||||
tp->t_flags &= ~TF_INCQUEUE;
|
||||
soisconnected(so);
|
||||
}
|
||||
/* Do window scaling? */
|
||||
if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
|
||||
(TF_RCVD_SCALE|TF_REQ_SCALE)) {
|
||||
|
@ -1039,7 +1039,8 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
|
||||
TCPSTAT_INC(tcps_accepts);
|
||||
TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, TCPS_LISTEN);
|
||||
|
||||
solisten_enqueue(so, SS_ISCONNECTED);
|
||||
if (!solisten_enqueue(so, SS_ISCONNECTED))
|
||||
tp->t_flags |= TF_INCQUEUE;
|
||||
|
||||
return (so);
|
||||
|
||||
|
@ -2978,8 +2978,8 @@ db_print_tflags(u_int t_flags)
|
||||
db_printf("%sTF_MORETOCOME", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (t_flags & TF_LQ_OVERFLOW) {
|
||||
db_printf("%sTF_LQ_OVERFLOW", comma ? ", " : "");
|
||||
if (t_flags & TF_INCQUEUE) {
|
||||
db_printf("%sTF_INCQUEUE", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (t_flags & TF_LASTIDLE) {
|
||||
|
@ -515,7 +515,7 @@ tcp_unlock_or_drop(struct tcpcb *tp, int tcp_output_retval)
|
||||
#define TF_WAKESOR 0x00004000 /* wake up receive socket */
|
||||
#define TF_GPUTINPROG 0x00008000 /* Goodput measurement in progress */
|
||||
#define TF_MORETOCOME 0x00010000 /* More data to be appended to sock */
|
||||
#define TF_LQ_OVERFLOW 0x00020000 /* listen queue overflow */
|
||||
#define TF_INCQUEUE 0x00020000 /* on incomplete queue of listener */
|
||||
#define TF_LASTIDLE 0x00040000 /* connection was previously idle */
|
||||
#define TF_RXWIN0SENT 0x00080000 /* sent a receiver win 0 in response */
|
||||
#define TF_FASTRECOVERY 0x00100000 /* in NewReno Fast Recovery */
|
||||
|
@ -474,7 +474,7 @@ int solisten(struct socket *so, int backlog, struct thread *td);
|
||||
void solisten_proto(struct socket *so, int backlog);
|
||||
void solisten_proto_abort(struct socket *so);
|
||||
int solisten_proto_check(struct socket *so);
|
||||
void solisten_enqueue(struct socket *, int);
|
||||
bool solisten_enqueue(struct socket *, int);
|
||||
int solisten_dequeue(struct socket *, struct socket **, int);
|
||||
struct socket *
|
||||
solisten_clone(struct socket *);
|
||||
|
Loading…
Reference in New Issue
Block a user