async_rcvd: Don't add/drop socket reference on hot path
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 19 Mar 2013 08:51:49 +0000 (16:51 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 19 Mar 2013 08:51:49 +0000 (16:51 +0800)
Instead, add reference in tcp_attach(), and drop the reference in
tcp_close()

sys/kern/uipc_msg.c
sys/kern/uipc_socket2.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_usrreq.c

index 1507f89..d1b496d 100644 (file)
@@ -324,7 +324,6 @@ so_pru_rcvd_async(struct socket *so)
        spin_lock(&so->so_rcvd_spin);
        if ((so->so_rcvd_msg.nm_pru_flags & PRUR_DEAD) == 0) {
                if (lmsg->ms_flags & MSGF_DONE) {
-                       soreference(so);
                        lwkt_sendmsg_stage1(so->so_port, lmsg);
                        spin_unlock(&so->so_rcvd_spin);
                        lwkt_sendmsg_stage2(so->so_port, lmsg);
@@ -612,7 +611,6 @@ so_async_rcvd_reply(struct socket *so)
        spin_lock(&so->so_rcvd_spin);
        lwkt_replymsg(&so->so_rcvd_msg.base.lmsg, 0);
        spin_unlock(&so->so_rcvd_spin);
-       sofree(so);
 }
 
 void
@@ -626,8 +624,7 @@ so_async_rcvd_drop(struct socket *so)
        spin_lock(&so->so_rcvd_spin);
        so->so_rcvd_msg.nm_pru_flags |= PRUR_DEAD;
 again:
-       if (lwkt_dropmsg(lmsg) == 0)
-               sofree(so);
+       lwkt_dropmsg(lmsg);
        if ((lmsg->ms_flags & MSGF_DONE) == 0) {
                ++async_rcvd_drop_race;
                ssleep(so, &so->so_rcvd_spin, 0, "soadrop", 1);
index 8b27070..7982538 100644 (file)
@@ -380,7 +380,10 @@ sonewconn_faddr(struct socket *head, int connstatus,
                sofree(so);             /* remove implied pcb ref */
                return (NULL);
        }
-       KKASSERT(so->so_refs == 2);     /* attach + our base ref */
+       KKASSERT(((so->so_proto->pr_flags & PR_ASYNC_RCVD) == 0 &&
+           so->so_refs == 2) ||        /* attach + our base ref */
+          ((so->so_proto->pr_flags & PR_ASYNC_RCVD) &&
+           so->so_refs == 3));         /* + async rcvd ref */
        sofree(so);
        KKASSERT(so->so_port != NULL);
        so->so_rcv.ssb_lowat = head->so_rcv.ssb_lowat;
index a846322..6d0cac3 100644 (file)
@@ -1002,6 +1002,8 @@ no_valid_rt:
                syncache_destroy(tp);
 
        so_async_rcvd_drop(so);
+       /* Drop the reference for the asynchronized pru_rcvd */
+       sofree(so);
 
        /*
         * NOTE:
index 69396e0..6fe2263 100644 (file)
@@ -1573,6 +1573,8 @@ tcp_attach(struct socket *so, struct pru_attach_info *ai)
                return (ENOBUFS);
        }
        tp->t_state = TCPS_CLOSED;
+       /* Keep a reference for asynchronized pru_rcvd */
+       soreference(so);
        return (0);
 }