--- //depot/vendor/freebsd/src/sys/kern/kern_descrip.c 2004/06/11 11:20:57 +++ //depot/user/rwatson/netperf_merge/sys/kern/kern_descrip.c 2004/06/12 19:29:02 @@ -2024,7 +2024,9 @@ *spp = fp->f_data; if (fflagp) *fflagp = fp->f_flag; + SOCK_LOCK(*spp); soref(*spp); + SOCK_UNLOCK(*spp); } FILEDESC_UNLOCK(td->td_proc->p_fd); return (error); @@ -2039,6 +2041,7 @@ { NET_ASSERT_GIANT(); + SOCK_LOCK(so); sorele(so); } --- //depot/vendor/freebsd/src/sys/kern/uipc_socket.c 2004/06/12 16:11:33 +++ //depot/user/rwatson/netperf_merge/sys/kern/uipc_socket.c 2004/06/12 19:29:02 @@ -201,9 +201,12 @@ #ifdef MAC mac_create_socket(cred, so); #endif + SOCK_LOCK(so); soref(so); + SOCK_UNLOCK(so); error = (*prp->pr_usrreqs->pru_attach)(so, proto, td); if (error) { + SOCK_LOCK(so); so->so_state |= SS_NOFDREF; sorele(so); return (error); @@ -292,10 +295,14 @@ int s; KASSERT(so->so_count == 0, ("socket %p so_count not 0", so)); + SOCK_LOCK_ASSERT(so); - if (so->so_pcb != NULL || (so->so_state & SS_NOFDREF) == 0) + if (so->so_pcb != NULL || (so->so_state & SS_NOFDREF) == 0) { + SOCK_UNLOCK(so); return; + } + SOCK_UNLOCK(so); ACCEPT_LOCK(); head = so->so_head; if (head != NULL) { @@ -409,6 +416,7 @@ error = error2; } discard: + SOCK_LOCK(so); if (so->so_state & SS_NOFDREF) panic("soclose: NOFDREF"); so->so_state |= SS_NOFDREF; @@ -428,6 +436,7 @@ error = (*so->so_proto->pr_usrreqs->pru_abort)(so); if (error) { + SOCK_LOCK(so); sotryfree(so); /* note: does not decrement the ref count */ return error; } --- //depot/vendor/freebsd/src/sys/kern/uipc_syscalls.c 2004/06/11 11:20:57 +++ //depot/user/rwatson/netperf_merge/sys/kern/uipc_syscalls.c 2004/06/12 19:29:02 @@ -309,7 +309,14 @@ KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP")); KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP")); + /* + * Before changing the flags on the socket, we have to bump the + * reference count. Otherwise, if the protocol calls sofree(), + * the socket will be released due to a zero refcount. + */ + SOCK_LOCK(so); soref(so); /* file descriptor reference */ + SOCK_UNLOCK(so); TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; --- //depot/vendor/freebsd/src/sys/kern/uipc_usrreq.c 2004/06/10 21:35:45 +++ //depot/user/rwatson/netperf_merge/sys/kern/uipc_usrreq.c 2004/06/12 19:29:02 @@ -114,6 +114,7 @@ UNP_LOCK(); unp_drop(unp, ECONNABORTED); unp_detach(unp); /* NB: unlocks */ + SOCK_LOCK(so); sotryfree(so); return (0); } --- //depot/vendor/freebsd/src/sys/net/raw_cb.c 2004/06/11 03:55:35 +++ //depot/user/rwatson/netperf_merge/sys/net/raw_cb.c 2004/06/12 20:30:39 @@ -32,7 +32,9 @@ #include #include +#include #include +#include #include #include #include @@ -93,6 +95,7 @@ { struct socket *so = rp->rcb_socket; + SOCK_LOCK(so); so->so_pcb = 0; sotryfree(so); LIST_REMOVE(rp, list); --- //depot/vendor/freebsd/src/sys/net/raw_usrreq.c 2004/04/07 20:52:05 +++ //depot/user/rwatson/netperf_merge/sys/net/raw_usrreq.c 2004/06/12 20:30:39 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -139,8 +140,9 @@ if (rp == 0) return EINVAL; raw_disconnect(rp); + soisdisconnected(so); + SOCK_LOCK(so); sotryfree(so); - soisdisconnected(so); /* XXX huh? called after the sofree()? */ return 0; } --- //depot/vendor/freebsd/src/sys/netatalk/ddp_pcb.c 2004/03/22 04:56:26 +++ //depot/user/rwatson/netperf_merge/sys/netatalk/ddp_pcb.c 2004/06/12 19:29:02 @@ -253,6 +253,7 @@ at_pcbdetach(struct socket *so, struct ddpcb *ddp) { soisdisconnected(so); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/netatm/atm_socket.c 2003/10/31 18:36:05 +++ //depot/user/rwatson/netperf_merge/sys/netatm/atm_socket.c 2004/06/12 19:29:02 @@ -173,6 +173,7 @@ /* * Break links and free control blocks */ + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 2004/05/29 00:56:26 +++ //depot/user/rwatson/netperf_merge/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 2004/06/12 19:29:02 @@ -1417,6 +1417,7 @@ bzero(pcb, sizeof(*pcb)); FREE(pcb, M_NETGRAPH_BTSOCKET_HCI_RAW); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c 2004/05/29 00:56:26 +++ //depot/user/rwatson/netperf_merge/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c 2004/06/12 19:29:02 @@ -1804,6 +1804,7 @@ FREE(pcb, M_NETGRAPH_BTSOCKET_L2CAP); soisdisconnected(so); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); @@ -2346,6 +2347,7 @@ FREE(pcb, M_NETGRAPH_BTSOCKET_L2CAP); soisdisconnected(so); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 2004/05/29 00:56:26 +++ //depot/user/rwatson/netperf_merge/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 2004/06/12 19:29:02 @@ -1129,6 +1129,7 @@ bzero(pcb, sizeof(*pcb)); FREE(pcb, M_NETGRAPH_BTSOCKET_L2CAP_RAW); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c 2004/06/02 04:20:47 +++ //depot/user/rwatson/netperf_merge/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c 2004/06/12 19:29:02 @@ -724,6 +724,7 @@ FREE(pcb, M_NETGRAPH_BTSOCKET_RFCOMM); soisdisconnected(so); + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); @@ -1370,8 +1371,10 @@ s0->l2so->so_qlen --; l2so->so_qstate &= ~SQ_COMP; l2so->so_head = NULL; + SOCK_LOCK(l2so); soref(l2so); l2so->so_state |= SS_NBIO; + SOCK_UNLOCK(l2so); ACCEPT_UNLOCK(); error = soaccept(l2so, (struct sockaddr **) &l2sa); --- //depot/vendor/freebsd/src/sys/netgraph/ng_ksocket.c 2004/06/02 04:20:47 +++ //depot/user/rwatson/netperf_merge/sys/netgraph/ng_ksocket.c 2004/06/12 19:29:02 @@ -1205,8 +1205,10 @@ head->so_qlen--; so->so_qstate &= ~SQ_COMP; so->so_head = NULL; + SOCK_LOCK(so); soref(so); so->so_state |= SS_NBIO; + SOCK_UNLOCK(so); ACCEPT_UNLOCK(); /* XXX KNOTE(&head->so_rcv.sb_sel.si_note, 0); */ --- //depot/vendor/freebsd/src/sys/netinet/in_pcb.c 2004/05/20 06:35:28 +++ //depot/user/rwatson/netperf_merge/sys/netinet/in_pcb.c 2004/06/12 19:29:02 @@ -690,6 +690,7 @@ inp->inp_gencnt = ++ipi->ipi_gencnt; in_pcbremlists(inp); if (so) { + SOCK_LOCK(so); so->so_pcb = 0; sotryfree(so); } --- //depot/vendor/freebsd/src/sys/netinet/tcp_subr.c 2004/05/04 02:15:32 +++ //depot/user/rwatson/netperf_merge/sys/netinet/tcp_subr.c 2004/06/12 19:29:02 @@ -1657,13 +1657,14 @@ } tcp_discardcb(tp); so = inp->inp_socket; + SOCK_LOCK(so); so->so_pcb = NULL; tw->tw_cred = crhold(so->so_cred); tw->tw_so_options = so->so_options; + sotryfree(so); + inp->inp_socket = NULL; if (acknow) tcp_twrespond(tw, TH_ACK); - sotryfree(so); - inp->inp_socket = NULL; inp->inp_ppcb = (caddr_t)tw; inp->inp_vflag |= INP_TIMEWAIT; tcp_timer_2msl_reset(tw, tw_time); --- //depot/vendor/freebsd/src/sys/netinet6/in6_pcb.c 2004/04/07 20:52:05 +++ //depot/user/rwatson/netperf_merge/sys/netinet6/in6_pcb.c 2004/06/12 19:29:02 @@ -438,6 +438,7 @@ in_pcbremlists(inp); if (so) { + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); } --- //depot/vendor/freebsd/src/sys/netipx/ipx_pcb.c 2004/03/01 03:15:33 +++ //depot/user/rwatson/netperf_merge/sys/netipx/ipx_pcb.c 2004/06/12 19:29:02 @@ -268,6 +268,7 @@ { struct socket *so = ipxp->ipxp_socket; + SOCK_LOCK(so); so->so_pcb = 0; sotryfree(so); if (ipxp->ipxp_route.ro_rt != NULL) --- //depot/vendor/freebsd/src/sys/netipx/ipx_usrreq.c 2003/11/18 00:40:43 +++ //depot/user/rwatson/netperf_merge/sys/netipx/ipx_usrreq.c 2004/06/12 19:29:02 @@ -423,8 +423,9 @@ s = splnet(); ipx_pcbdetach(ipxp); splx(s); + soisdisconnected(so); + SOCK_LOCK(so); sotryfree(so); - soisdisconnected(so); return (0); } --- //depot/vendor/freebsd/src/sys/netnatm/natm.c 2004/03/01 03:15:33 +++ //depot/user/rwatson/netperf_merge/sys/netnatm/natm.c 2004/06/12 19:29:02 @@ -135,6 +135,7 @@ * we turn on 'drain' *before* we sofree. */ npcb_free(npcb, NPCB_DESTROY); /* drain */ + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); out: @@ -463,6 +464,7 @@ */ npcb_free(npcb, NPCB_DESTROY); /* drain */ + SOCK_LOCK(so); so->so_pcb = NULL; sotryfree(so); --- //depot/vendor/freebsd/src/sys/sys/socketvar.h 2004/06/12 18:38:10 +++ //depot/user/rwatson/netperf_merge/sys/sys/socketvar.h 2004/06/12 19:29:02 @@ -57,7 +57,7 @@ * (g) used only as a sleep/wakeup address, no value. */ struct socket { - int so_count; /* reference count */ + int so_count; /* (b) reference count */ short so_type; /* (a) generic type, see socket.h */ short so_options; /* from socket call, see socket.h */ short so_linger; /* time to linger while closing */ @@ -316,19 +316,26 @@ * the structure. */ #define soref(so) do { \ + SOCK_LOCK_ASSERT(so); \ ++(so)->so_count; \ } while (0) #define sorele(so) do { \ + SOCK_LOCK_ASSERT(so); \ if ((so)->so_count <= 0) \ panic("sorele"); \ if (--(so)->so_count == 0) \ sofree(so); \ + else \ + SOCK_UNLOCK(so); \ } while (0) #define sotryfree(so) do { \ + SOCK_LOCK_ASSERT(so); \ if ((so)->so_count == 0) \ sofree(so); \ + else \ + SOCK_UNLOCK(so); \ } while(0) #define sorwakeup(so) do { \