svn commit: r218026 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Fri Jan 28 17:37:09 UTC 2011


Author: kib
Date: Fri Jan 28 17:37:09 2011
New Revision: 218026
URL: http://svn.freebsd.org/changeset/base/218026

Log:
  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

Modified:
  head/sys/kern/uipc_syscalls.c

Modified: head/sys/kern/uipc_syscalls.c
==============================================================================
--- head/sys/kern/uipc_syscalls.c	Fri Jan 28 17:30:24 2011	(r218025)
+++ head/sys/kern/uipc_syscalls.c	Fri Jan 28 17:37:09 2011	(r218026)
@@ -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;
 			}
 


More information about the svn-src-head mailing list