Index: tcp_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.186 diff -u -p -r1.186 tcp_input.c --- tcp_input.c 30 Dec 2002 19:31:04 -0000 1.186 +++ tcp_input.c 6 Jan 2003 08:43:25 -0000 @@ -134,7 +134,7 @@ static void tcp_dooptions(struct tcpopt static void tcp_pulloutofband(struct socket *, struct tcphdr *, struct mbuf *, int); static int tcp_reass(struct tcpcb *, struct tcphdr *, int *, - struct mbuf *); + struct mbuf *, int *); static void tcp_xmit_timer(struct tcpcb *, int); static void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *); @@ -163,11 +163,12 @@ do { \ (tp->t_flags & TF_RXWIN0SENT) == 0) static int -tcp_reass(tp, th, tlenp, m) +tcp_reass(tp, th, tlenp, m, pneedrwakeup) register struct tcpcb *tp; register struct tcphdr *th; int *tlenp; struct mbuf *m; + int *pneedrwakeup; { struct tseg_qent *q; struct tseg_qent *p = NULL; @@ -288,7 +289,7 @@ present: q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); ND6_HINT(tp); - sorwakeup(so); + *pneedrwakeup = 1; return (flags); } @@ -350,6 +351,8 @@ tcp_input(m, off0) int headlocked = 0; struct sockaddr_in *next_hop = NULL; int rstreason; /* For badport_bandlim accounting purposes */ + int needwwakeup = 0; + int needrwakeup = 0; struct ip6_hdr *ip6 = NULL; #ifdef INET6 @@ -1042,10 +1045,10 @@ after_listen: tp->t_rxtcur, tcp_timer_rexmt, tp); - sowwakeup(so); if (so->so_snd.sb_cc) (void) tcp_output(tp); INP_UNLOCK(inp); + sowwakeup(so); return; } } else if (th->th_ack == tp->snd_una && @@ -1083,7 +1086,6 @@ after_listen: m_adj(m, drop_hdrlen); /* delayed header drop */ sbappend(&so->so_rcv, m); } - sorwakeup(so); if (DELAY_ACK(tp)) { callout_reset(tp->tt_delack, tcp_delacktime, tcp_timer_delack, tp); @@ -1092,6 +1094,7 @@ after_listen: tcp_output(tp); } INP_UNLOCK(inp); + sorwakeup(so); return; } } @@ -1664,7 +1667,7 @@ trimthenstep6: */ if (tlen == 0 && (thflags & TH_FIN) == 0) (void) tcp_reass(tp, (struct tcphdr *)0, 0, - (struct mbuf *)0); + (struct mbuf *)0, &needrwakeup); tp->snd_wl1 = th->th_seq - 1; /* FALLTHROUGH */ @@ -1911,7 +1914,7 @@ process_ACK: tp->snd_wnd -= acked; ourfinisacked = 0; } - sowwakeup(so); + needwwakeup = 1; tp->snd_una = th->th_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; @@ -2114,9 +2117,9 @@ dodata: /* XXX */ m_freem(m); else sbappend(&so->so_rcv, m); - sorwakeup(so); + needrwakeup = 1; } else { - thflags = tcp_reass(tp, th, &tlen, m); + thflags = tcp_reass(tp, th, &tlen, m, &needrwakeup); tp->t_flags |= TF_ACKNOW; } @@ -2217,6 +2220,10 @@ dodata: /* XXX */ if (needoutput || (tp->t_flags & TF_ACKNOW)) (void) tcp_output(tp); INP_UNLOCK(inp); + if (needrwakeup) + sorwakeup(so); + if (needwwakeup) + sowwakeup(so); return; dropafterack: @@ -2252,6 +2259,10 @@ dropafterack: tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); INP_UNLOCK(inp); + if (needrwakeup) + sorwakeup(so); + if (needwwakeup) + sowwakeup(so); return; dropwithreset: @@ -2303,6 +2314,10 @@ dropwithreset: } if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); + if (needrwakeup) + sorwakeup(so); + if (needwwakeup) + sowwakeup(so); return; drop: @@ -2319,6 +2334,10 @@ drop: m_freem(m); if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); + if (needrwakeup) + sorwakeup(so); + if (needwwakeup) + sowwakeup(so); return; }