Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Apr 2006 22:19:21 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 96112 for review
Message-ID:  <200604252219.k3PMJLOq016016@repoman.freebsd.org>

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

Change 96112 by marcel@marcel_nfs on 2006/04/25 22:18:32

	IFC @96106

Affected files ...

.. //depot/projects/uart/amd64/amd64/mp_machdep.c#14 integrate
.. //depot/projects/uart/boot/i386/libi386/biosacpi.c#7 integrate
.. //depot/projects/uart/conf/options#32 integrate
.. //depot/projects/uart/ddb/db_ps.c#8 integrate
.. //depot/projects/uart/ddb/db_thread.c#5 integrate
.. //depot/projects/uart/ddb/ddb.h#9 integrate
.. //depot/projects/uart/dev/bce/if_bcereg.h#2 integrate
.. //depot/projects/uart/dev/bge/if_bge.c#25 integrate
.. //depot/projects/uart/i386/i386/mp_machdep.c#22 integrate
.. //depot/projects/uart/kern/subr_turnstile.c#9 integrate
.. //depot/projects/uart/kern/subr_witness.c#16 integrate
.. //depot/projects/uart/kern/uipc_syscalls.c#18 integrate
.. //depot/projects/uart/netgraph/netflow/netflow.c#9 integrate
.. //depot/projects/uart/netgraph/netflow/netflow.h#3 integrate
.. //depot/projects/uart/netinet/in_pcb.c#16 integrate
.. //depot/projects/uart/netinet/in_pcb.h#10 integrate
.. //depot/projects/uart/netinet/tcp_subr.c#21 integrate
.. //depot/projects/uart/netinet/udp_usrreq.c#16 integrate
.. //depot/projects/uart/netinet6/in6_pcb.c#13 integrate
.. //depot/projects/uart/netinet6/in6_src.c#9 integrate
.. //depot/projects/uart/nfsserver/nfsrvcache.h#4 integrate
.. //depot/projects/uart/vm/vm_pageq.c#8 integrate

Differences ...

==== //depot/projects/uart/amd64/amd64/mp_machdep.c#14 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.272 2006/04/24 21:17:01 cperciva Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.273 2006/04/25 00:06:37 jkim Exp $");
 
 #include "opt_cpu.h"
 #include "opt_kstack_pages.h"
@@ -183,6 +183,7 @@
 mp_topology(void)
 {
 	struct cpu_group *group;
+	u_int regs[4];
 	int logical_cpus;
 	int apic_id;
 	int groups;
@@ -195,6 +196,13 @@
 	logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
 	if (logical_cpus <= 1)
 		return;
+	/* Nothing to do if reported cores are physical cores. */
+	if (strcmp(cpu_vendor, "GenuineIntel") == 0 && cpu_high >= 4) {
+		cpuid_count(4, 0, regs);
+		if ((regs[0] & 0x1f) != 0 &&
+		    logical_cpus <= ((regs[0] >> 26) & 0x3f) + 1)
+			return;
+	}
 	group = &mp_groups[0];
 	groups = 1;
 	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {

==== //depot/projects/uart/boot/i386/libi386/biosacpi.c#7 (text+ko) ====

@@ -25,11 +25,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.10 2005/04/16 17:38:24 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.11 2006/04/25 18:42:22 jhb Exp $");
 
 #include <stand.h>
 #include <machine/stdarg.h>
 #include <bootstrap.h>
+#include <btxv86.h>
+#include "libi386.h"
 
 #include "acfreebsd.h"
 #include "acconfig.h"
@@ -93,7 +95,7 @@
     uint16_t		*addr;
 
     /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
-    addr = (uint16_t *)0x40E;
+    addr = (uint16_t *)PTOV(0x40E);
     if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), 0x400)) != NULL)
 	return (rsdp);
 
@@ -113,7 +115,7 @@
 
     /* search on 16-byte boundaries */
     for (ofs = 0; ofs < length; ofs += 16) {
-	rsdp = (RSDP_DESCRIPTOR *)(base + ofs);
+	rsdp = (RSDP_DESCRIPTOR *)PTOV(base + ofs);
 
 	/* compare signature, validate checksum */
 	if (!strncmp(rsdp->Signature, RSDP_SIG, strlen(RSDP_SIG))) {

==== //depot/projects/uart/conf/options#32 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/options,v 1.536 2006/04/24 23:31:50 marcel Exp $
+# $FreeBSD: src/sys/conf/options,v 1.537 2006/04/25 15:56:52 mr Exp $
 #
 #        On the handling of kernel options
 #
@@ -639,9 +639,6 @@
 # bce driver
 BCE_DEBUG		opt_bce.h
 
-# bge driver
-BGE_FAKE_AUTONEG	opt_bge.h
-
 # wi driver
 WI_SYMBOL_FIRMWARE	opt_wi.h
 

==== //depot/projects/uart/ddb/db_ps.c#8 (text+ko) ====

@@ -28,13 +28,17 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.55 2004/11/20 02:32:42 das Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.56 2006/04/25 20:34:04 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/jail.h>
+#include <sys/kdb.h>
+#include <sys/linker_set.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
+#include <sys/sysent.h>
 #include <sys/cons.h>
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -42,19 +46,47 @@
 
 #include <ddb/ddb.h>
 
-static void	dumpthread(volatile struct proc *p, volatile struct thread *td);
+/* XXX I'd prefer a better way. */
+#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__)
+#define	PTR64
+#endif
+
+#ifdef PTR64
+CTASSERT(sizeof(uintptr_t) == sizeof(uint64_t));
+#else
+CTASSERT(sizeof(uintptr_t) == sizeof(uint32_t));
+#endif
+
+static void	dumpthread(volatile struct proc *p, volatile struct thread *td,
+		    int all);
 
+/*
+ * Layout:
+ * - column counts
+ * - header
+ * - single-threaded process
+ * - multi-threaded process
+ * - thread in a MT process
+ *
+ *          1         2         3         4         5         6         7
+ * 1234567890123456789012345678901234567890123456789012345678901234567890
+ *  pid   uid  ppid  pgrp  state   wmesg      wchan    cmd
+ * <pid> <ui> <ppi> <pgi> <stat> < wmesg > <  wchan  > <name>
+ * <pid> <ui> <ppi> <pgi> <stat>  (threaded)           <command>
+ *  <tid    >             <stat> < wmesg > <  wchan  > <name>
+ *
+ * For machines with 64-bit pointers, we expand the wchan field 8 more
+ * characters.
+ */
 void
-db_ps(dummy1, dummy2, dummy3, dummy4)
-	db_expr_t	dummy1;
-	boolean_t	dummy2;
-	db_expr_t	dummy3;
-	char *		dummy4;
+db_ps(db_expr_t addr, boolean_t hasaddr, db_expr_t count, char *modif)
 {
 	volatile struct proc *p, *pp;
 	volatile struct thread *td;
-	char *state;
-	int np, quit;
+	struct ucred *cred;
+	struct pgrp *pgrp;
+	char state[9];
+	int np, quit, rflag, sflag, dflag, lflag, wflag;
 
 	np = nprocs;
 	quit = 0;
@@ -66,10 +98,14 @@
 		p = &proc0;
 
 	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
-	db_printf("  pid   proc     uid  ppid  pgrp  flag   stat  wmesg    wchan  cmd\n");
+#ifdef PTR64
+	db_printf(" pid   uid  ppid  pgrp  state   wmesg          wchan        cmd\n");
+#else
+	db_printf(" pid   uid  ppid  pgrp  state   wmesg      wchan    cmd\n");
+#endif
 	while (--np >= 0 && !quit) {
 		if (p == NULL) {
-			printf("oops, ran out of processes early!\n");
+			db_printf("oops, ran out of processes early!\n");
 			break;
 		}
 		/* PROC_LOCK(p); */
@@ -77,33 +113,99 @@
 		if (pp == NULL)
 			pp = p;
 
+		cred = p->p_ucred;
+		pgrp = p->p_pgrp;
+		db_printf("%5d %4d %5d %5d ", p->p_pid,
+		    cred != NULL ? cred->cr_ruid : 0, pp->p_pid,
+		    pgrp != NULL ? pgrp->pg_id : 0);
 
+		/* Determine our primary process state. */
 		switch(p->p_state) {
 		case PRS_NORMAL:
 			if (P_SHOULDSTOP(p))
-				state = "stop";
-			else
-				state = "";
+				state[0] = 'T';
+			else {
+				/*
+				 * One of D, L, R, S, W.  For a
+				 * multithreaded process we will use
+				 * the state of the thread with the
+				 * highest precedence.  The
+				 * precendence order from high to low
+				 * is R, L, D, S, W.  If no thread is
+				 * in a sane state we use '?' for our
+				 * primary state.
+				 */
+				rflag = sflag = dflag = lflag = wflag = 0;
+				FOREACH_THREAD_IN_PROC(p, td) {
+					if (td->td_state == TDS_RUNNING ||
+					    td->td_state == TDS_RUNQ ||
+					    td->td_state == TDS_CAN_RUN)
+						rflag++;
+					if (TD_ON_LOCK(td))
+						lflag++;
+					if (TD_IS_SLEEPING(td)) {
+						if (!td->td_flags & TDF_SINTR)
+							dflag++;
+						else
+							sflag++;
+					}
+					if (TD_AWAITING_INTR(td))
+						wflag++;
+				}
+				if (rflag)
+					state[0] = 'R';
+				else if (lflag)
+					state[0] = 'L';
+				else if (dflag)
+					state[0] = 'D';
+				else if (sflag)
+					state[0] = 'S';
+				else if (wflag)
+					state[0] = 'W';
+				else
+					state[0] = '?';				
+			}
 			break;
 		case PRS_NEW:
-			state = "new ";
+			state[0] = 'N';
 			break;
 		case PRS_ZOMBIE:
-			state = "zomb";
+			state[0] = 'Z';
 			break;
 		default:
-			state = "Unkn";
+			state[0] = 'U';
 			break;
 		}
-		db_printf("%5d %8p %4d %5d %5d %07x %s",
-		    p->p_pid, (volatile void *)p,
-		    p->p_ucred != NULL ? p->p_ucred->cr_ruid : 0, pp->p_pid,
-		    p->p_pgrp != NULL ? p->p_pgrp->pg_id : 0, p->p_flag,
-		    state);
+		state[1] = '\0';
+
+		/* Additional process state flags. */
+		if (!p->p_sflag & PS_INMEM)
+			strlcat(state, "W", sizeof(state));
+		if (p->p_flag & P_TRACED)
+			strlcat(state, "X", sizeof(state));
+		if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE)
+			strlcat(state, "E", sizeof(state));
+		if (p->p_flag & P_PPWAIT)
+			strlcat(state, "V", sizeof(state));
+		if (p->p_flag & P_SYSTEM || p->p_lock > 0)
+			strlcat(state, "L", sizeof(state));
+		if (p->p_session != NULL && SESS_LEADER(p))
+			strlcat(state, "s", sizeof(state));
+		/* Cheated here and didn't compare pgid's. */
+		if (p->p_flag & P_CONTROLT)
+			strlcat(state, "+", sizeof(state));
+		if (cred != NULL && jailed(cred))
+			strlcat(state, "J", sizeof(state));
+		db_printf(" %-6.6s ", state);
 		if (p->p_flag & P_HADTHREADS)
-			db_printf("(threaded)  %s\n", p->p_comm);
+#ifdef PTR64
+			db_printf(" (threaded)                  %s\n",
+			    p->p_comm);
+#else
+			db_printf(" (threaded)          %s\n", p->p_comm);
+#endif
 		FOREACH_THREAD_IN_PROC(p, td) {
-			dumpthread(p, td);
+			dumpthread(p, td, p->p_flag & P_HADTHREADS);
 			if (quit)
 				break;
 		}
@@ -117,54 +219,216 @@
 }
 
 static void
-dumpthread(volatile struct proc *p, volatile struct thread *td)
+dumpthread(volatile struct proc *p, volatile struct thread *td, int all)
+{
+	char state[9], wprefix;
+	const char *wmesg;
+	void *wchan;
+	
+	if (all) {
+		db_printf(" %9d             ", td->td_tid);
+		switch (td->td_state) {
+		case TDS_RUNNING:
+			snprintf(state, sizeof(state), "Run");
+			break;
+		case TDS_RUNQ:
+			snprintf(state, sizeof(state), "RunQ");
+			break;
+		case TDS_CAN_RUN:
+			snprintf(state, sizeof(state), "CanRun");
+			break;
+		case TDS_INACTIVE:
+			snprintf(state, sizeof(state), "Inactv");
+			break;
+		case TDS_INHIBITED:
+			state[0] = '\0';
+			if (TD_ON_LOCK(td))
+				strlcat(state, "L", sizeof(state));
+			if (TD_IS_SLEEPING(td)) {
+				if (td->td_flags & TDF_SINTR)
+					strlcat(state, "S", sizeof(state));
+				else
+					strlcat(state, "D", sizeof(state));
+			}
+			if (TD_IS_SWAPPED(td))
+				strlcat(state, "W", sizeof(state));
+			if (TD_AWAITING_INTR(td))
+				strlcat(state, "I", sizeof(state));
+			if (TD_IS_SUSPENDED(td))
+				strlcat(state, "s", sizeof(state));
+			if (state[0] != '\0')
+				break;
+		default:
+			snprintf(state, sizeof(state), "???");
+		}			
+		db_printf(" %-6.6s ", state);
+	}
+	wprefix = ' ';
+	if (TD_ON_LOCK(td)) {
+		wprefix = '*';
+		wmesg = td->td_lockname;
+		wchan = td->td_blocked;
+	} else if (TD_ON_SLEEPQ(td)) {
+		wmesg = td->td_wmesg;
+		wchan = td->td_wchan;
+	} else if (TD_IS_RUNNING(td)) {
+		snprintf(state, sizeof(state), "CPU %d", td->td_oncpu);
+		wmesg = state;
+		wchan = NULL;
+	} else {
+		wmesg = "";
+		wchan = NULL;
+	}
+	db_printf("%c%-8.8s ", wprefix, wmesg);
+	if (wchan == NULL)
+#ifdef PTR64
+		db_printf("%18s ", "");
+#else
+		db_printf("%10s ", "");
+#endif
+	else
+		db_printf("%p ", wchan);
+	if (p->p_flag & P_SYSTEM)
+		db_printf("[");
+	if (td->td_name[0] != '\0')
+		db_printf("%s", td->td_name);
+	else
+		db_printf("%s", td->td_proc->p_comm);
+	if (p->p_flag & P_SYSTEM)
+		db_printf("]");
+	db_printf("\n");
+}
+
+DB_SHOW_COMMAND(thread, db_show_thread)
 {
+	struct thread *td;
+	boolean_t comma;
+
+	/* Determine which thread to examine. */
+	if (have_addr)
+		td = db_lookup_thread(addr, FALSE);
+	else
+		td = kdb_thread;
 
-	if (p->p_flag & P_HADTHREADS)
-		db_printf( "   thread %p ksegrp %p ", td, td->td_ksegrp);
-	if (TD_ON_SLEEPQ(td))
-		db_printf("[SLPQ %s %p]", td->td_wmesg, (void *)td->td_wchan);
+	db_printf("Thread %d at %p:\n", td->td_tid, td);
+	db_printf(" proc (pid %d): %p ", td->td_proc->p_pid, td->td_proc);
+	db_printf(" ksegrp: %p\n", td->td_ksegrp);
+	if (td->td_name[0] != '\0')
+		db_printf(" name: %s\n", td->td_name);
+	db_printf(" flags: %#x ", td->td_flags);
+	db_printf(" pflags: %#x\n", td->td_pflags);
+	db_printf(" state: ");
 	switch (td->td_state) {
+	case TDS_INACTIVE:
+		db_printf("INACTIVE\n");
+		break;
+	case TDS_CAN_RUN:
+		db_printf("CAN RUN\n");
+		break;
+	case TDS_RUNQ:
+		db_printf("RUNQ\n");
+		break;
+	case TDS_RUNNING:
+		db_printf("RUNNING (CPU %d)\n", td->td_oncpu);
+		break;
 	case TDS_INHIBITED:
-		if (TD_ON_LOCK(td)) {
-			db_printf("[LOCK %6s %8p]",
-			    td->td_lockname,
-			    (void *)td->td_blocked);
+		db_printf("INHIBITED: {");
+		comma = FALSE;
+		if (TD_IS_SLEEPING(td)) {
+			db_printf("SLEEPING");
+			comma = TRUE;
+		}
+		if (TD_IS_SUSPENDED(td)) {
+			if (comma)
+				db_printf(", ");
+			db_printf("SUSPENDED");
+			comma = TRUE;
 		}
-		if (TD_IS_SLEEPING(td)) {
-			db_printf("[SLP]");
-		}  
 		if (TD_IS_SWAPPED(td)) {
-			db_printf("[SWAP]");
+			if (comma)
+				db_printf(", ");
+			db_printf("SWAPPED");
+			comma = TRUE;
 		}
-		if (TD_IS_SUSPENDED(td)) {
-			db_printf("[SUSP]");
+		if (TD_ON_LOCK(td)) {
+			if (comma)
+				db_printf(", ");
+			db_printf("LOCK");
+			comma = TRUE;
 		}
 		if (TD_AWAITING_INTR(td)) {
-			db_printf("[IWAIT]");
+			if (comma)
+				db_printf(", ");
+			db_printf("IWAIT");
 		}
+		db_printf("}\n");
 		break;
-	case TDS_CAN_RUN:
-		db_printf("[Can run]");
+	default:
+		db_printf("??? (%#x)\n", td->td_state);
 		break;
-	case TDS_RUNQ:
-		db_printf("[RUNQ]");
+	}
+	if (TD_ON_LOCK(td))
+		db_printf(" lock: %s  turnstile: %p\n", td->td_lockname,
+		    td->td_blocked);
+	if (TD_ON_SLEEPQ(td))
+		db_printf(" wmesg: %s  wchan: %p\n", td->td_wmesg,
+		    td->td_wchan);
+	db_printf(" priority: %d\n", td->td_priority);
+}
+
+DB_SHOW_COMMAND(proc, db_show_proc)
+{
+	struct thread *td;
+	struct proc *p;
+	int i, quit;
+
+	/* Determine which process to examine. */
+	if (have_addr)
+		p = db_lookup_proc(addr);
+	else
+		p = kdb_thread->td_proc;
+
+	quit = 0;
+	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
+	db_printf("Process %d (%s) at %p:\n", p->p_pid, p->p_comm, p);
+	db_printf(" state: ");
+	switch (p->p_state) {
+	case PRS_NEW:
+		db_printf("NEW\n");
 		break;
-	case TDS_RUNNING:
-		db_printf("[CPU %d]", td->td_oncpu);
+	case PRS_NORMAL:
+		db_printf("NORMAL\n");
 		break;
-	case TDS_INACTIVE:
-		db_printf("[INACTIVE]");
+	case PRS_ZOMBIE:
+		db_printf("ZOMBIE\n");
 		break;
 	default:
-		db_printf("[UNK: %#x]", td->td_state);
+		db_printf("??? (%#x)\n", p->p_state);
 	}
-	if (p->p_flag & P_HADTHREADS) {
-#ifdef KEF_DIDRUN
-		if (td->td_kse)
-			db_printf("[kse %p]", td->td_kse);
-#endif
+	if (p->p_ucred != NULL) {
+		db_printf(" uid: %d  gids: ", p->p_ucred->cr_uid);
+		for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
+			db_printf("%d", p->p_ucred->cr_groups[i]);
+			if (i < (p->p_ucred->cr_ngroups - 1))
+				db_printf(", ");
+		}
 		db_printf("\n");
-	} else
-		db_printf(" %s\n", p->p_comm);
+	}
+	if (p->p_pptr != NULL)
+		db_printf(" parent: pid %d at %p\n", p->p_pptr->p_pid,
+		    p->p_pptr);
+	if (p->p_leader != NULL && p->p_leader != p)
+		db_printf(" leader: pid %d at %p\n", p->p_leader->p_pid,
+		    p->p_leader);
+	if (p->p_sysent != NULL)
+		db_printf(" ABI: %s\n", p->p_sysent->sv_name);
+	if (p->p_args != NULL)
+		db_printf(" arguments: %.*s\n", (int)p->p_args->ar_length,
+		    p->p_args->ar_args);
+	db_printf(" threads: %d\n", p->p_numthreads);
+	FOREACH_THREAD_IN_PROC(p, td) {
+		dumpthread(p, td, 1);
+		if (quit)
+			break;
+	}
 }

==== //depot/projects/uart/ddb/db_thread.c#5 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_thread.c,v 1.4 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_thread.c,v 1.5 2006/04/25 20:22:48 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,8 @@
 #include <ddb/db_command.h>
 #include <ddb/db_sym.h>
 
+static db_expr_t hex2dec(db_expr_t expr);
+
 void
 db_print_thread(void)
 {
@@ -108,3 +110,93 @@
 		thr = kdb_thr_next(thr);
 	}
 }
+
+/*
+ * Take the parsed expression value from the command line that was parsed
+ * as a hexadecimal value and convert it as if the expression was parsed
+ * as a decimal value.  Returns -1 if the expression was not a valid
+ * decimal value.
+ */
+static db_expr_t
+hex2dec(db_expr_t expr)
+{
+	uintptr_t x, y;
+	db_expr_t val;
+
+	y = 1;
+	val = 0;
+	x = expr;
+	while (x != 0) {
+		if (x % 16 > 9)
+			return (-1);
+		val += (x % 16) * (y);
+		x >>= 4;
+		y *= 10;
+	}
+	return (val);
+}
+
+/*
+ * Lookup a thread based on a db expression address.  We assume that the
+ * address was parsed in hexadecimal.  We reparse the address in decimal
+ * first and try to treat it as a thread ID to find an associated thread.
+ * If that fails and check_pid is true, we terat the decimal value as a
+ * PID.  If that matches a process, we return the first thread in that
+ * process.  Otherwise, we treat the addr as a pointer to a thread.
+ */
+struct thread *
+db_lookup_thread(db_expr_t addr, boolean_t check_pid)
+{
+	struct thread *td;
+	db_expr_t decaddr;
+	struct proc *p;
+
+	/*
+	 * If the parsed address was not a valid decimal expression,
+	 * assume it is a thread pointer.
+	 */
+	decaddr = hex2dec(addr);
+	if (decaddr == -1)
+		return ((struct thread *)addr);
+
+	td = kdb_thr_lookup(decaddr);
+	if (td != NULL)
+		return (td);
+	if (check_pid) {
+		LIST_FOREACH(p, &allproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (FIRST_THREAD_IN_PROC(p));
+		}
+		LIST_FOREACH(p, &zombproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (FIRST_THREAD_IN_PROC(p));
+		}
+	}
+	return ((struct thread *)addr);
+}
+
+/*
+ * Lookup a process based on a db expression address.  We assume that the
+ * address was parsed in hexadecimal.  We reparse the address in decimal
+ * first and try to treat it as a PID to find an associated process.
+ * If that fails we treat the addr as a pointer to a process.
+ */
+struct proc *
+db_lookup_proc(db_expr_t addr)
+{
+	db_expr_t decaddr;
+	struct proc *p;
+
+	decaddr = hex2dec(addr);
+	if (decaddr != -1) {
+		LIST_FOREACH(p, &allproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (p);
+		}
+		LIST_FOREACH(p, &zombproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (p);
+		}
+	}
+	return ((struct proc *)addr);
+}

==== //depot/projects/uart/ddb/ddb.h#9 (text+ko) ====

@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/ddb/ddb.h,v 1.41 2006/03/07 22:17:05 jhb Exp $
+ * $FreeBSD: src/sys/ddb/ddb.h,v 1.42 2006/04/25 20:22:48 jhb Exp $
  */
 
 /*
@@ -101,6 +101,8 @@
 int		db_expression(db_expr_t *valuep);
 int		db_get_variable(db_expr_t *valuep);
 void		db_iprintf(const char *,...) __printflike(1, 2);
+struct proc	*db_lookup_proc(db_expr_t addr);
+struct thread	*db_lookup_thread(db_expr_t addr, boolean_t check_pid);
 struct vm_map	*db_map_addr(vm_offset_t);
 boolean_t	db_map_current(struct vm_map *);
 boolean_t	db_map_equal(struct vm_map *, struct vm_map *);

==== //depot/projects/uart/dev/bce/if_bcereg.h#2 (text) ====

@@ -26,7 +26,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/bce/if_bcereg.h,v 1.1 2006/04/10 19:55:23 ps Exp $
+ * $FreeBSD: src/sys/dev/bce/if_bcereg.h,v 1.2 2006/04/25 19:18:48 jhb Exp $
  */
 
 #ifndef	_BCE_H_DEFINED
@@ -4703,7 +4703,7 @@
 #define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG	0x100
 #define BCE_PHY_INT_MODE_LINK_READY_FLAG	0x200
 
-	bus_size_t			max_bus_addr;
+	bus_addr_t			max_bus_addr;
 	u16					bus_speed_mhz;		/* PCI bus speed */
 	struct flash_spec	*bce_flash_info;	/* Flash NVRAM settings */
 	u32					bce_flash_size;		/* Flash NVRAM size */

==== //depot/projects/uart/dev/bge/if_bge.c#25 (text+ko) ====

@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.126 2006/04/15 08:13:06 scottl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.128 2006/04/25 17:54:42 mjacob Exp $");
 
 /*
  * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
@@ -111,8 +111,6 @@
 
 #include <dev/bge/if_bgereg.h>
 
-#include "opt_bge.h"
-
 #define BGE_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP)
 #define ETHER_MIN_NOPAD		(ETHER_MIN_LEN - ETHER_CRC_LEN) /* i.e., 60 */
 
@@ -306,6 +304,9 @@
 DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0);
 DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0);
 
+static int bge_fake_autoneg = 0;
+TUNABLE_INT("hw.bge.fake_autoneg", &bge_fake_autoneg);
+
 static u_int32_t
 bge_readmem_ind(sc, off)
 	struct bge_softc *sc;
@@ -3341,13 +3342,13 @@
 			return(EINVAL);
 		switch(IFM_SUBTYPE(ifm->ifm_media)) {
 		case IFM_AUTO:
-#ifndef BGE_FAKE_AUTONEG
 			/*
 			 * The BCM5704 ASIC appears to have a special
 			 * mechanism for programming the autoneg
 			 * advertisement registers in TBI mode.
 			 */
-			if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+			if (bge_fake_autoneg == 0 &&
+			    sc->bge_asicrev == BGE_ASICREV_BCM5704) {
 				uint32_t sgdig;
 				CSR_WRITE_4(sc, BGE_TX_TBI_AUTONEG, 0);
 				sgdig = CSR_READ_4(sc, BGE_SGDIG_CFG);
@@ -3359,7 +3360,6 @@
 				DELAY(5);
 				CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
 			}
-#endif
 			break;
 		case IFM_1000_SX:
 			if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {

==== //depot/projects/uart/i386/i386/mp_machdep.c#22 (text+ko) ====

@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.265 2006/04/24 21:17:01 cperciva Exp $");
+__FBSDID("$FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.266 2006/04/25 00:06:37 jkim Exp $");
 
 #include "opt_apic.h"
 #include "opt_cpu.h"
@@ -240,6 +240,7 @@
 mp_topology(void)
 {
 	struct cpu_group *group;
+	u_int regs[4];
 	int logical_cpus;
 	int apic_id;
 	int groups;
@@ -252,6 +253,13 @@
 	logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
 	if (logical_cpus <= 1)
 		return;
+	/* Nothing to do if reported cores are physical cores. */
+	if (strcmp(cpu_vendor, "GenuineIntel") == 0 && cpu_high >= 4) {
+		cpuid_count(4, 0, regs);
+		if ((regs[0] & 0x1f) != 0 &&
+		    logical_cpus <= ((regs[0] >> 26) & 0x3f) + 1)
+			return;
+	}
 	group = &mp_groups[0];
 	groups = 1;
 	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {

==== //depot/projects/uart/kern/subr_turnstile.c#9 (text+ko) ====

@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/subr_turnstile.c,v 1.159 2006/04/21 20:40:43 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/subr_turnstile.c,v 1.160 2006/04/25 20:28:17 jhb Exp $");
 
 #include "opt_ddb.h"
 #include "opt_turnstile_profiling.h"
@@ -76,6 +76,7 @@
 #include <sys/turnstile.h>
 
 #ifdef DDB
+#include <sys/kdb.h>
 #include <ddb/ddb.h>
 #endif
 
@@ -1033,4 +1034,141 @@
 	print_queue(&ts->ts_pending, "Pending Threads", "\t");
 	
 }
+
+static void
+print_threadchain(struct thread *td, const char *prefix)
+{
+	struct lock_object *lock;
+	struct lock_class *class;
+	struct turnstile *ts;
+
+	/*
+	 * Follow the chain.  We keep walking as long as the thread is
+	 * blocked on a turnstile that has an owner.
+	 */
+	for (;;) {
+		db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
+		    td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name :
+		    td->td_proc->p_comm);
+		switch (td->td_state) {
+		case TDS_INACTIVE:
+			db_printf("is inactive\n");
+			return;
+		case TDS_CAN_RUN:
+			db_printf("can run\n");
+			return;
+		case TDS_RUNQ:
+			db_printf("is on a run queue\n");
+			return;
+		case TDS_RUNNING:
+			db_printf("running on CPU %d\n", td->td_oncpu);
+			return;
+		case TDS_INHIBITED:
+			if (TD_ON_LOCK(td)) {
+				ts = td->td_blocked;
+				lock = ts->ts_lockobj;
+				class = LOCK_CLASS(lock);
+				db_printf("blocked on lock %p (%s) \"%s\"\n",
+				    lock, class->lc_name, lock->lo_name);
+				if (ts->ts_owner == NULL)
+					return;
+				td = ts->ts_owner;
+				break;
+			}
+			db_printf("inhibited\n");
+			return;
+		default:
+			db_printf("??? (%#x)\n", td->td_state);
+			return;
+		}
+	}
+}
+
+DB_SHOW_COMMAND(threadchain, db_show_threadchain)
+{
+	struct thread *td;
+
+	/* Figure out which thread to start with. */
+	if (have_addr)
+		td = db_lookup_thread(addr, TRUE);
+	else
+		td = kdb_thread;
+
+	print_threadchain(td, "");
+}
+
+DB_SHOW_COMMAND(allchains, db_show_allchains)
+{
+	struct thread *td;
+	struct proc *p;
+	int i;
+
+	i = 1;
+	LIST_FOREACH(p, &allproc, p_list) {
+		FOREACH_THREAD_IN_PROC(p, td) {
+			if (TD_ON_LOCK(td) && LIST_EMPTY(&td->td_contested)) {
+				db_printf("chain %d:\n", i++);
+				print_threadchain(td, " ");
+			}
+		}
+	}
+}
+
+static void	print_waiters(struct turnstile *ts, int indent);
+	
+static void
+print_waiter(struct thread *td, int indent)
+{
+	struct turnstile *ts;
+	int i;
+
+	for (i = 0; i < indent; i++)
+		db_printf(" ");
+	print_thread(td, "thread ");
+	LIST_FOREACH(ts, &td->td_contested, ts_link)
+		print_waiters(ts, indent + 1);
+}
+
+static void
+print_waiters(struct turnstile *ts, int indent)
+{
+	struct lock_object *lock;
+	struct lock_class *class;
+	struct thread *td;
+	int i;
+
+	lock = ts->ts_lockobj;
+	class = LOCK_CLASS(lock);
+	for (i = 0; i < indent; i++)
+		db_printf(" ");
+	db_printf("lock %p (%s) \"%s\"\n", lock, class->lc_name, lock->lo_name);
+	TAILQ_FOREACH(td, &ts->ts_blocked[TS_EXCLUSIVE_QUEUE], td_lockq)
+		print_waiter(td, indent + 1);
+	TAILQ_FOREACH(td, &ts->ts_blocked[TS_SHARED_QUEUE], td_lockq)
+		print_waiter(td, indent + 1);
+	TAILQ_FOREACH(td, &ts->ts_pending, td_lockq)
+		print_waiter(td, indent + 1);
+}
+
+DB_SHOW_COMMAND(lockchain, db_show_lockchain)
+{
+	struct lock_object *lock;
+	struct lock_class *class;
+	struct turnstile_chain *tc;
+	struct turnstile *ts;
+
+	if (!have_addr)
+		return;
+	lock = (struct lock_object *)addr;
+	tc = TC_LOOKUP(lock);
+	LIST_FOREACH(ts, &tc->tc_turnstiles, ts_hash)
+		if (ts->ts_lockobj == lock)
+			break;
+	if (ts == NULL) {
+		class = LOCK_CLASS(lock);
+		db_printf("lock %p (%s) \"%s\"\n", lock, class->lc_name,
+		    lock->lo_name);
+	} else
+		print_waiters(ts, 0);
+}
 #endif

==== //depot/projects/uart/kern/subr_witness.c#16 (text+ko) ====

@@ -82,7 +82,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/subr_witness.c,v 1.214 2006/04/07 22:15:54 marcel Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/subr_witness.c,v 1.216 2006/04/25 20:24:23 jhb Exp $");
 
 #include "opt_ddb.h"
 #include "opt_witness.h"
@@ -382,7 +382,6 @@
 #endif
 	{ "scc_hwmtx", &lock_class_mtx_spin },
 	{ "uart_hwmtx", &lock_class_mtx_spin },

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



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