Index: sys/socketvar.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/socketvar.h,v
retrieving revision 1.160
diff -u -r1.160 socketvar.h
--- sys/socketvar.h	17 Dec 2007 10:02:01 -0000	1.160
+++ sys/socketvar.h	30 Jan 2008 06:13:43 -0000
@@ -273,6 +273,13 @@
  */
 
 /*
+ * Flags to sblock().
+ */
+#define	SBL_WAIT	0x00000001	/* Wait if not immediately available. */
+#define	SBL_NOINTR	0x00000002	/* Force non-interruptible sleep. */
+#define	SBL_VALID	(SBL_WAIT | SBL_NOINTR)
+
+/*
  * Do we need to notify the other side when I/O is possible?
  */
 #define	sb_notify(sb)	(((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
Index: kern/uipc_sockbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_sockbuf.c,v
retrieving revision 1.174
diff -u -r1.174 uipc_sockbuf.c
--- kern/uipc_sockbuf.c	17 Dec 2007 10:02:01 -0000	1.174
+++ kern/uipc_sockbuf.c	30 Jan 2008 13:21:40 -0000
@@ -137,8 +137,12 @@
 sblock(struct sockbuf *sb, int flags)
 {
 
-	if (flags == M_WAITOK) {
-		if (sb->sb_flags & SB_NOINTR) {
+	KASSERT((flags & SBL_VALID) == flags,
+	    ("sblock: flags invalid (0x%x)", flags));
+
+	if (flags & SBL_WAIT) {
+		if ((sb->sb_flags & SB_NOINTR) ||
+		    (flags & SBL_NOINTR)) {
 			sx_xlock(&sb->sb_sx);
 			return (0);
 		}
Index: kern/uipc_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.303
diff -u -r1.303 uipc_socket.c
--- kern/uipc_socket.c	24 Oct 2007 19:03:55 -0000	1.303
+++ kern/uipc_socket.c	30 Jan 2008 05:40:06 -0000
@@ -916,7 +916,7 @@
 }
 #endif /*ZERO_COPY_SOCKETS*/
 
-#define	SBLOCKWAIT(f)	(((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
+#define	SBLOCKWAIT(f)	(((f) & MSG_DONTWAIT) ? 0 : SBL_WAIT)
 
 int
 sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio,
@@ -1884,10 +1884,16 @@
 	 * however, we have to initialize and destroy the mutex in the copy
 	 * so that dom_dispose() and sbrelease() can lock t as needed.
 	 */
-	(void) sblock(sb, M_WAITOK);
-	SOCKBUF_LOCK(sb);
-	sb->sb_flags |= SB_NOINTR;
-	socantrcvmore_locked(so);
+
+	/*
+	 * Dislodge threads currently blocked in receive and wait to acquire
+	 * a lock against other simultaneous readers before clearing the
+	 * socket buffer.  Don't let our acquire be interrupted by a signal
+	 * despite any existing socket disposition on interruptable waiting.
+	 */
+	socantrcvmore(so);
+	(void) sblock(sb, SBL_WAIT | SBL_NOINTR);
+
 	/*
 	 * Invalidate/clear most of the sockbuf structure, but leave selinfo
 	 * and mutex data unchanged.
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.263
diff -u -r1.263 uipc_syscalls.c
--- kern/uipc_syscalls.c	13 Jan 2008 14:44:09 -0000	1.263
+++ kern/uipc_syscalls.c	30 Jan 2008 05:41:03 -0000
@@ -1863,8 +1863,13 @@
 		}
 	}
 
-	/* Protect against multiple writers to the socket. */
-	(void) sblock(&so->so_snd, M_WAITOK);
+	/*
+	 * Protect against multiple writers to the socket.
+	 *
+	 * XXXRW: Historically this has assumed non-interruptibility, so now
+	 * we implement that, but possibly shouldn't.
+	 */
+	(void)sblock(&so->so_snd, SBL_WAIT | SBL_NOINTR);
 
 	/*
 	 * Loop through the pages of the file, starting with the requested
Index: netinet/sctp_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/sctp_input.c,v
retrieving revision 1.66
diff -u -r1.66 sctp_input.c
--- netinet/sctp_input.c	16 Oct 2007 14:05:51 -0000	1.66
+++ netinet/sctp_input.c	30 Jan 2008 05:41:58 -0000
@@ -2509,7 +2509,8 @@
 			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
 			SCTP_TCB_UNLOCK((*stcb));
 
-			sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb, M_NOWAIT);
+			sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb,
+			    0);
 			SCTP_TCB_LOCK((*stcb));
 			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
 
Index: netinet/sctp_peeloff.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/sctp_peeloff.c,v
retrieving revision 1.16
diff -u -r1.16 sctp_peeloff.c
--- netinet/sctp_peeloff.c	8 Sep 2007 11:35:10 -0000	1.16
+++ netinet/sctp_peeloff.c	30 Jan 2008 05:42:07 -0000
@@ -134,7 +134,7 @@
 	atomic_add_int(&stcb->asoc.refcnt, 1);
 	SCTP_TCB_UNLOCK(stcb);
 
-	sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK);
+	sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT);
 	atomic_subtract_int(&stcb->asoc.refcnt, 1);
 
 	return (0);
@@ -230,7 +230,7 @@
 	 * And now the final hack. We move data in the pending side i.e.
 	 * head to the new socket buffer. Let the GRUBBING begin :-0
 	 */
-	sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK);
+	sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT);
 	atomic_subtract_int(&stcb->asoc.refcnt, 1);
 	return (newso);
 }
Index: netinet/sctputil.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/sctputil.c,v
retrieving revision 1.72
diff -u -r1.72 sctputil.c
--- netinet/sctputil.c	7 Dec 2007 01:32:14 -0000	1.72
+++ netinet/sctputil.c	30 Jan 2008 05:41:42 -0000
@@ -4993,7 +4993,7 @@
 		sctp_misc_ints(SCTP_SORECV_ENTERPL,
 		    rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid);
 	}
-	error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0));
+	error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0));
 	sockbuf_lock = 1;
 	if (error) {
 		goto release_unlocked;
