Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jun 2004 04:07:30 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 55437 for review
Message-ID:  <200406210407.i5L47UaS073664@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55437

Change 55437 by marcel@marcel_nfs on 2004/06/21 04:06:55

	IFC @55425

Affected files ...

.. //depot/projects/gdb/bin/ps/extern.h#3 integrate
.. //depot/projects/gdb/bin/ps/keyword.c#4 integrate
.. //depot/projects/gdb/bin/ps/print.c#4 integrate
.. //depot/projects/gdb/bin/ps/ps.c#12 integrate
.. //depot/projects/gdb/bin/ps/ps.h#3 integrate
.. //depot/projects/gdb/contrib/gdb/gdb/abug-rom.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/ada-tasks.c#5 integrate
.. //depot/projects/gdb/contrib/gdb/gdb/alpha-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/arm-tdep.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/coff-solib.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/coff-solib.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/nm-gnu.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/nm-lynx.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/nm-nbsd.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/nm-sysv4.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/tm-lynx.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/tm-sunos.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/tm-sysv4.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/xm-nbsd.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/config/xm-sysv4.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/cpu32bug-rom.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/gnu-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/gnu-nat.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/i386-stub.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/i386gnu-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/i386ly-tdep.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/i386v-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/i386v4-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/lynx-nat.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/minimon.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/monitor.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/monitor.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/ppcbug-rom.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/procfs.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-e7000.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-est.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-hms.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-mips.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-rdp.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-sds.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-sim.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-st.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-vx.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-vx68.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-vxmips.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/remote-vxsparc.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/ser-e7kpc.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/ser-go32.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/somread.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/somsolib.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/somsolib.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/srec.h#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/standalone.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/stop-gdb.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/tui/tui.c#5 branch
.. //depot/projects/gdb/contrib/gdb/gdb/tui/tui.h#5 branch
.. //depot/projects/gdb/contrib/gdb/gdb/xcoffread.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/xcoffsolib.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/xmodem.c#4 branch
.. //depot/projects/gdb/contrib/gdb/gdb/xmodem.h#4 branch
.. //depot/projects/gdb/contrib/gdb/include/COPYING#3 branch
.. //depot/projects/gdb/contrib/gdb/include/ansidecl.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/bfdlink.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/bout.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/demangle.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/dis-asm.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/floatformat.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/fopen-bin.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/fopen-same.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/gdbm.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/getopt.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/hp-symtab.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/ieee.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/libiberty.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/oasys.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/obstack.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/os9k.h#3 branch
.. //depot/projects/gdb/contrib/gdb/include/progress.h#3 branch
.. //depot/projects/gdb/contrib/gdb/move-if-change#3 branch
.. //depot/projects/gdb/gnu/usr.bin/binutils/libbfd/Makefile.sparc64#4 integrate
.. //depot/projects/gdb/gnu/usr.bin/binutils/libbfd/sparc64/elf64-sparc.c-bad-rtld.diff#2 delete
.. //depot/projects/gdb/sys/conf/ldscript.ia64#2 integrate
.. //depot/projects/gdb/sys/kern/kern_proc.c#12 integrate
.. //depot/projects/gdb/sys/kern/uipc_socket.c#14 integrate
.. //depot/projects/gdb/sys/kern/uipc_socket2.c#12 integrate
.. //depot/projects/gdb/sys/kern/uipc_usrreq.c#10 integrate
.. //depot/projects/gdb/sys/netgraph/ng_fec.c#5 integrate
.. //depot/projects/gdb/sys/netinet/tcp_subr.c#9 integrate
.. //depot/projects/gdb/sys/netipx/spx_usrreq.c#4 integrate
.. //depot/projects/gdb/sys/netkey/keysock.c#2 integrate
.. //depot/projects/gdb/sys/sys/mutex.h#4 integrate
.. //depot/projects/gdb/sys/sys/socketvar.h#7 integrate
.. //depot/projects/gdb/sys/sys/user.h#7 integrate
.. //depot/projects/gdb/usr.sbin/zic/private.h#2 integrate
.. //depot/projects/gdb/usr.sbin/zic/zdump.8#2 integrate
.. //depot/projects/gdb/usr.sbin/zic/zdump.c#2 integrate
.. //depot/projects/gdb/usr.sbin/zic/zic.8#2 integrate
.. //depot/projects/gdb/usr.sbin/zic/zic.c#2 integrate

Differences ...

==== //depot/projects/gdb/bin/ps/extern.h#3 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)extern.h	8.3 (Berkeley) 4/2/94
- * $FreeBSD: src/bin/ps/extern.h,v 1.32 2004/04/06 20:06:49 markm Exp $
+ * $FreeBSD: src/bin/ps/extern.h,v 1.33 2004/06/20 23:40:54 gad Exp $
  */
 
 struct kinfo;
@@ -48,6 +48,7 @@
 void	 cputime(KINFO *, VARENT *);
 int	 donlist(void);
 void	 elapsed(KINFO *, VARENT *);
+void	 emulname(KINFO *, VARENT *);
 VARENT	*find_varentry(VAR *);
 const	 char *fmt_argv(char **, char *, size_t);
 double	 getpcpu(const KINFO *);

==== //depot/projects/gdb/bin/ps/keyword.c#4 (text+ko) ====

@@ -33,7 +33,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/ps/keyword.c,v 1.66 2004/04/06 20:06:49 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/ps/keyword.c,v 1.68 2004/06/20 23:40:54 gad Exp $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -57,6 +57,11 @@
 #define	KOFF(x)	offsetof(struct kinfo_proc, x)
 #define	ROFF(x)	offsetof(struct rusage, x)
 
+#define	EMULLEN	13		/* enough for "FreeBSD ELF32" */
+#define	LWPFMT	"d"
+#define	LWPLEN	6
+#define	NLWPFMT	"d"
+#define	NLWPLEN	4
 #define	UIDFMT	"u"
 #define	UIDLEN	5
 #define	PIDFMT	"d"
@@ -81,6 +86,8 @@
 	{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d",
 		0},
 	{"cputime", "", "time", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
+	{"emul", "EMUL", NULL, LJUST, emulname, NULL, EMULLEN, 0, CHAR,
+		NULL, 0},
 	{"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, 0},
 	{"f", "F", NULL, 0, kvar, NULL, 7, KOFF(ki_flag), INT, "x", 0},
 	{"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
@@ -102,6 +109,8 @@
 	{"logname", "", "login", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
 	{"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28, 0, CHAR,
 		NULL, 0},
+	{"lwp", "LWP", NULL, 0, kvar, NULL, LWPLEN, KOFF(ki_tid), UINT,
+		LWPFMT, 0},
 	{"majflt", "MAJFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_majflt),
 		LONG, "ld", 0},
 	{"minflt", "MINFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_minflt),
@@ -116,6 +125,8 @@
 		0},
 	{"nivcsw", "NIVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw),
 		LONG, "ld", 0},
+	{"nlwp", "NLWP", NULL, 0, kvar, NULL, NLWPLEN, KOFF(ki_numthreads),
+		UINT, NLWPFMT, 0},
 	{"nsignals", "", "nsigs", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
 	{"nsigs", "NSIGS", NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals),
 		LONG, "ld", 0},

==== //depot/projects/gdb/bin/ps/print.c#4 (text+ko) ====

@@ -34,7 +34,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/ps/print.c,v 1.85 2004/04/06 20:06:49 markm Exp $");
+__FBSDID("$FreeBSD: src/bin/ps/print.c,v 1.87 2004/06/20 23:40:54 gad Exp $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -750,6 +750,15 @@
 }
 
 void
+emulname(KINFO *k, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	printf("%-*s", v->width, *k->ki_p->ki_emul ? k->ki_p->ki_emul : "-");
+}
+
+void
 label(KINFO *k, VARENT *ve)
 {
 	char *string;
@@ -774,7 +783,7 @@
 		(void)printf("%-*s", v->width, string);
 		free(string);
 	} else
-		(void)printf("%-*s", v->width, "");
+		(void)printf("%-*s", v->width, "  -");
 	return;
 }
 

==== //depot/projects/gdb/bin/ps/ps.c#12 (text+ko) ====

@@ -47,7 +47,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/ps/ps.c,v 1.98 2004/06/01 23:27:11 gad Exp $");
+__FBSDID("$FreeBSD: src/bin/ps/ps.c,v 1.99 2004/06/20 21:25:10 gad Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -166,6 +166,7 @@
 	struct listinfo gidlist, pgrplist, pidlist;
 	struct listinfo ruidlist, sesslist, ttylist, uidlist;
 	struct kinfo_proc *kp;
+	KINFO *next_KINFO;
 	struct varent *vent;
 	struct winsize ws;
 	const char *nlistf, *memf;
@@ -569,10 +570,15 @@
 			continue;
 
 		keepit:
-			kinfo[nkept].ki_p = kp;
+			next_KINFO = &kinfo[nkept];
+			next_KINFO->ki_p = kp;
+			next_KINFO->ki_pcpu = getpcpu(next_KINFO);
+			if (sortby == SORTMEM)
+				next_KINFO->ki_memsize = kp->ki_tsize +
+				    kp->ki_dsize + kp->ki_ssize;
 			if (needuser)
-				saveuser(&kinfo[nkept]);
-			dynsizevars(&kinfo[nkept]);
+				saveuser(next_KINFO);
+			dynsizevars(next_KINFO);
 			nkept++;
 		}
 	}
@@ -989,53 +995,40 @@
 	}
 }
 
+/* A macro used to improve the readability of pscomp(). */
+#define	DIFF_RETURN(a, b, field) do {	\
+	if ((a)->field != (b)->field)	\
+		return (((a)->field < (b)->field) ? -1 : 1); 	\
+} while (0)
+
 static int
 pscomp(const void *a, const void *b)
 {
 	const KINFO *ka, *kb;
-	double cpua, cpub;
-	segsz_t sizea, sizeb;
 
 	ka = a;
 	kb = b;
 	/* SORTCPU and SORTMEM are sorted in descending order. */
-	if (sortby == SORTCPU) {
-		cpua = getpcpu(ka);
-		cpub = getpcpu(kb);
-		if (cpua < cpub)
-			return (1);
-		if (cpua > cpub)
-			return (-1);
-	}
-	if (sortby == SORTMEM) {
-		sizea = ka->ki_p->ki_tsize + ka->ki_p->ki_dsize +
-		    ka->ki_p->ki_ssize;
-		sizeb = kb->ki_p->ki_tsize + kb->ki_p->ki_dsize +
-		    kb->ki_p->ki_ssize;
-		if (sizea < sizeb)
-			return (1);
-		if (sizea > sizeb)
-			return (-1);
-	}
+	if (sortby == SORTCPU)
+		DIFF_RETURN(kb, ka, ki_pcpu);
+	if (sortby == SORTMEM)
+		DIFF_RETURN(kb, ka, ki_memsize);
 	/*
 	 * TTY's are sorted in ascending order, except that all NODEV
 	 * processes come before all processes with a device.
 	 */
-	if (ka->ki_p->ki_tdev == NODEV && kb->ki_p->ki_tdev != NODEV)
-		return (-1);
-	if (ka->ki_p->ki_tdev != NODEV && kb->ki_p->ki_tdev == NODEV)
-		return (1);
-	if (ka->ki_p->ki_tdev < kb->ki_p->ki_tdev)
-		return (-1);
-	if (ka->ki_p->ki_tdev > kb->ki_p->ki_tdev)
-		return (1);
-	/* PID's are sorted in ascending order. */
-	if (ka->ki_p->ki_pid < kb->ki_p->ki_pid)
-		return (-1);
-	if (ka->ki_p->ki_pid > kb->ki_p->ki_pid)
-		return (1);
+	if (ka->ki_p->ki_tdev != kb->ki_p->ki_tdev) {
+		if (ka->ki_p->ki_tdev == NODEV)
+			return (-1);
+		if (kb->ki_p->ki_tdev == NODEV)
+			return (1);
+		DIFF_RETURN(ka, kb, ki_p->ki_tdev);
+	}
+
+	DIFF_RETURN(ka, kb, ki_p->ki_pid);
 	return (0);
 }
+#undef DIFF_RETURN
 
 /*
  * ICK (all for getopt), would rather hide the ugliness

==== //depot/projects/gdb/bin/ps/ps.h#3 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)ps.h	8.1 (Berkeley) 5/31/93
- * $FreeBSD: src/bin/ps/ps.h,v 1.17 2004/04/06 20:06:49 markm Exp $
+ * $FreeBSD: src/bin/ps/ps.h,v 1.18 2004/06/20 21:25:10 gad Exp $
  */
 
 #define	UNLIMITED	0	/* unlimited terminal width */
@@ -38,6 +38,8 @@
 	char *ki_args;		/* exec args */
 	char *ki_env;		/* environment */
 	int ki_valid;		/* 1 => uarea stuff valid */
+	double	 ki_pcpu;	/* calculated in main() */
+	segsz_t	 ki_memsize;	/* calculated in main() */
 } KINFO;
 
 /* Variables. */

==== //depot/projects/gdb/contrib/gdb/gdb/ada-tasks.c#5 (text+ko) ====


==== //depot/projects/gdb/gnu/usr.bin/binutils/libbfd/Makefile.sparc64#4 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/gnu/usr.bin/binutils/libbfd/Makefile.sparc64,v 1.9 2004/06/19 20:37:38 marcel Exp $
+# $FreeBSD: src/gnu/usr.bin/binutils/libbfd/Makefile.sparc64,v 1.10 2004/06/20 09:46:13 obrien Exp $
 
 DEFAULT_VECTOR=	bfd_elf64_sparc_vec
 
@@ -7,7 +7,7 @@
 	elf32-sparc.c	\
 	elf32-target.h	\
 	elf32.c		\
-	elf64-sparc%FIXED.c	\
+	elf64-sparc.c	\
 	elf64-target.h	\
 	elf64.c		\
 	elflink.c	\
@@ -20,8 +20,3 @@
 .endif
 
 CLEANFILES+=	elf32-target.h elf64-target.h
-
-CLEANFILES+=	elf64-sparc%FIXED.c
-elf64-sparc%FIXED.c: elf64-sparc.c elf64-sparc.c-bad-rtld.diff
-	cp ${.ALLSRC:M*.c} ${.TARGET}
-	patch -b .orig < ${.ALLSRC:M*.diff}

==== //depot/projects/gdb/sys/conf/ldscript.ia64#2 (text+ko) ====

@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/conf/ldscript.ia64,v 1.10 2003/09/06 05:15:36 marcel Exp $ */
+/* $FreeBSD: src/sys/conf/ldscript.ia64,v 1.11 2004/06/20 22:32:19 marcel Exp $ */
 OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little")
 OUTPUT_ARCH(ia64)
 ENTRY(__start)
@@ -74,6 +74,8 @@
     *(.dtors)
     *(SORT(.dtors.*))
   }
+  . = ALIGN(16);
+  __gp = . + 0x200000;
   .got            : { *(.got.plt) *(.got) }
   .IA_64.pltoff   : { *(.IA_64.pltoff) }
   /* We want the small data sections together, so single-instruction offsets

==== //depot/projects/gdb/sys/kern/kern_proc.c#12 (text+ko) ====

@@ -27,11 +27,11 @@
  * SUCH DAMAGE.
  *
  *	@(#)kern_proc.c	8.7 (Berkeley) 2/14/95
- * $FreeBSD: src/sys/kern/kern_proc.c,v 1.210 2004/06/20 02:03:33 gad Exp $
+ * $FreeBSD: src/sys/kern/kern_proc.c,v 1.211 2004/06/20 22:17:22 gad Exp $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_proc.c,v 1.210 2004/06/20 02:03:33 gad Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_proc.c,v 1.211 2004/06/20 22:17:22 gad Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_kstack_pages.h"
@@ -763,6 +763,8 @@
 		kp->ki_lastcpu = td->td_lastcpu;
 		kp->ki_oncpu = td->td_oncpu;
 		kp->ki_tdflags = td->td_flags;
+		kp->ki_tid = td->td_tid;
+		kp->ki_numthreads = p->p_numthreads;
 		kp->ki_pcb = td->td_pcb;
 		kp->ki_kstack = (void *)td->td_kstack;
 		kp->ki_pctcpu = sched_pctcpu(td);

==== //depot/projects/gdb/sys/kern/uipc_socket.c#14 (text+ko) ====

@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/uipc_socket.c,v 1.185 2004/06/20 17:50:42 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/uipc_socket.c,v 1.186 2004/06/21 00:20:42 rwatson Exp $");
 
 #include "opt_inet.h"
 #include "opt_mac.h"
@@ -348,9 +348,15 @@
 	SOCKBUF_LOCK(&so->so_snd);
 	so->so_snd.sb_flags |= SB_NOINTR;
 	(void)sblock(&so->so_snd, M_WAITOK);
-	socantsendmore(so);
+	/*
+	 * socantsendmore_locked() drops the socket buffer mutex so that it
+	 * can safely perform wakeups.  Re-acquire the mutex before
+	 * continuing.
+	 */
+	socantsendmore_locked(so);
+	SOCKBUF_LOCK(&so->so_snd);
 	sbunlock(&so->so_snd);
-	sbrelease(&so->so_snd, so);
+	sbrelease_locked(&so->so_snd, so);
 	SOCKBUF_UNLOCK(&so->so_snd);
 	sorflush(so);
 	sodealloc(so);
@@ -1202,7 +1208,7 @@
 		flags |= MSG_TRUNC;
 		if ((flags & MSG_PEEK) == 0) {
 			SOCKBUF_LOCK_ASSERT(&so->so_rcv);
-			(void) sbdroprecord(&so->so_rcv);
+			(void) sbdroprecord_locked(&so->so_rcv);
 		}
 	}
 	if ((flags & MSG_PEEK) == 0) {
@@ -1271,23 +1277,41 @@
 	struct protosw *pr = so->so_proto;
 	struct sockbuf asb;
 
+	/*
+	 * XXXRW: This is quite ugly.  The existing code made a copy of the
+	 * socket buffer, then zero'd the original to clear the buffer
+	 * fields.  However, with mutexes in the socket buffer, this causes
+	 * problems.  We only clear the zeroable bits of the original;
+	 * however, we have to initialize and destroy the mutex in the copy
+	 * so that dom_dispose() and sbrelease() can lock t as needed.
+	 */
 	SOCKBUF_LOCK(sb);
 	sb->sb_flags |= SB_NOINTR;
 	(void) sblock(sb, M_WAITOK);
-	socantrcvmore(so);
+	/*
+	 * socantrcvmore_locked() drops the socket buffer mutex so that it
+	 * can safely perform wakeups.  Re-acquire the mutex before
+	 * continuing.
+	 */
+	socantrcvmore_locked(so);
+	SOCKBUF_LOCK(sb);
 	sbunlock(sb);
-	asb = *sb;
 	/*
-	 * Invalidate/clear most of the sockbuf structure, but keep
-	 * its selinfo structure valid.
+	 * Invalidate/clear most of the sockbuf structure, but leave
+	 * selinfo and mutex data unchanged.
 	 */
+	bzero(&asb, offsetof(struct sockbuf, sb_startzero));
+	bcopy(&sb->sb_startzero, &asb.sb_startzero,
+	    sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
 	bzero(&sb->sb_startzero,
 	    sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
 	SOCKBUF_UNLOCK(sb);
 
+	SOCKBUF_LOCK_INIT(&asb, "so_rcv");
 	if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL)
 		(*pr->pr_domain->dom_dispose)(asb.sb_mb);
 	sbrelease(&asb, so);
+	SOCKBUF_LOCK_DESTROY(&asb);
 }
 
 #ifdef INET

==== //depot/projects/gdb/sys/kern/uipc_socket2.c#12 (text+ko) ====

@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/uipc_socket2.c,v 1.133 2004/06/19 03:23:14 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/uipc_socket2.c,v 1.134 2004/06/21 00:20:42 rwatson Exp $");
 
 #include "opt_mac.h"
 #include "opt_param.h"
@@ -197,9 +197,9 @@
 	SOCKBUF_UNLOCK(&so->so_rcv);
 	SOCKBUF_LOCK(&so->so_snd);
 	so->so_snd.sb_state |= SBS_CANTSENDMORE;
+	sbdrop_locked(&so->so_snd, so->so_snd.sb_cc);
 	SOCKBUF_UNLOCK(&so->so_snd);
 	wakeup(&so->so_timeo);
-	sbdrop(&so->so_snd, so->so_snd.sb_cc);
 	sowwakeup(so);
 	sorwakeup(so);
 }
@@ -296,14 +296,38 @@
  * protocol when it detects that the peer will send no more data.
  * Data queued for reading in the socket may yet be read.
  */
+void
+socantsendmore_locked(so)
+	struct socket *so;
+{
 
+	SOCKBUF_LOCK_ASSERT(&so->so_snd);
+
+	so->so_snd.sb_state |= SBS_CANTSENDMORE;
+	sowwakeup_locked(so);
+	mtx_assert(SOCKBUF_MTX(&so->so_snd), MA_NOTOWNED);
+}
+
 void
 socantsendmore(so)
 	struct socket *so;
 {
 
-	so->so_snd.sb_state |= SBS_CANTSENDMORE;
-	sowwakeup(so);
+	SOCKBUF_LOCK(&so->so_snd);
+	socantsendmore_locked(so);
+	mtx_assert(SOCKBUF_MTX(&so->so_snd), MA_NOTOWNED);
+}
+
+void
+socantrcvmore_locked(so)
+	struct socket *so;
+{
+
+	SOCKBUF_LOCK_ASSERT(&so->so_rcv);
+
+	so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+	sorwakeup_locked(so);
+	mtx_assert(SOCKBUF_MTX(&so->so_rcv), MA_NOTOWNED);
 }
 
 void
@@ -311,8 +335,9 @@
 	struct socket *so;
 {
 
-	so->so_rcv.sb_state |= SBS_CANTRCVMORE;
-	sorwakeup(so);
+	SOCKBUF_LOCK(&so->so_rcv);
+	socantrcvmore_locked(so);
+	mtx_assert(SOCKBUF_MTX(&so->so_rcv), MA_NOTOWNED);
 }
 
 /*
@@ -356,9 +381,16 @@
 }
 
 /*
- * Wakeup processes waiting on a socket buffer.
- * Do asynchronous notification via SIGIO
- * if the socket has the SS_ASYNC flag set.
+ * Wakeup processes waiting on a socket buffer.  Do asynchronous
+ * notification via SIGIO if the socket has the SS_ASYNC flag set.
+ *
+ * Called with the socket buffer lock held; will release the lock by the end
+ * of the function.  This allows the caller to acquire the socket buffer lock
+ * while testing for the need for various sorts of wakeup and hold it through
+ * to the point where it's no longer required.  We currently hold the lock
+ * through calls out to other subsystems (with the exception of kqueue), and
+ * then release it to avoid lock order issues.  It's not clear that's
+ * correct.
  */
 void
 sowakeup(so, sb)
@@ -366,19 +398,23 @@
 	register struct sockbuf *sb;
 {
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	selwakeuppri(&sb->sb_sel, PSOCK);
 	sb->sb_flags &= ~SB_SEL;
 	if (sb->sb_flags & SB_WAIT) {
 		sb->sb_flags &= ~SB_WAIT;
 		wakeup(&sb->sb_cc);
 	}
+	KNOTE(&sb->sb_sel.si_note, 0);
+	SOCKBUF_UNLOCK(sb);
 	if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
 		pgsigio(&so->so_sigio, SIGIO, 0);
 	if (sb->sb_flags & SB_UPCALL)
 		(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
 	if (sb->sb_flags & SB_AIO)
 		aio_swake(so, sb);
-	KNOTE(&sb->sb_sel.si_note, 0);
+	mtx_assert(SOCKBUF_MTX(sb), MA_NOTOWNED);
 }
 
 /*
@@ -500,17 +536,29 @@
  * Free mbufs held by a socket, and reserved mbuf space.
  */
 void
-sbrelease(sb, so)
+sbrelease_locked(sb, so)
 	struct sockbuf *sb;
 	struct socket *so;
 {
 
-	sbflush(sb);
+	SOCKBUF_LOCK_ASSERT(sb);
+
+	sbflush_locked(sb);
 	(void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
 	    RLIM_INFINITY);
 	sb->sb_mbmax = 0;
 }
 
+void
+sbrelease(sb, so)
+	struct sockbuf *sb;
+	struct socket *so;
+{
+
+	SOCKBUF_LOCK(sb);
+	sbrelease_locked(sb, so);
+	SOCKBUF_UNLOCK(sb);
+}
 /*
  * Routines to add and remove
  * data from an mbuf queue.
@@ -542,6 +590,8 @@
 {
 	struct mbuf *m = sb->sb_mb;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	while (m && m->m_nextpkt)
 		m = m->m_nextpkt;
 
@@ -561,6 +611,8 @@
 	struct mbuf *m = sb->sb_mb;
 	struct mbuf *n;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	while (m && m->m_nextpkt)
 		m = m->m_nextpkt;
 
@@ -583,6 +635,7 @@
 #endif /* SOCKBUF_DEBUG */
 
 #define SBLINKRECORD(sb, m0) do {					\
+	SOCKBUF_LOCK_ASSERT(sb);					\
 	if ((sb)->sb_lastrecord != NULL)				\
 		(sb)->sb_lastrecord->m_nextpkt = (m0);			\
 	else								\
@@ -597,14 +650,17 @@
  * discarded and mbufs are compacted where possible.
  */
 void
-sbappend(sb, m)
+sbappend_locked(sb, m)
 	struct sockbuf *sb;
 	struct mbuf *m;
 {
 	register struct mbuf *n;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (m == 0)
 		return;
+
 	SBLASTRECORDCHK(sb);
 	n = sb->sb_mb;
 	if (n) {
@@ -612,7 +668,7 @@
 			n = n->m_nextpkt;
 		do {
 			if (n->m_flags & M_EOR) {
-				sbappendrecord(sb, m); /* XXXXXX!!!! */
+				sbappendrecord_locked(sb, m); /* XXXXXX!!!! */
 				return;
 			}
 		} while (n->m_next && (n = n->m_next));
@@ -625,7 +681,7 @@
 		if ((n = sb->sb_lastrecord) != NULL) {
 			do {
 				if (n->m_flags & M_EOR) {
-					sbappendrecord(sb, m); /* XXXXXX!!!! */
+					sbappendrecord_locked(sb, m); /* XXXXXX!!!! */
 					return;
 				}
 			} while (n->m_next && (n = n->m_next));
@@ -642,13 +698,31 @@
 }
 
 /*
+ * Append mbuf chain m to the last record in the
+ * socket buffer sb.  The additional space associated
+ * the mbuf chain is recorded in sb.  Empty mbufs are
+ * discarded and mbufs are compacted where possible.
+ */
+void
+sbappend(sb, m)
+	struct sockbuf *sb;
+	struct mbuf *m;
+{
+
+	SOCKBUF_LOCK(sb);
+	sbappend_locked(sb, m);
+	SOCKBUF_UNLOCK(sb);
+}
+
+/*
  * This version of sbappend() should only be used when the caller
  * absolutely knows that there will never be more than one record
  * in the socket buffer, that is, a stream protocol (such as TCP).
  */
 void
-sbappendstream(struct sockbuf *sb, struct mbuf *m)
+sbappendstream_locked(struct sockbuf *sb, struct mbuf *m)
 {
+	SOCKBUF_LOCK_ASSERT(sb);
 
 	KASSERT(m->m_nextpkt == NULL,("sbappendstream 0"));
 	KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1"));
@@ -661,6 +735,20 @@
 	SBLASTRECORDCHK(sb);
 }
 
+/*
+ * This version of sbappend() should only be used when the caller
+ * absolutely knows that there will never be more than one record
+ * in the socket buffer, that is, a stream protocol (such as TCP).
+ */
+void
+sbappendstream(struct sockbuf *sb, struct mbuf *m)
+{
+
+	SOCKBUF_LOCK(sb);
+	sbappendstream_locked(sb, m);
+	SOCKBUF_UNLOCK(sb);
+}
+
 #ifdef SOCKBUF_DEBUG
 void
 sbcheck(sb)
@@ -670,6 +758,8 @@
 	struct mbuf *n = 0;
 	u_long len = 0, mbcnt = 0;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	for (m = sb->sb_mb; m; m = n) {
 	    n = m->m_nextpkt;
 	    for (; m; m = m->m_next) {
@@ -692,12 +782,14 @@
  * begins a new record.
  */
 void
-sbappendrecord(sb, m0)
+sbappendrecord_locked(sb, m0)
 	register struct sockbuf *sb;
 	register struct mbuf *m0;
 {
 	register struct mbuf *m;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (m0 == 0)
 		return;
 	m = sb->sb_mb;
@@ -725,18 +817,35 @@
 }
 
 /*
+ * As above, except the mbuf chain
+ * begins a new record.
+ */
+void
+sbappendrecord(sb, m0)
+	register struct sockbuf *sb;
+	register struct mbuf *m0;
+{
+
+	SOCKBUF_LOCK(sb);
+	sbappendrecord_locked(sb, m0);
+	SOCKBUF_UNLOCK(sb);
+}
+
+/*
  * As above except that OOB data
  * is inserted at the beginning of the sockbuf,
  * but after any other OOB data.
  */
 void
-sbinsertoob(sb, m0)
+sbinsertoob_locked(sb, m0)
 	register struct sockbuf *sb;
 	register struct mbuf *m0;
 {
 	register struct mbuf *m;
 	register struct mbuf **mp;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (m0 == 0)
 		return;
 	for (mp = &sb->sb_mb; *mp ; mp = &((*mp)->m_nextpkt)) {
@@ -771,13 +880,29 @@
 }
 
 /*
+ * As above except that OOB data
+ * is inserted at the beginning of the sockbuf,
+ * but after any other OOB data.
+ */
+void
+sbinsertoob(sb, m0)
+	register struct sockbuf *sb;
+	register struct mbuf *m0;
+{
+
+	SOCKBUF_LOCK(sb);
+	sbinsertoob_locked(sb, m0);
+	SOCKBUF_UNLOCK(sb);
+}
+
+/*
  * Append address and data, and optionally, control (ancillary) data
  * to the receive queue of a socket.  If present,
  * m0 must include a packet header with total length.
  * Returns 0 if no space in sockbuf or insufficient mbufs.
  */
 int
-sbappendaddr(sb, asa, m0, control)
+sbappendaddr_locked(sb, asa, m0, control)
 	struct sockbuf *sb;
 	const struct sockaddr *asa;
 	struct mbuf *m0, *control;
@@ -785,11 +910,14 @@
 	struct mbuf *m, *n, *nlast;
 	int space = asa->sa_len;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
-		panic("sbappendaddr");
+		panic("sbappendaddr_locked");
 	if (m0)
 		space += m0->m_pkthdr.len;
 	space += m_length(control, &n);
+
 	if (space > sbspace(sb))
 		return (0);
 #if MSIZE <= 256
@@ -819,17 +947,40 @@
 	return (1);
 }
 
+/*
+ * Append address and data, and optionally, control (ancillary) data
+ * to the receive queue of a socket.  If present,
+ * m0 must include a packet header with total length.
+ * Returns 0 if no space in sockbuf or insufficient mbufs.
+ */
 int
-sbappendcontrol(sb, m0, control)
+sbappendaddr(sb, asa, m0, control)
+	struct sockbuf *sb;
+	const struct sockaddr *asa;
+	struct mbuf *m0, *control;
+{
+	int retval;
+
+	SOCKBUF_LOCK(sb);
+	retval = sbappendaddr_locked(sb, asa, m0, control);
+	SOCKBUF_UNLOCK(sb);
+	return (retval);
+}
+
+int
+sbappendcontrol_locked(sb, m0, control)
 	struct sockbuf *sb;
 	struct mbuf *control, *m0;
 {
 	struct mbuf *m, *n, *mlast;
 	int space;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (control == 0)
-		panic("sbappendcontrol");
+		panic("sbappendcontrol_locked");
 	space = m_length(control, &n) + m_length(m0, NULL);
+
 	if (space > sbspace(sb))
 		return (0);
 	n->m_next = m0;			/* concatenate data to control */
@@ -849,6 +1000,19 @@
 	return (1);
 }
 
+int
+sbappendcontrol(sb, m0, control)
+	struct sockbuf *sb;
+	struct mbuf *control, *m0;
+{
+	int retval;
+
+	SOCKBUF_LOCK(sb);
+	retval = sbappendcontrol_locked(sb, m0, control);
+	SOCKBUF_UNLOCK(sb);
+	return (retval);
+}
+
 /*
  * Compress mbuf chain m into the socket
  * buffer sb following mbuf n.  If n
@@ -862,6 +1026,8 @@
 	register int eor = 0;
 	register struct mbuf *o;
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	while (m) {
 		eor |= m->m_flags & M_EOR;
 		if (m->m_len == 0 &&
@@ -914,12 +1080,14 @@
  * Check that all resources are reclaimed.
  */
 void
-sbflush(sb)
+sbflush_locked(sb)
 	register struct sockbuf *sb;
 {
 
+	SOCKBUF_LOCK_ASSERT(sb);
+
 	if (sb->sb_flags & SB_LOCK)
-		panic("sbflush: locked");
+		panic("sbflush_locked: locked");
 	while (sb->sb_mbcnt) {
 		/*
 		 * Don't call sbdrop(sb, 0) if the leading mbuf is non-empty:
@@ -927,23 +1095,35 @@
 		 */
 		if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len))
 			break;
-		sbdrop(sb, (int)sb->sb_cc);
+		sbdrop_locked(sb, (int)sb->sb_cc);
 	}
 	if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt)
-		panic("sbflush: cc %u || mb %p || mbcnt %u", sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt);
+		panic("sbflush_locked: cc %u || mb %p || mbcnt %u", sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt);
+}
+
+void
+sbflush(sb)
+	register struct sockbuf *sb;
+{
+
+	SOCKBUF_LOCK(sb);
+	sbflush_locked(sb);
+	SOCKBUF_UNLOCK(sb);
 }
 
 /*
  * Drop data from (the front of) a sockbuf.
  */

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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