diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 459082b18c9a..ce83a9380eaa 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -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; }