Date: Thu, 29 Jan 2004 19:41:03 -0800 (PST) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 46164 for review Message-ID: <200401300341.i0U3f32d099120@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=46164 Change 46164 by sam@sam_ebb on 2004/01/29 19:40:04 add (very suboptimal) locking of do_sendfile Affected files ... .. //depot/projects/netperf+sockets/sys/kern/uipc_syscalls.c#9 edit Differences ... ==== //depot/projects/netperf+sockets/sys/kern/uipc_syscalls.c#9 (text+ko) ==== @@ -1683,7 +1683,7 @@ struct writev_args nuap; struct sf_hdtr hdtr; off_t off, xfsize, hdtr_size, sbytes = 0; - int error, s; + int error; mtx_lock(&Giant); @@ -1692,7 +1692,8 @@ /* * The descriptor must be a regular file and have a backing VM object. */ - if ((error = fgetvp_read(td, uap->fd, &vp)) != 0) + error = fgetvp_read(td, uap->fd, &vp); + if (error != 0) goto done; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); if (vp->v_type != VREG || VOP_GETVOBJECT(vp, &obj) != 0) { @@ -1750,6 +1751,7 @@ /* * Protect against multiple writers to the socket. */ + SOCKBUF_LOCK(&so->so_snd); (void) sblock(&so->so_snd, M_WAITOK); /* @@ -1763,6 +1765,11 @@ vm_offset_t pgoff; pindex = OFF_TO_IDX(off); + /* + * XXX too many places where we can block + * XXX to make it worth holding the lock + */ + SOCKBUF_UNLOCK(&so->so_snd); VM_OBJECT_LOCK(obj); retry_lookup: /* @@ -1778,8 +1785,10 @@ xfsize = PAGE_SIZE - pgoff; if (uap->nbytes && xfsize > (uap->nbytes - sbytes)) xfsize = uap->nbytes - sbytes; - if (xfsize <= 0) - break; + if (xfsize <= 0) { + SOCKBUF_LOCK(&so->so_snd); + goto unlock; + } /* * Optimize the non-blocking case by looking at the socket space * before going to the extra work of constituting the sf_buf. @@ -1789,8 +1798,8 @@ error = EPIPE; else error = EAGAIN; - sbunlock(&so->so_snd); - goto done; + SOCKBUF_LOCK(&so->so_snd); + goto unlock; } VM_OBJECT_LOCK(obj); /* @@ -1873,8 +1882,8 @@ } vm_page_unlock_queues(); VM_OBJECT_UNLOCK(obj); - sbunlock(&so->so_snd); - goto done; + SOCKBUF_LOCK(&so->so_snd); + goto unlock; } mbstat.sf_iocnt++; } else { @@ -1893,9 +1902,8 @@ if (pg->wire_count == 0 && pg->object == NULL) vm_page_free(pg); vm_page_unlock_queues(); - sbunlock(&so->so_snd); error = EINTR; - goto done; + goto unlock; } /* @@ -1905,8 +1913,8 @@ if (m == NULL) { error = ENOBUFS; sf_buf_free((void *)sf_buf_kva(sf), sf); - sbunlock(&so->so_snd); - goto done; + SOCKBUF_LOCK(&so->so_snd); /* XXX */ + goto unlock; } /* * Setup external storage for mbuf. @@ -1918,7 +1926,7 @@ /* * Add the buffer to the socket buffer chain. */ - s = splnet(); + SOCKBUF_LOCK(&so->so_snd); retry_space: /* * Make sure that the socket is still able to take more data. @@ -1939,9 +1947,7 @@ so->so_error = 0; } m_freem(m); - sbunlock(&so->so_snd); - splx(s); - goto done; + goto unlock; } /* * Wait for socket space to become available. We do this just @@ -1951,10 +1957,8 @@ if (sbspace(&so->so_snd) < so->so_snd.sb_lowat) { if (so->so_state & SS_NBIO) { m_freem(m); - sbunlock(&so->so_snd); - splx(s); error = EAGAIN; - goto done; + goto unlock; } error = sbwait(&so->so_snd); /* @@ -1964,25 +1968,22 @@ */ if (error) { m_freem(m); - sbunlock(&so->so_snd); - splx(s); - goto done; + goto unlock; } goto retry_space; } error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, 0, 0, td); - splx(s); - if (error) { - sbunlock(&so->so_snd); - goto done; - } + if (error) + goto unlock; } +unlock: sbunlock(&so->so_snd); + SOCKBUF_UNLOCK(&so->so_snd); /* * Send trailers. Wimp out and use writev(2). */ - if (uap->hdtr != NULL && hdtr.trailers != NULL) { + if (uap->hdtr != NULL && hdtr.trailers != NULL && error == 0) { nuap.fd = uap->s; nuap.iovp = hdtr.trailers; nuap.iovcnt = hdtr.trl_cnt;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200401300341.i0U3f32d099120>