PERFORCE change 46164 for review
Sam Leffler
sam at FreeBSD.org
Thu Jan 29 19:41:07 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=46164
Change 46164 by sam at 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;
More information about the p4-projects
mailing list