Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Aug 2006 06:52:59 GMT
From:      Chris Jones <cdjones@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 104654 for review
Message-ID:  <200608210652.k7L6qx0c032830@repoman.freebsd.org>

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

Change 104654 by cdjones@cdjones-impulse on 2006/08/21 06:52:43

	IFS.

Affected files ...

.. //depot/projects/soc2006/cdjones_jail/src/sys/conf/NOTES#4 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/conf/files#4 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_lock.c#5 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_sx.c#6 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_sleepqueue.c#5 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_turnstile.c#6 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_syscalls.c#6 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_lookup.c#5 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/sys/lockmgr.h#5 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/sys/sx.h#5 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/vm/vm_object.c#2 integrate

Differences ...

==== //depot/projects/soc2006/cdjones_jail/src/sys/conf/NOTES#4 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/NOTES,v 1.1325.2.16 2006/08/10 10:40:45 glebius Exp $
+# $FreeBSD: src/sys/conf/NOTES,v 1.1325.2.17 2006/08/17 11:01:24 ru Exp $
 #
 # NOTES -- Lines that can be cut/pasted into kernel and hints configs.
 #
@@ -2179,7 +2179,7 @@
 # which is a child of the 'smbus' device.
 #
 # Supported devices:
-# smb		standard io through /dev/smb*
+# smb		standard I/O through /dev/smb*
 #
 # Supported SMB interfaces:
 # iicsmb	I2C to SMB bridge with any iicbus interface
@@ -2189,7 +2189,9 @@
 # ichsmb	Intel ICH SMBus controller chips (82801AA, 82801AB, 82801BA)
 # viapm		VIA VT82C586B/596B/686A and VT8233 Power Management Unit
 # amdpm		AMD 756 Power Management Unit
+# amdsmb	AMD 8111 SMBus 2.0 Controller
 # nfpm		NVIDIA nForce Power Management Unit
+# nfsmb		NVIDIA nForce2/3/4 MCP SMBus 2.0 Controller
 #
 device		smbus		# Bus support, required for smb below.
 
@@ -2198,7 +2200,9 @@
 device		ichsmb
 device		viapm
 device		amdpm
+device		amdsmb
 device		nfpm
+device		nfsmb
 
 device		smb
 

==== //depot/projects/soc2006/cdjones_jail/src/sys/conf/files#4 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files,v 1.1031.2.37 2006/08/10 10:40:45 glebius Exp $
+# $FreeBSD: src/sys/conf/files,v 1.1031.2.38 2006/08/17 11:01:24 ru Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1811,6 +1811,7 @@
 pci/alpm.c			optional alpm pci
 pci/amdpm.c			optional amdpm pci
 pci/amdpm.c			optional nfpm pci
+pci/amdsmb.c			optional amdsmb pci
 pci/if_dc.c			optional dc pci
 pci/if_de.c			optional de pci
 pci/if_mn.c			optional mn pci
@@ -1826,6 +1827,7 @@
 pci/if_xl.c			optional xl pci
 pci/intpm.c			optional intpm pci
 pci/ncr.c			optional ncr pci
+pci/nfsmb.c			optional nfsmb pci
 pci/viapm.c			optional viapm pci
 pci/xrpu.c			optional xrpu pci
 posix4/ksched.c			optional _kposix_priority_scheduling

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_lock.c#5 (text+ko) ====

@@ -41,7 +41,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_lock.c,v 1.89.2.3 2006/03/13 03:05:50 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_lock.c,v 1.89.2.4 2006/08/17 19:53:06 jhb Exp $");
+
+#include "opt_ddb.h"
 
 #include <sys/param.h>
 #include <sys/kdb.h>
@@ -56,6 +58,10 @@
 #include <sys/stack.h>
 #endif
 
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
 /*
  * Locking primitives implementation.
  * Locks provide shared/exclusive sychronization.
@@ -575,3 +581,57 @@
 	stack_print(&lkp->lk_stack);
 #endif
 }
+
+#ifdef DDB
+/*
+ * Check to see if a thread that is blocked on a sleep queue is actually
+ * blocked on a 'struct lock'.  If so, output some details and return true.
+ * If the lock has an exclusive owner, return that in *ownerp.
+ */
+int
+lockmgr_chain(struct thread *td, struct thread **ownerp)
+{
+	struct lock *lkp;
+
+	lkp = td->td_wchan;
+
+	/* Simple test to see if wchan points to a lockmgr lock. */
+	if (lkp->lk_wmesg != td->td_wmesg)
+		return (0);
+
+	/* Ok, we think we have a lockmgr lock, so output some details. */
+	db_printf("blocked on lk \"%s\" ", lkp->lk_wmesg);
+	if (lkp->lk_sharecount) {
+		db_printf("SHARED (count %d)\n", lkp->lk_sharecount);
+		*ownerp = NULL;
+	} else {
+		db_printf("EXCL (count %d)\n", lkp->lk_exclusivecount);
+		*ownerp = lkp->lk_lockholder;
+	}
+	return (1);
+}
+
+DB_SHOW_COMMAND(lockmgr, db_show_lockmgr)
+{
+	struct thread *td;
+	struct lock *lkp;
+
+	if (!have_addr)
+		return;
+	lkp = (struct lock *)addr;
+
+	db_printf("lock type: %s\n", lkp->lk_wmesg);
+	db_printf("state: ");
+	if (lkp->lk_sharecount)
+		db_printf("SHARED (count %d)\n", lkp->lk_sharecount);
+	else if (lkp->lk_flags & LK_HAVE_EXCL) {
+		td = lkp->lk_lockholder;
+		db_printf("EXCL (count %d) %p ", lkp->lk_exclusivecount, td);
+		db_printf("(tid %d, pid %d, \"%s\")\n", td->td_tid,
+		    td->td_proc->p_pid, td->td_proc->p_comm);
+	} else
+		db_printf("UNLOCKED\n");
+	if (lkp->lk_waitcount > 0)
+		db_printf("waiters: %d\n", lkp->lk_waitcount);
+}
+#endif

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_sx.c#6 (text+ko) ====

@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_sx.c,v 1.25.2.3 2006/08/11 18:54:10 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_sx.c,v 1.25.2.4 2006/08/17 19:53:06 jhb Exp $");
 
 #include "opt_ddb.h"
 
@@ -48,9 +48,9 @@
 #include <sys/proc.h>
 #include <sys/sx.h>
 
+#ifdef DDB
 #include <ddb/ddb.h>
 
-#ifdef DDB
 static void	db_show_sx(struct lock_object *lock);
 #endif
 
@@ -395,4 +395,57 @@
 	db_printf(" waiters: %d shared, %d exclusive\n", sx->sx_shrd_wcnt,
 	    sx->sx_excl_wcnt);
 }
+
+/*
+ * Check to see if a thread that is blocked on a sleep queue is actually
+ * blocked on an sx lock.  If so, output some details and return true.
+ * If the lock has an exclusive owner, return that in *ownerp.
+ */
+int
+sx_chain(struct thread *td, struct thread **ownerp)
+{
+	struct sx *sx;
+	struct cv *cv;
+
+	/*
+	 * First, see if it looks like td is blocked on a condition
+	 * variable.
+	 */
+	cv = td->td_wchan;
+	if (cv->cv_description != td->td_wmesg)
+		return (0);
+
+	/*
+	 * Ok, see if it looks like td is blocked on the exclusive
+	 * condition variable.
+	 */
+	sx = (struct sx *)((char *)cv - offsetof(struct sx, sx_excl_cv));
+	if (LOCK_CLASS(&sx->sx_object) == &lock_class_sx &&
+	    sx->sx_excl_wcnt > 0)
+		goto ok;
+
+	/*
+	 * Second, see if it looks like td is blocked on the shared
+	 * condition variable.
+	 */
+	sx = (struct sx *)((char *)cv - offsetof(struct sx, sx_shrd_cv));
+	if (LOCK_CLASS(&sx->sx_object) == &lock_class_sx &&
+	    sx->sx_shrd_wcnt > 0)
+		goto ok;
+
+	/* Doesn't seem to be an sx lock. */
+	return (0);
+
+ok:
+	/* We think we have an sx lock, so output some details. */
+	db_printf("blocked on sx \"%s\" ", td->td_wmesg);
+	if (sx->sx_cnt >= 0) {
+		db_printf("SLOCK (count %d)\n", sx->sx_cnt);
+		*ownerp = NULL;
+	} else {
+		db_printf("XLOCK\n");
+		*ownerp = sx->sx_xholder;
+	}
+	return (1);
+}
 #endif

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_sleepqueue.c#5 (text+ko) ====

@@ -59,11 +59,12 @@
  * variables.
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/kern/subr_sleepqueue.c,v 1.18.2.4 2006/08/17 19:53:06 jhb Exp $");
+
 #include "opt_sleepqueue_profiling.h"
+#include "opt_ddb.h"
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/subr_sleepqueue.c,v 1.18.2.3 2006/04/30 23:22:55 davidxu Exp $");
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
@@ -77,6 +78,10 @@
 #include <sys/sleepqueue.h>
 #include <sys/sysctl.h>
 
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
 /*
  * Constants for the hash table of sleep queue chains.  These constants are
  * the same ones that 4BSD (and possibly earlier versions of BSD) used.
@@ -847,3 +852,62 @@
 	sleepq_remove(td, wchan);
 	mtx_lock_spin(&sched_lock);
 }
+
+#ifdef DDB
+DB_SHOW_COMMAND(sleepq, db_show_sleepqueue)
+{
+	struct sleepqueue_chain *sc;
+	struct sleepqueue *sq;
+#ifdef INVARIANTS
+	struct lock_object *lock;
+#endif
+	struct thread *td;
+	void *wchan;
+	int i;
+
+	if (!have_addr)
+		return;
+
+	/*
+	 * First, see if there is an active sleep queue for the wait channel
+	 * indicated by the address.
+	 */
+	wchan = (void *)addr;
+	sc = SC_LOOKUP(wchan);
+	LIST_FOREACH(sq, &sc->sc_queues, sq_hash)
+		if (sq->sq_wchan == wchan)
+			goto found;
+
+	/*
+	 * Second, see if there is an active sleep queue at the address
+	 * indicated.
+	 */
+	for (i = 0; i < SC_TABLESIZE; i++)
+		LIST_FOREACH(sq, &sleepq_chains[i].sc_queues, sq_hash) {
+			if (sq == (struct sleepqueue *)addr)
+				goto found;
+		}
+
+	db_printf("Unable to locate a sleep queue via %p\n", (void *)addr);
+	return;
+found:
+	db_printf("Wait channel: %p\n", sq->sq_wchan);
+#ifdef INVARIANTS
+	db_printf("Queue type: %d\n", sq->sq_type);
+	if (sq->sq_lock) {
+		lock = &sq->sq_lock->mtx_object;
+		db_printf("Associated Interlock: %p - (%s) %s\n", lock,
+		    LOCK_CLASS(lock)->lc_name, lock->lo_name);
+	}
+#endif
+	db_printf("Blocked threads:\n");
+	if (TAILQ_EMPTY(&sq->sq_blocked))
+		db_printf("\tempty\n");
+	else
+		TAILQ_FOREACH(td, &sq->sq_blocked, td_slpq) {
+			db_printf("\t%p (tid %d, pid %d, \"%s\")\n", td,
+			    td->td_tid, td->td_proc->p_pid,
+			    td->td_proc->p_comm);
+		}	
+}
+#endif

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_turnstile.c#6 (text+ko) ====

@@ -56,11 +56,12 @@
  * it from the hash table.
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/kern/subr_turnstile.c,v 1.152.2.4 2006/08/17 19:53:06 jhb Exp $");
+
+#include "opt_ddb.h"
 #include "opt_turnstile_profiling.h"
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/subr_turnstile.c,v 1.152.2.3 2006/08/01 17:40:13 jhb Exp $");
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -74,6 +75,13 @@
 #include <sys/sysctl.h>
 #include <sys/turnstile.h>
 
+#ifdef DDB
+#include <sys/kdb.h>
+#include <ddb/ddb.h>
+#include <sys/lockmgr.h>
+#include <sys/sx.h>
+#endif
+
 /*
  * Constants for the hash table of turnstile chains.  TC_SHIFT is a magic
  * number chosen because the sleep queue's use the same value for the
@@ -840,6 +848,296 @@
 	return (TAILQ_FIRST(&ts->ts_blocked));
 }
 
+#ifdef DDB
+static int db_pager_quit;
+
+static void
+print_thread(struct thread *td, const char *prefix)
+{
+
+	db_printf("%s%p (tid %d, pid %d, \"%s\")\n", prefix, td, td->td_tid,
+	    td->td_proc->p_pid, td->td_proc->p_comm);
+}
+
+static void
+print_queue(struct threadqueue *queue, const char *header, const char *prefix)
+{
+	struct thread *td;
+
+	db_printf("%s:\n", header);
+	if (TAILQ_EMPTY(queue)) {
+		db_printf("%sempty\n", prefix);
+		return;
+	}
+	TAILQ_FOREACH(td, queue, td_lockq) {
+		print_thread(td, prefix);
+	}
+}
+
+DB_SHOW_COMMAND(turnstile, db_show_turnstile)
+{
+	struct turnstile_chain *tc;
+	struct turnstile *ts;
+	struct lock_object *lock;
+	int i;
+
+	if (!have_addr)
+		return;
+
+	/*
+	 * First, see if there is an active turnstile for the lock indicated
+	 * by the address.
+	 */
+	lock = (struct lock_object *)addr;
+	tc = TC_LOOKUP(lock);
+	LIST_FOREACH(ts, &tc->tc_turnstiles, ts_hash)
+		if (ts->ts_lockobj == lock)
+			goto found;
+
+	/*
+	 * Second, see if there is an active turnstile at the address
+	 * indicated.
+	 */
+	for (i = 0; i < TC_TABLESIZE; i++)
+		LIST_FOREACH(ts, &turnstile_chains[i].tc_turnstiles, ts_hash) {
+			if (ts == (struct turnstile *)addr)
+				goto found;
+		}
+
+	db_printf("Unable to locate a turnstile via %p\n", (void *)addr);
+	return;
+found:
+	db_pager_quit = 0;
+	db_setup_paging(db_simple_pager, &db_pager_quit, db_lines_per_page);
+	lock = ts->ts_lockobj;
+	db_printf("Lock: %p - (%s) %s\n", lock, LOCK_CLASS(lock)->lc_name,
+	    lock->lo_name);
+	if (ts->ts_owner)
+		print_thread(ts->ts_owner, "Lock Owner: ");
+	else
+		db_printf("Lock Owner: none\n");
+	print_queue((struct threadqueue *)&ts->ts_blocked, "Waiters", "\t");
+	print_queue((struct threadqueue *)&ts->ts_pending, "Pending Threads",
+	    "\t");	
+}
+
+/*
+ * Show all the threads a particular thread is waiting on based on
+ * non-sleepable and non-spin locks.
+ */
+static void
+print_lockchain(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.
+	 */
+	while (!db_pager_quit) {
+		db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
+		    td->td_proc->p_pid, 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(lockchain, db_show_lockchain)
+{
+	struct thread *td;
+
+	/* Figure out which thread to start with. */
+	if (have_addr)
+		td = db_lookup_thread(addr, TRUE);
+	else
+		td = kdb_thread;
+
+	db_pager_quit = 0;
+	db_setup_paging(db_simple_pager, &db_pager_quit, db_lines_per_page);
+	print_lockchain(td, "");
+}
+
+DB_SHOW_COMMAND(allchains, db_show_allchains)
+{
+	struct thread *td;
+	struct proc *p;
+	int i;
+
+	i = 1;
+	db_pager_quit = 0;
+	db_setup_paging(db_simple_pager, &db_pager_quit, db_lines_per_page);
+	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_lockchain(td, " ");
+			}
+			if (db_pager_quit)
+				return;
+		}
+	}
+}
+
+/*
+ * Show all the threads a particular thread is waiting on based on
+ * sleepable locks.
+ */
+static void
+print_sleepchain(struct thread *td, const char *prefix)
+{
+	struct thread *owner;
+
+	/*
+	 * Follow the chain.  We keep walking as long as the thread is
+	 * blocked on a sleep lock that has an owner.
+	 */
+	while (!db_pager_quit) {
+		db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
+		    td->td_proc->p_pid, 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_SLEEPQ(td)) {
+				if (lockmgr_chain(td, &owner) ||
+				    sx_chain(td, &owner)) {
+					if (owner == NULL)
+						return;
+					td = owner;
+					break;
+				}
+				db_printf("sleeping on %p \"%s\"\n",
+				    td->td_wchan, td->td_wmesg);
+				return;
+			}
+			db_printf("inhibited\n");
+			return;
+		default:
+			db_printf("??? (%#x)\n", td->td_state);
+			return;
+		}
+	}
+}
+
+DB_SHOW_COMMAND(sleepchain, db_show_sleepchain)
+{
+	struct thread *td;
+
+	/* Figure out which thread to start with. */
+	if (have_addr)
+		td = db_lookup_thread(addr, TRUE);
+	else
+		td = kdb_thread;
+
+	db_pager_quit = 0;
+	db_setup_paging(db_simple_pager, &db_pager_quit, db_lines_per_page);
+	print_sleepchain(td, "");
+}
+
+static void	print_waiters(struct turnstile *ts, int indent);
+	
+static void
+print_waiter(struct thread *td, int indent)
+{
+	struct turnstile *ts;
+	int i;
+
+	if (db_pager_quit)
+		return;
+	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;
+
+	if (db_pager_quit)
+		return;
+	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, td_lockq)
+		print_waiter(td, indent + 1);
+	TAILQ_FOREACH(td, &ts->ts_pending, td_lockq)
+		print_waiter(td, indent + 1);
+}
+
+DB_SHOW_COMMAND(locktree, db_show_locktree)
+{
+	struct lock_object *lock;
+	struct lock_class *class;
+	struct turnstile_chain *tc;
+	struct turnstile *ts;
+
+	if (!have_addr)
+		return;
+	db_pager_quit = 0;
+	db_setup_paging(db_simple_pager, &db_pager_quit, db_lines_per_page);
+	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
+
 /*
  * Returns true if a turnstile is empty.
  */

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_syscalls.c#6 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.221.2.2 2006/05/15 18:34:05 ps Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.221.2.3 2006/08/15 18:48:51 alc Exp $");
 
 #include "opt_compat.h"
 #include "opt_ktrace.h"
@@ -1798,15 +1798,16 @@
     struct uio *hdr_uio, struct uio *trl_uio, int compat)
 {
 	struct vnode *vp;
-	struct vm_object *obj;
+	struct vm_object *obj = NULL;
 	struct socket *so = NULL;
 	struct mbuf *m, *m_header = NULL;
 	struct sf_buf *sf;
 	struct vm_page *pg;
 	off_t off, xfsize, hdtr_size, sbytes = 0;
 	int error, headersize = 0, headersent = 0;
+	int vfslocked;
 
-	mtx_lock(&Giant);
+	NET_LOCK_GIANT();
 
 	hdtr_size = 0;
 
@@ -1815,9 +1816,26 @@
 	 */
 	if ((error = fgetvp_read(td, uap->fd, &vp)) != 0)
 		goto done;
+	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 	obj = vp->v_object;
+	if (obj != NULL) {
+		/*
+		 * Temporarily increase the backing VM object's reference
+		 * count so that a forced reclamation of its vnode does not
+		 * immediately destroy it.
+		 */
+		VM_OBJECT_LOCK(obj);
+		if ((obj->flags & OBJ_DEAD) == 0) {
+			vm_object_reference_locked(obj);
+			VM_OBJECT_UNLOCK(obj);
+		} else {
+			VM_OBJECT_UNLOCK(obj);
+			obj = NULL;
+		}
+	}
 	VOP_UNLOCK(vp, 0, td);
+	VFS_UNLOCK_GIANT(vfslocked);
 	if (obj == NULL) {
 		error = EINVAL;
 		goto done;
@@ -1973,6 +1991,7 @@
 			 * Get the page from backing store.
 			 */
 			bsize = vp->v_mount->mnt_stat.f_iosize;
+			vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 			vn_lock(vp, LK_SHARED | LK_RETRY, td);
 			/*
 			 * XXXMAC: Because we don't have fp->f_cred here,
@@ -1984,6 +2003,7 @@
 			    IO_VMIO | ((MAXBSIZE / bsize) << IO_SEQSHIFT),
 			    td->td_ucred, NOCRED, &resid, td);
 			VOP_UNLOCK(vp, 0, td);
+			VFS_UNLOCK_GIANT(vfslocked);
 			VM_OBJECT_LOCK(obj);
 			vm_page_lock_queues();
 			vm_page_io_finish(pg);
@@ -2163,14 +2183,19 @@
 			sbytes += hdtr_size;
 		copyout(&sbytes, uap->sbytes, sizeof(off_t));
 	}
-	if (vp)
+	if (obj != NULL)
+		vm_object_deallocate(obj);
+	if (vp != NULL) {
+		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 		vrele(vp);
+		VFS_UNLOCK_GIANT(vfslocked);
+	}
 	if (so)
 		fputsock(so);
 	if (m_header)
 		m_freem(m_header);
 
-	mtx_unlock(&Giant);
+	NET_UNLOCK_GIANT();
 
 	if (error == ERESTART)
 		error = EINTR;

==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_lookup.c#5 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/vfs_lookup.c,v 1.80.2.7 2006/04/30 03:57:46 kris Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/vfs_lookup.c,v 1.80.2.8 2006/08/18 14:03:29 rwatson Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_mac.h"
@@ -86,7 +86,7 @@
     "Enables/Disables shared locks for path name translation");
 
 /*
- * Convert a pathname into a pointer to a locked inode.
+ * Convert a pathname into a pointer to a locked vnode.
  *
  * The FOLLOW flag is set when symbolic links are to be followed
  * when they occur at the end of the name translation process.
@@ -593,7 +593,7 @@
 		/*
 		 * We return with ni_vp NULL to indicate that the entry
 		 * doesn't currently exist, leaving a pointer to the
-		 * (possibly locked) directory inode in ndp->ni_dvp.
+		 * (possibly locked) directory vnode in ndp->ni_dvp.
 		 */
 		if (cnp->cn_flags & SAVESTART) {
 			ndp->ni_startdir = ndp->ni_dvp;
@@ -840,7 +840,7 @@
 		/*
 		 * We return with ni_vp NULL to indicate that the entry
 		 * doesn't currently exist, leaving a pointer to the
-		 * (possibly locked) directory inode in ndp->ni_dvp.
+		 * (possibly locked) directory vnode in ndp->ni_dvp.
 		 */
 		return (0);
 	}

==== //depot/projects/soc2006/cdjones_jail/src/sys/sys/lockmgr.h#5 (text+ko) ====

@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)lock.h	8.12 (Berkeley) 5/19/95
- * $FreeBSD: src/sys/sys/lockmgr.h,v 1.47.2.1 2006/03/13 03:07:09 jeff Exp $
+ * $FreeBSD: src/sys/sys/lockmgr.h,v 1.47.2.2 2006/08/17 19:53:06 jhb Exp $
  */
 
 #ifndef	_SYS_LOCKMGR_H_
@@ -203,5 +203,8 @@
 void	lockmgr_printinfo(struct lock *);
 int	lockstatus(struct lock *, struct thread *);
 int	lockcount(struct lock *);
+#ifdef DDB
+int	lockmgr_chain(struct thread *td, struct thread **ownerp);
+#endif
 
 #endif /* !_SYS_LOCKMGR_H_ */

==== //depot/projects/soc2006/cdjones_jail/src/sys/sys/sx.h#5 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  *
- * $FreeBSD: src/sys/sys/sx.h,v 1.21.2.1 2005/09/21 21:05:19 jhb Exp $
+ * $FreeBSD: src/sys/sys/sx.h,v 1.21.2.2 2006/08/17 19:53:06 jhb Exp $
  */
 
 #ifndef	_SYS_SX_H_
@@ -60,6 +60,9 @@
 #ifdef INVARIANT_SUPPORT
 void	_sx_assert(struct sx *sx, int what, const char *file, int line);
 #endif
+#ifdef DDB
+int	sx_chain(struct thread *td, struct thread **ownerp);
+#endif
 
 struct sx_args {
 	struct sx 	*sa_sx;

==== //depot/projects/soc2006/cdjones_jail/src/sys/vm/vm_object.c#2 (text+ko) ====

@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/vm/vm_object.c,v 1.349.2.4 2006/03/13 03:08:21 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/vm/vm_object.c,v 1.349.2.5 2006/08/15 17:51:02 alc Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -517,8 +517,11 @@
 						VM_OBJECT_UNLOCK(object);
 						vm_object_pip_wait(robject,
 						    "objde1");
-						VM_OBJECT_LOCK(object);
-						goto retry;
+						temp = robject->backing_object;
+						if (object == temp) {
+							VM_OBJECT_LOCK(object);
+							goto retry;
+						}
 					} else if (object->paging_in_progress) {
 						VM_OBJECT_UNLOCK(robject);
 						object->flags |= OBJ_PIPWNT;
@@ -526,10 +529,14 @@
 						    VM_OBJECT_MTX(object),
 						    PDROP | PVM, "objde2", 0);
 						VM_OBJECT_LOCK(robject);
-						VM_OBJECT_LOCK(object);
-						goto retry;
-					}
-					VM_OBJECT_UNLOCK(object);
+						temp = robject->backing_object;
+						if (object == temp) {
+							VM_OBJECT_LOCK(object);
+							goto retry;
+						}
+					} else
+						VM_OBJECT_UNLOCK(object);
+
 					if (robject->ref_count == 1) {
 						robject->ref_count--;
 						object = robject;



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