If more than one thread allocated sf buffers for sendfile(2), and

each of the threads needs more while current pool of the buffers is
exhausted, then neither thread can make progress.

Switch to nowait allocations after we got first buffer already.

Reported by:	az
Reviewed by:	alc (previous version)
Tested by:	pho
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2011-01-28 17:37:09 +00:00
parent 3fce3875e5
commit 9ca9fc5380

View File

@ -2126,18 +2126,25 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap,
}
/*
* Get a sendfile buf. We usually wait as long
* as necessary, but this wait can be interrupted.
* Get a sendfile buf. When allocating the
* first buffer for mbuf chain, we usually
* wait as long as necessary, but this wait
* can be interrupted. For consequent
* buffers, do not sleep, since several
* threads might exhaust the buffers and then
* deadlock.
*/
if ((sf = sf_buf_alloc(pg,
(mnw ? SFB_NOWAIT : SFB_CATCH))) == NULL) {
sf = sf_buf_alloc(pg, (mnw || m != NULL) ? SFB_NOWAIT :
SFB_CATCH);
if (sf == NULL) {
mbstat.sf_allocfail++;
vm_page_lock(pg);
vm_page_unwire(pg, 0);
KASSERT(pg->object != NULL,
("kern_sendfile: object disappeared"));
vm_page_unlock(pg);
error = (mnw ? EAGAIN : EINTR);
if (m == NULL)
error = (mnw ? EAGAIN : EINTR);
break;
}