PERFORCE change 104654 for review
Chris Jones
cdjones at FreeBSD.org
Mon Aug 21 06:53:07 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=104654
Change 104654 by cdjones at 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;
More information about the p4-projects
mailing list