Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Aug 2011 16:12:29 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r225040 - head/sys/kern
Message-ID:  <201108201612.p7KGCTMa059038@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Aug 20 16:12:29 2011
New Revision: 225040
URL: http://svn.freebsd.org/changeset/base/225040

Log:
  Prevent the hiwatermark for the unix domain socket from becoming
  effectively negative. Often seen as upstream fastcgi connection timeouts
  in nginx when using sendfile over unix domain sockets for communication.
  
  Sendfile(2) may send more bytes then currently allowed by the
  hiwatermark of the socket, e.g. because the so_snd sockbuf lock is
  dropped after sbspace() call in the kern_sendfile() loop. In this case,
  recalculated hiwatermark will overflow. Since lowatermark is renewed
  as half of the hiwatermark by sendfile code, and both are unsigned,
  the send buffer never reaches the free space requested by lowatermark,
  causing indefinite wait in sendfile.
  
  Reviewed by:	rwatson
  Approved by:	re (bz)
  MFC after:	2 weeks

Modified:
  head/sys/kern/uipc_usrreq.c

Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c	Sat Aug 20 15:21:02 2011	(r225039)
+++ head/sys/kern/uipc_usrreq.c	Sat Aug 20 16:12:29 2011	(r225040)
@@ -816,7 +816,7 @@ uipc_send(struct socket *so, int flags, 
 	struct unpcb *unp, *unp2;
 	struct socket *so2;
 	u_int mbcnt_delta, sbcc;
-	u_long newhiwat;
+	u_int newhiwat;
 	int error = 0;
 
 	unp = sotounpcb(so);
@@ -974,7 +974,10 @@ uipc_send(struct socket *so, int flags, 
 		sorwakeup_locked(so2);
 
 		SOCKBUF_LOCK(&so->so_snd);
-		newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
+		if ((int)so->so_snd.sb_hiwat >= (int)(sbcc - unp2->unp_cc))
+			newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
+		else
+			newhiwat = 0;
 		(void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat,
 		    newhiwat, RLIM_INFINITY);
 		so->so_snd.sb_mbmax -= mbcnt_delta;



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