summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_syscalls.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 459082b..ce83a93 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2126,18 +2126,25 @@ retry_space:
}
/*
- * 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;
}
OpenPOWER on IntegriCloud