Index: kern/kern_proc.c =================================================================== RCS file: /usr/cvs/src/sys/kern/kern_proc.c,v retrieving revision 1.230 diff -u -r1.230 kern_proc.c --- kern/kern_proc.c 18 Apr 2005 02:10:36 -0000 1.230 +++ kern/kern_proc.c 26 Sep 2005 20:58:58 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,6 @@ struct proclist zombproc; struct sx allproc_lock; struct sx proctree_lock; -struct mtx pargs_ref_lock; struct mtx ppeers_lock; uma_zone_t proc_zone; uma_zone_t ithread_zone; @@ -109,7 +109,6 @@ sx_init(&allproc_lock, "allproc"); sx_init(&proctree_lock, "proctree"); - mtx_init(&pargs_ref_lock, "struct pargs.ref", NULL, MTX_DEF); mtx_init(&ppeers_lock, "p_peers", NULL, MTX_DEF); LIST_INIT(&allproc); LIST_INIT(&zombproc); @@ -1090,7 +1089,7 @@ MALLOC(pa, struct pargs *, sizeof(struct pargs) + len, M_PARGS, M_WAITOK); - pa->ar_ref = 1; + refcount_init(&pa->ar_ref, 1); pa->ar_length = len; return (pa); } @@ -1108,9 +1107,7 @@ if (pa == NULL) return; - PARGS_LOCK(pa); - pa->ar_ref++; - PARGS_UNLOCK(pa); + refcount_acquire(&pa->ar_ref); } void @@ -1119,12 +1116,8 @@ if (pa == NULL) return; - PARGS_LOCK(pa); - if (--pa->ar_ref == 0) { - PARGS_UNLOCK(pa); + if (refcount_release(&pa->ar_ref)) pargs_free(pa); - } else - PARGS_UNLOCK(pa); } /* Index: kern/kern_prot.c =================================================================== RCS file: /usr/cvs/src/sys/kern/kern_prot.c,v retrieving revision 1.200 diff -u -r1.200 kern_prot.c --- kern/kern_prot.c 18 Apr 2005 13:36:56 -0000 1.200 +++ kern/kern_prot.c 26 Sep 2005 20:58:58 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -1841,8 +1842,7 @@ register struct ucred *cr; MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); - cr->cr_ref = 1; - cr->cr_mtxp = mtx_pool_find(mtxpool_sleep, cr); + refcount_init(&cr->cr_ref, 1); #ifdef MAC mac_init_cred(cr); #endif @@ -1857,9 +1857,7 @@ crhold(struct ucred *cr) { - mtx_lock(cr->cr_mtxp); - cr->cr_ref++; - mtx_unlock(cr->cr_mtxp); + refcount_acquire(&cr->cr_ref); return (cr); } @@ -1871,12 +1869,10 @@ void crfree(struct ucred *cr) { - struct mtx *mtxp = cr->cr_mtxp; - mtx_lock(mtxp); KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); - if (--cr->cr_ref == 0) { - mtx_unlock(mtxp); + KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred")); + if (refcount_release(&cr->cr_ref)) { /* * Some callers of crget(), such as nfs_statfs(), * allocate a temporary credential, but don't @@ -1895,8 +1891,6 @@ mac_destroy_cred(cr); #endif FREE(cr, M_CRED); - } else { - mtx_unlock(mtxp); } } @@ -1907,12 +1901,8 @@ int crshared(struct ucred *cr) { - int shared; - mtx_lock(cr->cr_mtxp); - shared = (cr->cr_ref > 1); - mtx_unlock(cr->cr_mtxp); - return (shared); + return (cr->cr_ref > 1); } /* Index: kern/kern_resource.c =================================================================== RCS file: /usr/cvs/src/sys/kern/kern_resource.c,v retrieving revision 1.148 diff -u -r1.148 kern_resource.c --- kern/kern_resource.c 1 Jun 2005 17:52:51 -0000 1.148 +++ kern/kern_resource.c 26 Sep 2005 20:58:58 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -901,8 +902,7 @@ struct plimit *limp; limp = malloc(sizeof(struct plimit), M_PLIMIT, M_WAITOK); - limp->pl_refcnt = 1; - limp->pl_mtx = mtx_pool_alloc(mtxpool_sleep); + refcount_init(&limp->pl_refcnt, 1); return (limp); } @@ -911,9 +911,7 @@ struct plimit *limp; { - LIM_LOCK(limp); - limp->pl_refcnt++; - LIM_UNLOCK(limp); + refcount_acquire(&limp->pl_refcnt); return (limp); } @@ -922,14 +920,9 @@ struct plimit *limp; { - LIM_LOCK(limp); KASSERT(limp->pl_refcnt > 0, ("plimit refcnt underflow")); - if (--limp->pl_refcnt == 0) { - LIM_UNLOCK(limp); + if (refcount_release(&limp->pl_refcnt)) free((void *)limp, M_PLIMIT); - return; - } - LIM_UNLOCK(limp); } /* Index: kern/uipc_mbuf.c =================================================================== RCS file: /usr/cvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.155 diff -u -r1.155 uipc_mbuf.c --- kern/uipc_mbuf.c 30 Aug 2005 21:31:42 -0000 1.155 +++ kern/uipc_mbuf.c 26 Sep 2005 20:58:58 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -203,7 +204,7 @@ mb->m_ext.ref_cnt = (ref_cnt == NULL) ? malloc(sizeof(u_int), M_MBUF, M_NOWAIT) : (u_int *)ref_cnt; if (mb->m_ext.ref_cnt != NULL) { - *(mb->m_ext.ref_cnt) = 1; + refcount_init(mb->m_ext.ref_cnt, 1); mb->m_flags |= (M_EXT | flags); mb->m_ext.ext_buf = buf; mb->m_data = mb->m_ext.ext_buf; @@ -221,28 +222,13 @@ void mb_free_ext(struct mbuf *m) { - u_int cnt; int dofree; /* Account for lazy ref count assign. */ if (m->m_ext.ref_cnt == NULL) dofree = 1; else - dofree = 0; - - /* - * This is tricky. We need to make sure to decrement the - * refcount in a safe way but to also clean up if we're the - * last reference. This method seems to do it without race. - */ - while (dofree == 0) { - cnt = *(m->m_ext.ref_cnt); - if (atomic_cmpset_int(m->m_ext.ref_cnt, cnt, cnt - 1)) { - if (cnt == 1) - dofree = 1; - break; - } - } + dofree = refcount_release(m->m_ext.ref_cnt); if (dofree) { /* Index: kern/vfs_export.c =================================================================== RCS file: /usr/cvs/src/sys/kern/vfs_export.c,v retrieving revision 1.333 diff -u -r1.333 vfs_export.c --- kern/vfs_export.c 11 May 2005 18:25:42 -0000 1.333 +++ kern/vfs_export.c 26 Sep 2005 20:58:58 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +116,7 @@ np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, sizeof(np->netc_anon.cr_groups)); - np->netc_anon.cr_ref = 1; + refcount_init(&np->netc_anon.cr_ref, 1); mp->mnt_flag |= MNT_DEFEXPORTED; return (0); } @@ -174,7 +175,7 @@ np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, sizeof(np->netc_anon.cr_groups)); - np->netc_anon.cr_ref = 1; + refcount_init(&np->netc_anon.cr_ref, 1); return (0); out: free(np, M_NETADDR); Index: nfsserver/nfs_srvsock.c =================================================================== RCS file: /usr/cvs/src/sys/nfsserver/nfs_srvsock.c,v retrieving revision 1.94 diff -u -r1.94 nfs_srvsock.c --- nfsserver/nfs_srvsock.c 19 Jan 2005 22:53:40 -0000 1.94 +++ nfsserver/nfs_srvsock.c 26 Sep 2005 20:58:58 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -364,12 +365,11 @@ /* * XXX: This credential should be managed using crget(9) * and related calls. Right now, this tramples on any - * extensible data in the ucred, fails to initialize the - * mutex, and worse. This must be fixed before FreeBSD - * 5.3-RELEASE. + * extensible data in the ucred, and worse. This wasn't + * fixed before FreeBSD 5.3-RELEASE. */ bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred)); - nd->nd_cr.cr_ref = 1; + refcount_init(&nd->nd_cr.cr_ref, 1); nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++); nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++); len = fxdr_unsigned(int, *tl); Index: nfsserver/nfs_srvsubs.c =================================================================== RCS file: /usr/cvs/src/sys/nfsserver/nfs_srvsubs.c,v retrieving revision 1.136 diff -u -r1.136 nfs_srvsubs.c --- nfsserver/nfs_srvsubs.c 28 Mar 2005 18:51:58 -0000 1.136 +++ nfsserver/nfs_srvsubs.c 26 Sep 2005 20:58:58 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -1257,7 +1258,7 @@ NFSD_LOCK_DONTCARE(); bzero((caddr_t)outcred, sizeof (struct ucred)); - outcred->cr_ref = 1; + refcount_init(&outcred->cr_ref, 1); outcred->cr_uid = incred->cr_uid; outcred->cr_ngroups = incred->cr_ngroups; for (i = 0; i < incred->cr_ngroups; i++) Index: sys/mbuf.h =================================================================== RCS file: /usr/cvs/src/sys/sys/mbuf.h,v retrieving revision 1.177 diff -u -r1.177 mbuf.h --- sys/mbuf.h 30 Aug 2005 21:14:30 -0000 1.177 +++ sys/mbuf.h 26 Sep 2005 20:58:58 -0000 @@ -321,7 +321,7 @@ #define MEXT_REM_REF(m) do { \ KASSERT((m)->m_ext.ref_cnt != NULL, ("m_ext refcnt lazy NULL")); \ KASSERT(*((m)->m_ext.ref_cnt) > 0, ("m_ext refcnt < 0")); \ - atomic_subtract_int((m)->m_ext.ref_cnt, 1); \ + refcount_release((m)->m_ext.ref_cnt); \ } while(0) #define MEXT_ADD_REF(m) do { \ @@ -331,9 +331,9 @@ ("Unexpected mbuf type has lazy refcnt")); \ (m)->m_ext.ref_cnt = (u_int *)uma_find_refcnt( \ zone_clust, (m)->m_ext.ext_buf); \ - *((m)->m_ext.ref_cnt) = 2; \ + refcount_init((m)->m_ext.ref_cnt, 2); \ } else \ - atomic_add_int((m)->m_ext.ref_cnt, 1); \ + refcount_acquire((m)->m_ext.ref_cnt); \ } while (0) #ifdef WITNESS Index: sys/proc.h =================================================================== RCS file: /usr/cvs/src/sys/sys/proc.h,v retrieving revision 1.434 diff -u -r1.434 proc.h --- sys/proc.h 15 Sep 2005 19:05:37 -0000 1.434 +++ sys/proc.h 26 Sep 2005 20:58:58 -0000 @@ -806,10 +806,6 @@ curthread->td_pflags &= ~TDP_NOSLEEPING; \ } while (0) -/* Lock and unlock process arguments. */ -#define PARGS_LOCK(p) mtx_lock(&pargs_ref_lock) -#define PARGS_UNLOCK(p) mtx_unlock(&pargs_ref_lock) - #define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash]) extern LIST_HEAD(pidhashhead, proc) *pidhashtbl; extern u_long pidhash; @@ -820,7 +816,6 @@ extern struct sx allproc_lock; extern struct sx proctree_lock; -extern struct mtx pargs_ref_lock; extern struct mtx ppeers_lock; extern struct ksegrp ksegrp0; /* Primary ksegrp in proc0. */ extern struct proc proc0; /* Process slot for swapper. */ Index: sys/refcount.h =================================================================== RCS file: sys/refcount.h diff -N sys/refcount.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/refcount.h 26 Sep 2005 20:56:43 -0000 @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2005 John Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __SYS_REFCOUNT_H__ +#define __SYS_REFCOUNT_H__ + +#include + +static __inline void +refcount_init(volatile u_int *count, u_int value) +{ + + *count = value; +} + +static __inline void +refcount_acquire(volatile u_int *count) +{ + + atomic_add_acq_int(count, 1); +} + +static __inline int +refcount_release(volatile u_int *count) +{ + + /* XXX: Should this have a rel membar? */ + return (atomic_fetchadd_int(count, -1) == 1); +} + +#endif /* ! __SYS_REFCOUNT_H__ */ Index: sys/resourcevar.h =================================================================== RCS file: /usr/cvs/src/sys/sys/resourcevar.h,v retrieving revision 1.47 diff -u -r1.47 resourcevar.h --- sys/resourcevar.h 7 Jan 2005 02:29:23 -0000 1.47 +++ sys/resourcevar.h 26 Sep 2005 20:58:58 -0000 @@ -78,13 +78,8 @@ struct plimit { struct rlimit pl_rlimit[RLIM_NLIMITS]; int pl_refcnt; /* number of references */ - struct mtx *pl_mtx; }; -#define LIM_LOCK(lim) mtx_lock((lim)->pl_mtx) -#define LIM_UNLOCK(lim) mtx_unlock((lim)->pl_mtx) -#define LIM_LOCK_ASSERT(lim, f) mtx_assert((lim)->pl_mtx, (f)) - /*- * Per uid resource consumption * Index: sys/ucred.h =================================================================== RCS file: /usr/cvs/src/sys/sys/ucred.h,v retrieving revision 1.52 diff -u -r1.52 ucred.h --- sys/ucred.h 28 Jun 2005 02:23:56 -0000 1.52 +++ sys/ucred.h 26 Sep 2005 20:58:58 -0000 @@ -55,7 +55,6 @@ struct prison *cr_prison; /* jail(2) */ #define cr_endcopy cr_label struct label *cr_label; /* MAC label */ - struct mtx *cr_mtxp; /* protect refcount */ }; #define NOCRED ((struct ucred *)0) /* no credential available */ #define FSCRED ((struct ucred *)-1) /* filesystem credential */ Index: ufs/ufs/ufs_vnops.c =================================================================== RCS file: /usr/cvs/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.272 diff -u -r1.272 ufs_vnops.c --- ufs/ufs/ufs_vnops.c 6 Sep 2005 00:06:30 -0000 1.272 +++ ufs/ufs/ufs_vnops.c 26 Sep 2005 20:58:58 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -1364,7 +1365,7 @@ * XXX This seems to never be accessed out of * our context so a stack variable is ok. */ - ucred.cr_ref = 1; + refcount_init(&ucred.cr_ref, 1); ucred.cr_uid = ip->i_uid; ucred.cr_ngroups = 1; ucred.cr_groups[0] = dp->i_gid; @@ -2195,7 +2196,7 @@ * XXX This seems to never be accessed out of our * context so a stack variable is ok. */ - ucred.cr_ref = 1; + refcount_init(&ucred.cr_ref, 1); ucred.cr_uid = ip->i_uid; ucred.cr_ngroups = 1; ucred.cr_groups[0] = pdir->i_gid;