PERFORCE change 57125 for review

Robert Watson rwatson at FreeBSD.org
Sun Jul 11 16:27:17 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=57125

Change 57125 by rwatson at rwatson_tislabs on 2004/07/11 23:26:54

	Integrate netperf_socket to loop back soreceive() locking changes
	committed to CVS from rwatson_netperf.

Affected files ...

.. //depot/projects/netperf_socket/sys/kern/kern_conf.c#7 integrate
.. //depot/projects/netperf_socket/sys/kern/uipc_socket.c#31 integrate
.. //depot/projects/netperf_socket/sys/sys/conf.h#8 integrate

Differences ...

==== //depot/projects/netperf_socket/sys/kern/kern_conf.c#7 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_conf.c,v 1.153 2004/06/22 20:22:24 le Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_conf.c,v 1.154 2004/07/11 19:26:43 phk Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -44,7 +44,7 @@
 #include <sys/tty.h>
 #include <machine/stdarg.h>
 
-static MALLOC_DEFINE(M_DEVT, "struct cdev *", "struct cdev *storage");
+static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage");
 
 /* Built at compile time from sys/conf/majors */
 extern unsigned char reserved_majors[256];
@@ -77,7 +77,7 @@
 devlock(void)
 {
 	if (!mtx_initialized(&devmtx))
-		mtx_init(&devmtx, "struct cdev *", NULL, MTX_DEF);
+		mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
 	mtx_lock(&devmtx);
 }
 

==== //depot/projects/netperf_socket/sys/kern/uipc_socket.c#31 (text+ko) ====

@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2004 The FreeBSD Foundation
+ * Copyright (c) 2004 Robert Watson
  * Copyright (c) 1982, 1986, 1988, 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -30,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/uipc_socket.c,v 1.199 2004/07/11 18:29:47 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/uipc_socket.c,v 1.201 2004/07/11 23:13:14 rwatson Exp $");
 
 #include "opt_inet.h"
 #include "opt_mac.h"
@@ -895,6 +897,42 @@
 }
 
 /*
+ * Following replacement or removal of the first mbuf on the first mbuf chain
+ * of a socket buffer, push necessary state changes back into the socket
+ * buffer so that other consumers see the values consistently.  'nextrecord'
+ * is the callers locally stored value of the original value of
+ * sb->sb_mb->m_nextpkt which must be restored when the lead mbuf changes.
+ * NOTE: 'nextrecord' may be NULL.
+ */
+static __inline void
+sockbuf_pushsync(struct sockbuf *sb, struct mbuf *nextrecord)
+{
+
+	SOCKBUF_LOCK_ASSERT(sb);
+	/*
+	 * First, update for the new value of nextrecord.  If necessary, make
+	 * it the first record.
+	 */
+	if (sb->sb_mb != NULL)
+		sb->sb_mb->m_nextpkt = nextrecord;
+	else
+		sb->sb_mb = nextrecord;
+
+        /*
+         * Now update any dependent socket buffer fields to reflect the new
+         * state.  This is an expanded inline of SB_EMPTY_FIXUP(), with the
+	 * addition of a second clause that takes care of the case where
+	 * sb_mb has been updated, but remains the last record.
+         */
+        if (sb->sb_mb == NULL) {
+                sb->sb_mbtail = NULL;
+                sb->sb_lastrecord = NULL;
+        } else if (sb->sb_mb->m_nextpkt == NULL)
+                sb->sb_lastrecord = sb->sb_mb;
+}
+
+
+/*
  * Implement receive operations on a socket.
  * We depend on the way that records are added to the sockbuf
  * by sbappend*.  In particular, each record (mbufs linked through m_next)
@@ -1048,8 +1086,7 @@
 			sbfree(&so->so_rcv, m);
 			so->so_rcv.sb_mb = m_free(m);
 			m = so->so_rcv.sb_mb;
-			if (m != NULL)
-				m->m_nextpkt = nextrecord;
+			sockbuf_pushsync(&so->so_rcv, nextrecord);
 		}
 		orig_resid = 0;
 	}
@@ -1067,14 +1104,7 @@
 		do {
 			if (flags & MSG_PEEK) {
 				if (controlp != NULL) {
-					SOCKBUF_UNLOCK(&so->so_rcv);
-					*controlp = m_copym(m, 0, m->m_len,
-						M_TRYWAIT);
-					SOCKBUF_LOCK(&so->so_rcv);
-					if (*controlp == NULL) {
-						error = ENOBUFS;
-						goto release;
-					}
+					*controlp = m_copy(m, 0, m->m_len);
 					controlp = &(*controlp)->m_next;
 				}
 				m = m->m_next;
@@ -1093,34 +1123,29 @@
 				m = so->so_rcv.sb_mb;
 			}
 		} while (m != NULL && m->m_type == MT_CONTROL);
+		if ((flags & MSG_PEEK) == 0)
+			sockbuf_pushsync(&so->so_rcv, nextrecord);
 		if (cm != NULL) {
 			if (pr->pr_domain->dom_externalize != NULL) {
-				/*
-				 * NB: drop the lock to avoid potential LORs;
-				 * in particular unix domain sockets grab the
-				 * file descriptor lock which would be a LOR.
-				 */
 				SOCKBUF_UNLOCK(&so->so_rcv);
 				error = (*pr->pr_domain->dom_externalize)
-						(cm, controlp);
+				    (cm, controlp);
 				SOCKBUF_LOCK(&so->so_rcv);
 			} else
 				m_freem(cm);
 		}
+		nextrecord = so->so_rcv.sb_mb->m_nextpkt;
 		orig_resid = 0;
 	}
 	if (m != NULL) {
 		if ((flags & MSG_PEEK) == 0) {
-			m->m_nextpkt = nextrecord;
-			/*
-			 * If nextrecord == NULL (this is a single chain),
-			 * then sb_lastrecord may not be valid here if m
-			 * was changed earlier.
-			 */
+			KASSERT(m->m_nextpkt == nextrecord,
+			    ("soreceive: post-control, nextrecord !sync"));
 			if (nextrecord == NULL) {
 				KASSERT(so->so_rcv.sb_mb == m,
-					("receive tailq 1"));
-				so->so_rcv.sb_lastrecord = m;
+				    ("soreceive: post-control, sb_mb!=m"));
+				KASSERT(so->so_rcv.sb_lastrecord == m,
+				    ("soreceive: post-control, lastrecord!=m"));
 			}
 		}
 		type = m->m_type;
@@ -1128,9 +1153,12 @@
 			flags |= MSG_OOB;
 	} else {
 		if ((flags & MSG_PEEK) == 0) {
-			KASSERT(so->so_rcv.sb_mb == m,("receive tailq 2"));
-			so->so_rcv.sb_mb = nextrecord;
-			SB_EMPTY_FIXUP(&so->so_rcv);
+			KASSERT(so->so_rcv.sb_mb == nextrecord,
+			    ("soreceive: sb_mb != nextrecord"));
+			if (so->so_rcv.sb_mb == NULL) {
+				KASSERT(so->so_rcv.sb_lastrecord == NULL,
+				    ("soreceive: sb_lastercord != NULL"));
+			}
 		}
 	}
 	SOCKBUF_LOCK_ASSERT(&so->so_rcv);

==== //depot/projects/netperf_socket/sys/sys/conf.h#8 (text+ko) ====

@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)conf.h	8.5 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/sys/conf.h,v 1.189 2004/06/17 17:16:52 phk Exp $
+ * $FreeBSD: src/sys/sys/conf.h,v 1.190 2004/07/11 23:03:37 phk Exp $
  */
 
 #ifndef _SYS_CONF_H_
@@ -111,12 +111,6 @@
 #define si_copyonwrite	__si_u.__si_disk.__sid_copyonwrite
 
 /*
- * Special device management
- */
-#define	SPECHSZ	64
-#define	SPECHASH(rdev)	(((unsigned)(minor(rdev)))%SPECHSZ)
-
-/*
  * Definitions of device driver entry switches
  */
 


More information about the p4-projects mailing list