Folks, I am trying to understand the need to hold the V_tcbinfo lock
in part of this function [code included below for reference].

At present this causes the socket upcall to be called with the
V_tcbinfo lock held, which I'd like to avoid. We release this lock
right after this section.

Looking at the code, it seems the lock is needed if we were in
FIN_WAIT_2 and tcp_close() the connection. The lock also seems to be
protecting V_twq_2msl.

Would it be an acceptable solution if we deferred calling
socantrecvmore() till after the lock can be dropped (after the swtich
statement). tcp_twstart() can be changed to return tp if the
connections survives, or NULL if it doesn't, much like what
tcp_close() does. Also a new lock could be added to protect the
V_rwq_2msl queue.

If this sounds acceptable, I can generate a patch against -CURRENT. I
would appreciate feedback.

-vijay


relevant code from tcp_do_segment():

        if (thflags & TH_FIN) {
                if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
                        socantrcvmore(so);
                        /*
                         * If connection is half-synchronized
                         * (ie NEEDSYN flag on) then delay ACK,
                         * so it may be piggybacked when SYN is sent.
                         * Otherwise, since we received a FIN then no
                         * more input can be expected, send ACK now.
                         */
                        if (tp->t_flags & TF_NEEDSYN)
                                tp->t_flags |= TF_DELACK;
                        else
                                tp->t_flags |= TF_ACKNOW;
                        tp->rcv_nxt++;
                }
                switch (tp->t_state) {

                /*
                 * In SYN_RECEIVED and ESTABLISHED STATES
                 * enter the CLOSE_WAIT state.
                 */
                case TCPS_SYN_RECEIVED:
                        tp->t_starttime = ticks;
                        /* FALLTHROUGH */
                case TCPS_ESTABLISHED:
                        tp->t_state = TCPS_CLOSE_WAIT;
                        break;

                /*
                 * If still in FIN_WAIT_1 STATE FIN has not been acked so
                 * enter the CLOSING state.
                 */
                case TCPS_FIN_WAIT_1:
                        tp->t_state = TCPS_CLOSING;
                        break;

                /*
                 * In FIN_WAIT_2 state enter the TIME_WAIT state,
                 * starting the time-wait timer, turning off the other
                 * standard timers.
                 */
                case TCPS_FIN_WAIT_2:
                        INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
                        KASSERT(ti_locked == TI_WLOCKED, ("%s: dodata "
                            "TCP_FIN_WAIT_2 ti_locked: %d", __func__,
                            ti_locked));

                        tcp_twstart(tp);
                        INP_INFO_WUNLOCK(&V_tcbinfo);
                        return;
                }
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to