Date: Thu, 10 Jun 2004 22:20:37 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 54583 for review Message-ID: <200406102220.i5AMKb1W014493@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=54583 Change 54583 by rwatson@rwatson_paprika on 2004/06/10 22:19:38 Reinject netperf_socket socket locking following slightly too enthusiastic resolve -at of UNIX domain socket locking from CVS. Affected files ... .. //depot/projects/netperf_socket/sys/kern/uipc_usrreq.c#10 edit Differences ... ==== //depot/projects/netperf_socket/sys/kern/uipc_usrreq.c#10 (text+ko) ==== @@ -114,6 +114,7 @@ UNP_LOCK(); unp_drop(unp, ECONNABORTED); unp_detach(unp); /* NB: unlocks */ + SOCK_LOCK(so); sotryfree(so); return (0); } @@ -269,6 +270,12 @@ if (unp == NULL) return (EINVAL); + /* + * Reorder locks to avoid LORs. Note that we + * delay re-locking so_rcv to below so it can + * be done only once. + */ + SOCKBUF_UNLOCK(&so>so_rcv); UNP_LOCK(); switch (so->so_type) { case SOCK_DGRAM: @@ -276,9 +283,14 @@ /*NOTREACHED*/ case SOCK_STREAM: - if (unp->unp_conn == NULL) + if (unp->unp_conn == NULL) { + SOCKBUF_LOCK(&so->so_rcv); break; + } so2 = unp->unp_conn->unp_socket; + /* NB: careful of order here */ + SOCKBUF_LOCK(&so2->so_snd); + SOCKBUF_LOCK(&so->so_rcv); /* * Adjust backpressure on sender * and wakeup any waiting to write. @@ -290,7 +302,8 @@ (void)chgsbsize(so2->so_cred->cr_uidinfo, &so2->so_snd.sb_hiwat, newhiwat, RLIM_INFINITY); unp->unp_cc = so->so_rcv.sb_cc; - sowwakeup(so2); + sowwakeup_locked(so2); + SOCKBUF_UNLOCK(&so2->so_snd); break; default: @@ -323,7 +336,13 @@ if (control != NULL && (error = unp_internalize(&control, td))) goto release; + /* + * Reorder locks to avoid LORs. + */ + SOCKBUF_UNLOCK(&so->so_snd); UNP_LOCK(); + SOCKBUF_LOCK(&so->so_snd); + switch (so->so_type) { case SOCK_DGRAM: { @@ -334,7 +353,9 @@ error = EISCONN; break; } + SOCKBUF_UNLOCK(&so->so_snd); error = unp_connect(so, nam, td); + SOCKBUF_LOCK(&so->so_snd); if (error) break; } else { @@ -348,13 +369,15 @@ from = (struct sockaddr *)unp->unp_addr; else from = &sun_noname; - if (sbappendaddr(&so2->so_rcv, from, m, control)) { - sorwakeup(so2); + SOCKBUF_LOCK(&so2->so_rcv); + if (sbappendaddr_locked(&so2->so_rcv, from, m, control)) { + sorwakeup_locked(so2); m = NULL; control = NULL; } else { error = ENOBUFS; } + SOCKBUF_UNLOCK(&so2->so_rcv); if (nam != NULL) unp_disconnect(unp); break; @@ -368,7 +391,9 @@ */ if ((so->so_state & SS_ISCONNECTED) == 0) { if (nam != NULL) { + SOCKBUF_UNLOCK(&so->so_snd); error = unp_connect(so, nam, td); + SOCKBUF_LOCK(&so->so_snd); if (error) break; /* XXX */ } else { @@ -384,16 +409,17 @@ if (unp->unp_conn == NULL) panic("uipc_send connected but no connection?"); so2 = unp->unp_conn->unp_socket; + SOCKBUF_LOCK(&so2->so_rcv); /* * Send to paired receive port, and then reduce * send buffer hiwater marks to maintain backpressure. * Wake up readers. */ if (control != NULL) { - if (sbappendcontrol(&so2->so_rcv, m, control)) + if (sbappendcontrol_locked(&so2->so_rcv, m, control)) control = NULL; } else { - sbappend(&so2->so_rcv, m); + sbappend_locked(&so2->so_rcv, m); } so->so_snd.sb_mbmax -= so2->so_rcv.sb_mbcnt - unp->unp_conn->unp_mbcnt; @@ -403,7 +429,8 @@ (void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat, newhiwat, RLIM_INFINITY); unp->unp_conn->unp_cc = so2->so_rcv.sb_cc; - sorwakeup(so2); + sorwakeup_locked(so2); + SOCKBUF_UNLOCK(&so2->so_rcv); m = NULL; break; @@ -416,7 +443,7 @@ * a SHUTDOWN. */ if (flags & PRUS_EOF) { - socantsendmore(so); + socantsendmore_locked(so); unp_shutdown(unp); } UNP_UNLOCK(); @@ -462,6 +489,7 @@ if (unp == NULL) return (EINVAL); UNP_LOCK(); + /* XXX socket lock? */ socantsendmore(so); unp_shutdown(unp); UNP_UNLOCK();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406102220.i5AMKb1W014493>