From owner-svn-src-releng@FreeBSD.ORG Mon Apr 15 05:50:10 2013 Return-Path: Delivered-To: svn-src-releng@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 586BC2B9; Mon, 15 Apr 2013 05:50:10 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 2EF0B38D; Mon, 15 Apr 2013 05:50:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3F5oApw090809; Mon, 15 Apr 2013 05:50:10 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3F5oAsp090808; Mon, 15 Apr 2013 05:50:10 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <201304150550.r3F5oAsp090808@svn.freebsd.org> From: Xin LI Date: Mon, 15 Apr 2013 05:50:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r249501 - releng/8.4/release/doc/en_US.ISO8859-1/hardware X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Apr 2013 05:50:10 -0000 Author: delphij Date: Mon Apr 15 05:50:09 2013 New Revision: 249501 URL: http://svnweb.freebsd.org/changeset/base/249501 Log: MFS r249495: Fix a few typos. Reviewed by: gjb Approved by: re (hrs) Modified: releng/8.4/release/doc/en_US.ISO8859-1/hardware/article.xml Directory Properties: releng/8.4/release/doc/en_US.ISO8859-1/hardware/ (props changed) Modified: releng/8.4/release/doc/en_US.ISO8859-1/hardware/article.xml ============================================================================== --- releng/8.4/release/doc/en_US.ISO8859-1/hardware/article.xml Mon Apr 15 05:39:21 2013 (r249500) +++ releng/8.4/release/doc/en_US.ISO8859-1/hardware/article.xml Mon Apr 15 05:50:09 2013 (r249501) @@ -171,7 +171,7 @@ There is a wide variety of motherboards available for this architecture. Motherboards using the ISA, VLB, EISA, AGP, and - PCI expansion busses are well-supported. There is some + PCI expansion buses are well-supported. There is some limited support for the MCA (MicroChannel) expansion bus used in the IBM PS/2 line of PCs. @@ -202,7 +202,7 @@ memory above 4 gigabytes and allow it to be used by the system. This feature places constraints on the device drivers and other features of &os; which may be used; consult the - &man.pae.4; manpage for more details. + &man.pae.4; manual page for more details. &os; will generally run on i386-based laptops, albeit with varying levels of support for certain hardware features such @@ -480,7 +480,7 @@ The following systems are partially supported by &os;. In - particular the fibre channel controllers in SBus-based systems are not + particular the fiber channel controllers in SBus-based systems are not supported. However, it is possible to use these with a SCSI controller supported by the &man.esp.4 driver (Sun ESP SCSI, Sun FAS Fast-SCSI and Sun FAS366 Fast-Wide SCSI controllers). From owner-svn-src-releng@FreeBSD.ORG Mon Apr 15 19:45:11 2013 Return-Path: Delivered-To: svn-src-releng@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id B9F07142; Mon, 15 Apr 2013 19:45:11 +0000 (UTC) (envelope-from smh@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 9CC51168A; Mon, 15 Apr 2013 19:45:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3FJjB3C046465; Mon, 15 Apr 2013 19:45:11 GMT (envelope-from smh@svn.freebsd.org) Received: (from smh@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3FJj9nW046455; Mon, 15 Apr 2013 19:45:09 GMT (envelope-from smh@svn.freebsd.org) Message-Id: <201304151945.r3FJj9nW046455@svn.freebsd.org> From: Steven Hartland Date: Mon, 15 Apr 2013 19:45:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r249524 - in releng/8.4/sys: cddl/contrib/opensolaris/uts/common/fs/zfs cddl/contrib/opensolaris/uts/common/fs/zfs/sys kern sys X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Apr 2013 19:45:11 -0000 Author: smh Date: Mon Apr 15 19:45:09 2013 New Revision: 249524 URL: http://svnweb.freebsd.org/changeset/base/249524 Log: MFC three change sets (details below) which fix system shutdown and reboots hanging at "All buffers synced" when using ZFS. MFC r241556: Add a KPI to allow to reserve some amount of space in the numvnodes counter, without actually allocating the vnodes. For KBI stability, the td_vp_reserv was moved to the end of struct thread MFC r241628: zfs: make use of getnewvnode_reserve in zfs_mknode and zfs_zget MFC r243520, r243521: zfs: overhaul zfs-vfs glue for vnode life-cycle management Reviewed by: avg Approved by: re (jpaetzel), avg (co-mentor) Modified: releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c releng/8.4/sys/kern/kern_thread.c releng/8.4/sys/kern/subr_trap.c releng/8.4/sys/kern/vfs_subr.c releng/8.4/sys/sys/proc.h releng/8.4/sys/sys/vnode.h Directory Properties: releng/8.4/sys/ (props changed) releng/8.4/sys/cddl/ (props changed) releng/8.4/sys/cddl/contrib/opensolaris/ (props changed) releng/8.4/sys/kern/ (props changed) releng/8.4/sys/sys/ (props changed) Modified: releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h ============================================================================== --- releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h Mon Apr 15 19:45:09 2013 (r249524) @@ -207,8 +207,6 @@ typedef struct znode { list_node_t z_link_node; /* all znodes in fs link */ sa_handle_t *z_sa_hdl; /* handle to sa data */ boolean_t z_is_sa; /* are we native sa? */ - /* FreeBSD-specific field. */ - struct task z_task; } znode_t; Modified: releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c ============================================================================== --- releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Mon Apr 15 19:45:09 2013 (r249524) @@ -1844,18 +1844,6 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolea zfsvfs->z_unmounted = B_TRUE; rrw_exit(&zfsvfs->z_teardown_lock, FTAG); rw_exit(&zfsvfs->z_teardown_inactive_lock); - -#ifdef __FreeBSD__ - /* - * Some znodes might not be fully reclaimed, wait for them. - */ - mutex_enter(&zfsvfs->z_znodes_lock); - while (list_head(&zfsvfs->z_all_znodes) != NULL) { - msleep(zfsvfs, &zfsvfs->z_znodes_lock, 0, - "zteardown", 0); - } - mutex_exit(&zfsvfs->z_znodes_lock); -#endif } /* Modified: releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Mon Apr 15 19:45:09 2013 (r249524) @@ -4579,14 +4579,22 @@ zfs_inactive(vnode_t *vp, cred_t *cr, ca * The fs has been unmounted, or we did a * suspend/resume and this file no longer exists. */ - VI_LOCK(vp); - ASSERT(vp->v_count <= 1); - vp->v_count = 0; - VI_UNLOCK(vp); + rw_exit(&zfsvfs->z_teardown_inactive_lock); vrecycle(vp, curthread); + return; + } + + mutex_enter(&zp->z_lock); + if (zp->z_unlinked) { + /* + * Fast path to recycle a vnode of a removed file. + */ + mutex_exit(&zp->z_lock); rw_exit(&zfsvfs->z_teardown_inactive_lock); + vrecycle(vp, curthread); return; } + mutex_exit(&zp->z_lock); if (zp->z_atime_dirty && zp->z_unlinked == 0) { dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os); @@ -4605,8 +4613,6 @@ zfs_inactive(vnode_t *vp, cred_t *cr, ca dmu_tx_commit(tx); } } - - zfs_zinactive(zp); rw_exit(&zfsvfs->z_teardown_inactive_lock); } @@ -6116,28 +6122,6 @@ zfs_freebsd_inactive(ap) return (0); } -static void -zfs_reclaim_complete(void *arg, int pending) -{ - znode_t *zp = arg; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - - rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER); - if (zp->z_sa_hdl != NULL) { - ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id); - zfs_znode_dmu_fini(zp); - ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id); - } - zfs_znode_free(zp); - rw_exit(&zfsvfs->z_teardown_inactive_lock); - /* - * If the file system is being unmounted, there is a process waiting - * for us, wake it up. - */ - if (zfsvfs->z_unmounted) - wakeup_one(zfsvfs); -} - static int zfs_freebsd_reclaim(ap) struct vop_reclaim_args /* { @@ -6148,53 +6132,25 @@ zfs_freebsd_reclaim(ap) vnode_t *vp = ap->a_vp; znode_t *zp = VTOZ(vp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; - boolean_t rlocked; - - rlocked = rw_tryenter(&zfsvfs->z_teardown_inactive_lock, RW_READER); ASSERT(zp != NULL); - /* - * Destroy the vm object and flush associated pages. - */ + /* Destroy the vm object and flush associated pages. */ vnode_destroy_vobject(vp); - mutex_enter(&zp->z_lock); - zp->z_vnode = NULL; - mutex_exit(&zp->z_lock); - - if (zp->z_unlinked) { - ; /* Do nothing. */ - } else if (!rlocked) { - TASK_INIT(&zp->z_task, 0, zfs_reclaim_complete, zp); - taskqueue_enqueue(taskqueue_thread, &zp->z_task); - } else if (zp->z_sa_hdl == NULL) { + /* + * z_teardown_inactive_lock protects from a race with + * zfs_znode_dmu_fini in zfsvfs_teardown during + * force unmount. + */ + rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER); + if (zp->z_sa_hdl == NULL) zfs_znode_free(zp); - } else /* if (!zp->z_unlinked && zp->z_dbuf != NULL) */ { - int locked; + else + zfs_zinactive(zp); + rw_exit(&zfsvfs->z_teardown_inactive_lock); - locked = MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)) ? 2 : - ZFS_OBJ_HOLD_TRYENTER(zfsvfs, zp->z_id); - if (locked == 0) { - /* - * Lock can't be obtained due to deadlock possibility, - * so defer znode destruction. - */ - TASK_INIT(&zp->z_task, 0, zfs_reclaim_complete, zp); - taskqueue_enqueue(taskqueue_thread, &zp->z_task); - } else { - zfs_znode_dmu_fini(zp); - if (locked == 1) - ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id); - zfs_znode_free(zp); - } - } - VI_LOCK(vp); vp->v_data = NULL; - ASSERT(vp->v_holdcnt >= 1); - VI_UNLOCK(vp); - if (rlocked) - rw_exit(&zfsvfs->z_teardown_inactive_lock); return (0); } Modified: releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c ============================================================================== --- releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Mon Apr 15 19:45:09 2013 (r249524) @@ -855,6 +855,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d } } + getnewvnode_reserve(1); ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); VERIFY(0 == sa_buf_hold(zfsvfs->z_os, obj, NULL, &db)); @@ -1041,6 +1042,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d KASSERT(err == 0, ("insmntque() failed: error %d", err)); } ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); + getnewvnode_drop_reserve(); } /* @@ -1145,18 +1147,22 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_ dmu_object_info_t doi; dmu_buf_t *db; znode_t *zp; - int err; + vnode_t *vp; sa_handle_t *hdl; - int first = 1; - - *zpp = NULL; + struct thread *td; + int locked; + int err; + td = curthread; + getnewvnode_reserve(1); again: + *zpp = NULL; ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); if (err) { ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + getnewvnode_drop_reserve(); return (err); } @@ -1167,6 +1173,7 @@ again: doi.doi_bonus_size < sizeof (znode_phys_t)))) { sa_buf_rele(db, NULL); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + getnewvnode_drop_reserve(); return (EINVAL); } @@ -1188,48 +1195,39 @@ again: if (zp->z_unlinked) { err = ENOENT; } else { - vnode_t *vp; - int dying = 0; - vp = ZTOV(zp); - if (vp == NULL) - dying = 1; - else { - VN_HOLD(vp); - if ((vp->v_iflag & VI_DOOMED) != 0) { - dying = 1; - /* - * Don't VN_RELE() vnode here, because - * it can call vn_lock() which creates - * LOR between vnode lock and znode - * lock. We will VN_RELE() the vnode - * after droping znode lock. - */ - } - } - if (dying) { - if (first) { - ZFS_LOG(1, "dying znode detected (zp=%p)", zp); - first = 0; - } - /* - * znode is dying so we can't reuse it, we must - * wait until destruction is completed. - */ - sa_buf_rele(db, NULL); - mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - if (vp != NULL) - VN_RELE(vp); - tsleep(zp, 0, "zcollide", 1); - goto again; - } *zpp = zp; err = 0; } sa_buf_rele(db, NULL); + + /* Don't let the vnode disappear after ZFS_OBJ_HOLD_EXIT. */ + if (err == 0) + VN_HOLD(vp); + mutex_exit(&zp->z_lock); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + + if (err == 0) { + locked = VOP_ISLOCKED(vp); + VI_LOCK(vp); + if ((vp->v_iflag & VI_DOOMED) != 0 && + locked != LK_EXCLUSIVE) { + /* + * The vnode is doomed and this thread doesn't + * hold the exclusive lock on it, so the vnode + * must be being reclaimed by another thread. + * Otherwise the doomed vnode is being reclaimed + * by this thread and zfs_zget is called from + * ZIL internals. + */ + VI_UNLOCK(vp); + VN_RELE(vp); + goto again; + } + VI_UNLOCK(vp); + } + getnewvnode_drop_reserve(); return (err); } @@ -1265,6 +1263,7 @@ again: } } ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + getnewvnode_drop_reserve(); return (err); } @@ -1393,10 +1392,8 @@ zfs_znode_delete(znode_t *zp, dmu_tx_t * void zfs_zinactive(znode_t *zp) { - vnode_t *vp = ZTOV(zp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; uint64_t z_id = zp->z_id; - int vfslocked; ASSERT(zp->z_sa_hdl); @@ -1406,19 +1403,6 @@ zfs_zinactive(znode_t *zp) ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id); mutex_enter(&zp->z_lock); - VI_LOCK(vp); - if (vp->v_count > 0) { - /* - * If the hold count is greater than zero, somebody has - * obtained a new reference on this znode while we were - * processing it here, so we are done. - */ - VI_UNLOCK(vp); - mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); - return; - } - VI_UNLOCK(vp); /* * If this was the last reference to a file with no links, @@ -1427,16 +1411,14 @@ zfs_zinactive(znode_t *zp) if (zp->z_unlinked) { mutex_exit(&zp->z_lock); ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); - ASSERT(vp->v_count == 0); - vrecycle(vp, curthread); - vfslocked = VFS_LOCK_GIANT(zfsvfs->z_vfs); zfs_rmnode(zp); - VFS_UNLOCK_GIANT(vfslocked); return; } mutex_exit(&zp->z_lock); + zfs_znode_dmu_fini(zp); ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); + zfs_znode_free(zp); } void @@ -1444,8 +1426,8 @@ zfs_znode_free(znode_t *zp) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; - ASSERT(ZTOV(zp) == NULL); ASSERT(zp->z_sa_hdl == NULL); + zp->z_vnode = NULL; mutex_enter(&zfsvfs->z_znodes_lock); POINTER_INVALIDATE(&zp->z_zfsvfs); list_remove(&zfsvfs->z_all_znodes, zp); Modified: releng/8.4/sys/kern/kern_thread.c ============================================================================== --- releng/8.4/sys/kern/kern_thread.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/kern/kern_thread.c Mon Apr 15 19:45:09 2013 (r249524) @@ -159,6 +159,7 @@ thread_init(void *mem, int size, int fla td->td_sleepqueue = sleepq_alloc(); td->td_turnstile = turnstile_alloc(); + td->td_vp_reserv = 0; EVENTHANDLER_INVOKE(thread_init, td); td->td_sched = (struct td_sched *)&td[1]; umtx_thread_init(td); Modified: releng/8.4/sys/kern/subr_trap.c ============================================================================== --- releng/8.4/sys/kern/subr_trap.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/kern/subr_trap.c Mon Apr 15 19:45:09 2013 (r249524) @@ -132,6 +132,8 @@ userret(struct thread *td, struct trapfr sched_userret(td); KASSERT(td->td_locks == 0, ("userret: Returning with %d locks held.", td->td_locks)); + KASSERT(td->td_vp_reserv == 0, + ("userret: Returning while holding vnode reservation")); #ifdef VIMAGE /* Unfortunately td_vnet_lpush needs VNET_DEBUG. */ VNET_ASSERT(curvnet == NULL, Modified: releng/8.4/sys/kern/vfs_subr.c ============================================================================== --- releng/8.4/sys/kern/vfs_subr.c Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/kern/vfs_subr.c Mon Apr 15 19:45:09 2013 (r249524) @@ -977,34 +977,22 @@ vtryrecycle(struct vnode *vp) } /* - * Return the next vnode from the free list. + * Wait for available vnodes. */ -int -getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, - struct vnode **vpp) +static int +getnewvnode_wait(int suspended) { - struct vnode *vp = NULL; - struct bufobj *bo; - CTR3(KTR_VFS, "%s: mp %p with tag %s", __func__, mp, tag); - mtx_lock(&vnode_free_list_mtx); - /* - * Lend our context to reclaim vnodes if they've exceeded the max. - */ - if (freevnodes > wantfreevnodes) - vnlru_free(1); - /* - * Wait for available vnodes. - */ + mtx_assert(&vnode_free_list_mtx, MA_OWNED); if (numvnodes > desiredvnodes) { - if (mp != NULL && (mp->mnt_kern_flag & MNTK_SUSPEND)) { + if (suspended) { /* * File system is beeing suspended, we cannot risk a * deadlock here, so allocate new vnode anyway. */ if (freevnodes > wantfreevnodes) vnlru_free(freevnodes - wantfreevnodes); - goto alloc; + return (0); } if (vnlruproc_sig == 0) { vnlruproc_sig = 1; /* avoid unnecessary wakeups */ @@ -1012,16 +1000,76 @@ getnewvnode(const char *tag, struct moun } msleep(&vnlruproc_sig, &vnode_free_list_mtx, PVFS, "vlruwk", hz); -#if 0 /* XXX Not all VFS_VGET/ffs_vget callers check returns. */ - if (numvnodes > desiredvnodes) { - mtx_unlock(&vnode_free_list_mtx); - return (ENFILE); + } + return (numvnodes > desiredvnodes ? ENFILE : 0); +} + +void +getnewvnode_reserve(u_int count) +{ + struct thread *td; + + td = curthread; + mtx_lock(&vnode_free_list_mtx); + while (count > 0) { + if (getnewvnode_wait(0) == 0) { + count--; + td->td_vp_reserv++; + numvnodes++; } -#endif } -alloc: + mtx_unlock(&vnode_free_list_mtx); +} + +void +getnewvnode_drop_reserve(void) +{ + struct thread *td; + + td = curthread; + mtx_lock(&vnode_free_list_mtx); + KASSERT(numvnodes >= td->td_vp_reserv, ("reserve too large")); + numvnodes -= td->td_vp_reserv; + mtx_unlock(&vnode_free_list_mtx); + td->td_vp_reserv = 0; +} + +/* + * Return the next vnode from the free list. + */ +int +getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, + struct vnode **vpp) +{ + struct vnode *vp; + struct bufobj *bo; + struct thread *td; + int error; + + CTR3(KTR_VFS, "%s: mp %p with tag %s", __func__, mp, tag); + vp = NULL; + td = curthread; + if (td->td_vp_reserv > 0) { + td->td_vp_reserv -= 1; + goto alloc; + } + mtx_lock(&vnode_free_list_mtx); + /* + * Lend our context to reclaim vnodes if they've exceeded the max. + */ + if (freevnodes > wantfreevnodes) + vnlru_free(1); + error = getnewvnode_wait(mp != NULL && (mp->mnt_kern_flag & + MNTK_SUSPEND)); +#if 0 /* XXX Not all VFS_VGET/ffs_vget callers check returns. */ + if (error != 0) { + mtx_unlock(&vnode_free_list_mtx); + return (error); + } +#endif numvnodes++; mtx_unlock(&vnode_free_list_mtx); +alloc: vp = (struct vnode *) uma_zalloc(vnode_zone, M_WAITOK|M_ZERO); /* * Setup locks. Modified: releng/8.4/sys/sys/proc.h ============================================================================== --- releng/8.4/sys/sys/proc.h Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/sys/proc.h Mon Apr 15 19:45:09 2013 (r249524) @@ -308,6 +308,7 @@ struct thread { struct rusage_ext td_rux; /* (t) Internal rusage information. */ struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */ pid_t td_dbg_forked; /* (c) Child pid for debugger. */ + u_int td_vp_reserv; /* (k) Count of reserved vnodes. */ }; struct mtx *thread_lock_block(struct thread *); Modified: releng/8.4/sys/sys/vnode.h ============================================================================== --- releng/8.4/sys/sys/vnode.h Mon Apr 15 19:32:14 2013 (r249523) +++ releng/8.4/sys/sys/vnode.h Mon Apr 15 19:45:09 2013 (r249524) @@ -604,6 +604,8 @@ void cvtstat(struct stat *st, struct ost void cvtnstat(struct stat *sb, struct nstat *nsb); int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, struct vnode **vpp); +void getnewvnode_reserve(u_int count); +void getnewvnode_drop_reserve(void); int insmntque1(struct vnode *vp, struct mount *mp, void (*dtr)(struct vnode *, void *), void *dtr_arg); int insmntque(struct vnode *vp, struct mount *mp); From owner-svn-src-releng@FreeBSD.ORG Fri Apr 19 21:08:57 2013 Return-Path: Delivered-To: svn-src-releng@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 30799BC0; Fri, 19 Apr 2013 21:08:57 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 22F9E1EBA; Fri, 19 Apr 2013 21:08:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3JL8v5f018543; Fri, 19 Apr 2013 21:08:57 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3JL8uZF018536; Fri, 19 Apr 2013 21:08:56 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <201304192108.r3JL8uZF018536@svn.freebsd.org> From: Robert Watson Date: Fri, 19 Apr 2013 21:08:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r249660 - in releng/8.4/sys: netinet netinet6 X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Apr 2013 21:08:57 -0000 Author: rwatson Date: Fri Apr 19 21:08:56 2013 New Revision: 249660 URL: http://svnweb.freebsd.org/changeset/base/249660 Log: Merge r249478 from stable/8 to releng/8.4: FreeBSD 8.0 introduced inpcb reference counting, and FreeBSD 8.1 began using that reference count to protect inpcb stability in udp_pcblist() and other monitoring functions, preventing the inpcb from being garbage collected across potentially sleeping copyout() operations despite the inpcb zone becoming shrinkable. However, this introduced a race condition in which inp->inp_socket() might become NULL as a result of the socket being freed, but before the inpcb we removed from the global list of connections, allowing it to be exposed to a third thread invoking udp_input() or udp6_input() which would try to indirect through inp_socket without testing it for NULL. This might occur with particular regularity on systems that frequently run netstat, or which use SNMP for connection monitoring. Later FreeBSD releases use a different reference/destruction model, but stable/8 remained affected in FreeBSD 8.2 and 8.3; the problem could be spotted on very high-load UDP services, such as top-level name servers. An Errata Note for 8.x branches under continuing support might be appropriate. Regardless, this fix should be merged to releng/8.4 prior to 8.4-RELEASE. PR: 172963 Submitted by: Vincent Miller Submitted by: Julien Charbon Submitted by: Marc De La Gueronniere Approved by: re (rodrigc) Modified: releng/8.4/sys/netinet/udp_usrreq.c releng/8.4/sys/netinet6/udp6_usrreq.c Directory Properties: releng/8.4/sys/ (props changed) releng/8.4/sys/netinet/ (props changed) releng/8.4/sys/netinet6/ (props changed) Modified: releng/8.4/sys/netinet/udp_usrreq.c ============================================================================== --- releng/8.4/sys/netinet/udp_usrreq.c Fri Apr 19 21:08:21 2013 (r249659) +++ releng/8.4/sys/netinet/udp_usrreq.c Fri Apr 19 21:08:56 2013 (r249660) @@ -495,6 +495,15 @@ udp_input(struct mbuf *m, int off) INP_RLOCK(inp); /* + * Detached PCBs can linger in the list if someone + * holds a reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + continue; + } + + /* * Handle socket delivery policy for any-source * and source-specific multicast. [RFC3678] */ @@ -620,6 +629,15 @@ udp_input(struct mbuf *m, int off) */ INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); + + /* + * Detached PCBs can linger in the hash table if someone holds a + * reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + goto badunlocked; + } if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl) { INP_RUNLOCK(inp); goto badunlocked; Modified: releng/8.4/sys/netinet6/udp6_usrreq.c ============================================================================== --- releng/8.4/sys/netinet6/udp6_usrreq.c Fri Apr 19 21:08:21 2013 (r249659) +++ releng/8.4/sys/netinet6/udp6_usrreq.c Fri Apr 19 21:08:56 2013 (r249660) @@ -273,6 +273,13 @@ udp6_input(struct mbuf **mp, int *offp, } /* + * Detached PCBs can linger in the list if someone + * holds a reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) + continue; + + /* * Handle socket delivery policy for any-source * and source-specific multicast. [RFC3678] */ @@ -396,6 +403,15 @@ udp6_input(struct mbuf **mp, int *offp, } INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); + + /* + * Detached PCBs can linger in the hash table if someone holds a + * reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + goto badunlocked; + } up = intoudpcb(inp); if (up->u_tun_func == NULL) { udp6_append(inp, m, off, &fromsa); From owner-svn-src-releng@FreeBSD.ORG Sat Apr 20 19:13:56 2013 Return-Path: Delivered-To: svn-src-releng@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id EFC916D8; Sat, 20 Apr 2013 19:13:56 +0000 (UTC) (envelope-from gjb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id E2CE1AF7; Sat, 20 Apr 2013 19:13:56 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3KJDu6t039897; Sat, 20 Apr 2013 19:13:56 GMT (envelope-from gjb@svn.freebsd.org) Received: (from gjb@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3KJDuIG039896; Sat, 20 Apr 2013 19:13:56 GMT (envelope-from gjb@svn.freebsd.org) Message-Id: <201304201913.r3KJDuIG039896@svn.freebsd.org> From: Glen Barber Date: Sat, 20 Apr 2013 19:13:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r249710 - releng/8.4/sys/conf X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Apr 2013 19:13:57 -0000 Author: gjb (doc,ports committer) Date: Sat Apr 20 19:13:56 2013 New Revision: 249710 URL: http://svnweb.freebsd.org/changeset/base/249710 Log: - Update releng/8.4 branch to -RC2 Approved by: re (jpaetzel) Modified: releng/8.4/sys/conf/newvers.sh Modified: releng/8.4/sys/conf/newvers.sh ============================================================================== --- releng/8.4/sys/conf/newvers.sh Sat Apr 20 18:52:06 2013 (r249709) +++ releng/8.4/sys/conf/newvers.sh Sat Apr 20 19:13:56 2013 (r249710) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.4" -BRANCH="RC1" +BRANCH="RC2" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi