Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Feb 2011 09:15:23 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r218258 - stable/8/sys/kern
Message-ID:  <201102040915.p149FNhA075856@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Feb  4 09:15:23 2011
New Revision: 218258
URL: http://svn.freebsd.org/changeset/base/218258

Log:
  MFC r218026:
  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.

Modified:
  stable/8/sys/kern/uipc_syscalls.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/kern/uipc_syscalls.c
==============================================================================
--- stable/8/sys/kern/uipc_syscalls.c	Fri Feb  4 09:15:12 2011	(r218257)
+++ stable/8/sys/kern/uipc_syscalls.c	Fri Feb  4 09:15:23 2011	(r218258)
@@ -2128,11 +2128,17 @@ 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_queues();
 				vm_page_unwire(pg, 0);
@@ -2142,7 +2148,8 @@ retry_space:
 				if (pg->wire_count == 0 && pg->object == NULL)
 					vm_page_free(pg);
 				vm_page_unlock_queues();
-				error = (mnw ? EAGAIN : EINTR);
+				if (m == NULL)
+					error = (mnw ? EAGAIN : EINTR);
 				break;
 			}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102040915.p149FNhA075856>