From owner-p4-projects@FreeBSD.ORG Mon Aug 21 06:53:07 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 78AE416A4E5; Mon, 21 Aug 2006 06:53:07 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E769816A4DA for ; Mon, 21 Aug 2006 06:53:06 +0000 (UTC) (envelope-from cdjones@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 673D143D6E for ; Mon, 21 Aug 2006 06:53:00 +0000 (GMT) (envelope-from cdjones@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k7L6r0vA032833 for ; Mon, 21 Aug 2006 06:53:00 GMT (envelope-from cdjones@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7L6qx0c032830 for perforce@freebsd.org; Mon, 21 Aug 2006 06:52:59 GMT (envelope-from cdjones@FreeBSD.org) Date: Mon, 21 Aug 2006 06:52:59 GMT Message-Id: <200608210652.k7L6qx0c032830@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to cdjones@FreeBSD.org using -f From: Chris Jones To: Perforce Change Reviews Cc: Subject: PERFORCE change 104654 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Aug 2006 06:53:07 -0000 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 -__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 #include @@ -56,6 +58,10 @@ #include #endif +#ifdef DDB +#include +#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 -__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 #include +#ifdef DDB #include -#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 +__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 -__FBSDID("$FreeBSD: src/sys/kern/subr_sleepqueue.c,v 1.18.2.3 2006/04/30 23:22:55 davidxu Exp $"); - #include #include #include @@ -77,6 +78,10 @@ #include #include +#ifdef DDB +#include +#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 +__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 -__FBSDID("$FreeBSD: src/sys/kern/subr_turnstile.c,v 1.152.2.3 2006/08/01 17:40:13 jhb Exp $"); - #include #include #include @@ -74,6 +75,13 @@ #include #include +#ifdef DDB +#include +#include +#include +#include +#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 -__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 -__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 -__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 #include @@ -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;