Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Dec 2011 00:10:09 -0500
From:      Jason Hellenthal <jhell@DataIX.net>
To:        Ed Schouten <ed@80386.nl>
Cc:        freebsd-fs@freebsd.org, pjd@freebsd.org
Subject:   Re: Changing refcount(9) to use a refcount_t
Message-ID:  <20111223051009.GA77353@DataIX.net>
In-Reply-To: <20111222230756.GW1771@hoeg.nl>
References:  <20111222214728.GV1771@hoeg.nl> <20111222230756.GW1771@hoeg.nl>

next in thread | previous in thread | raw e-mail | index | archive | help

--l76fUT7nc3MelDdI
Content-Type: multipart/mixed; boundary="Q68bSM7Ycu6FN28Q"
Content-Disposition: inline


--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable


Nice work. So all-in-all we need both patches concatenated like so...?

On Fri, Dec 23, 2011 at 12:07:56AM +0100, Ed Schouten wrote:
> * Ed Schouten <ed@80386.nl>, 20111222 22:47:
> > Can any of you ZFS user please try the following patch?
>=20
> Whoops. It seems I forgot the ZFS source code is also built in userspace
> (libzpool). I have attached a new patch. Changes:
>=20
> - Remove the refcount.c file, as it has no use anymore.
> - Port the rrwlock code to not use refcount_t at all. It accesses
>   internal members of the refcount_t and it seems we don't need to use
>   atomics here anyway, as all operations on the counters are performed
>   while holding the rr_lock.
>=20
> --=20
>  Ed Schouten <ed@80386.nl>
>  WWW: http://80386.nl/

> Index: share/man/man9/refcount.9
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- share/man/man9/refcount.9	(revision 228798)
> +++ share/man/man9/refcount.9	(working copy)
> @@ -39,11 +39,11 @@
>  .In sys/param.h
>  .In sys/refcount.h
>  .Ft void
> -.Fn refcount_init "volatile u_int *count, u_int value"
> +.Fn refcount_init "refcount_t *count, u_int value"
>  .Ft void
> -.Fn refcount_acquire "volatile u_int *count"
> +.Fn refcount_acquire "refcount_t *count"
>  .Ft int
> -.Fn refcount_release "volatile u_int *count"
> +.Fn refcount_release "refcount_t *count"
>  .Sh DESCRIPTION
>  The
>  .Nm
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c	(revision 22=
8798)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c	(working cop=
y)
> @@ -23,7 +23,6 @@
>   * Use is subject to license terms.
>   */
> =20
> -#include <sys/refcount.h>
>  #include <sys/rrwlock.h>
> =20
>  /*
> @@ -81,7 +80,7 @@
>  {
>  	rrw_node_t *rn;
> =20
> -	if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0)
> +	if (rrl->rr_linked_rcount =3D=3D 0)
>  		return (NULL);
> =20
>  	for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) {
> @@ -115,7 +114,7 @@
>  	rrw_node_t *rn;
>  	rrw_node_t *prev =3D NULL;
> =20
> -	if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0)
> +	if (rrl->rr_linked_rcount =3D=3D 0)
>  		return (B_FALSE);
> =20
>  	for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) {
> @@ -138,8 +137,8 @@
>  	mutex_init(&rrl->rr_lock, NULL, MUTEX_DEFAULT, NULL);
>  	cv_init(&rrl->rr_cv, NULL, CV_DEFAULT, NULL);
>  	rrl->rr_writer =3D NULL;
> -	refcount_create(&rrl->rr_anon_rcount);
> -	refcount_create(&rrl->rr_linked_rcount);
> +	rrl->rr_anon_rcount =3D 0;
> +	rrl->rr_linked_rcount =3D 0;
>  	rrl->rr_writer_wanted =3D B_FALSE;
>  }
> =20
> @@ -149,8 +148,8 @@
>  	mutex_destroy(&rrl->rr_lock);
>  	cv_destroy(&rrl->rr_cv);
>  	ASSERT(rrl->rr_writer =3D=3D NULL);
> -	refcount_destroy(&rrl->rr_anon_rcount);
> -	refcount_destroy(&rrl->rr_linked_rcount);
> +	rrl->rr_anon_rcount =3D 0;
> +	rrl->rr_linked_rcount =3D 0;
>  }
> =20
>  static void
> @@ -159,26 +158,26 @@
>  	mutex_enter(&rrl->rr_lock);
>  #if !defined(DEBUG) && defined(_KERNEL)
>  	if (!rrl->rr_writer && !rrl->rr_writer_wanted) {
> -		rrl->rr_anon_rcount.rc_count++;
> +		rrl->rr_anon_rcount++;
>  		mutex_exit(&rrl->rr_lock);
>  		return;
>  	}
>  	DTRACE_PROBE(zfs__rrwfastpath__rdmiss);
>  #endif
>  	ASSERT(rrl->rr_writer !=3D curthread);
> -	ASSERT(refcount_count(&rrl->rr_anon_rcount) >=3D 0);
> +	ASSERT(rrl->rr_anon_rcount >=3D 0);
> =20
>  	while (rrl->rr_writer || (rrl->rr_writer_wanted &&
> -	    refcount_is_zero(&rrl->rr_anon_rcount) &&
> +	    rrl->rr_anon_rcount =3D=3D 0 &&
>  	    rrn_find(rrl) =3D=3D NULL))
>  		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
> =20
>  	if (rrl->rr_writer_wanted) {
>  		/* may or may not be a re-entrant enter */
>  		rrn_add(rrl);
> -		(void) refcount_add(&rrl->rr_linked_rcount, tag);
> +		rrl->rr_linked_rcount++;
>  	} else {
> -		(void) refcount_add(&rrl->rr_anon_rcount, tag);
> +		rrl->rr_anon_rcount++;
>  	}
>  	ASSERT(rrl->rr_writer =3D=3D NULL);
>  	mutex_exit(&rrl->rr_lock);
> @@ -190,8 +189,8 @@
>  	mutex_enter(&rrl->rr_lock);
>  	ASSERT(rrl->rr_writer !=3D curthread);
> =20
> -	while (refcount_count(&rrl->rr_anon_rcount) > 0 ||
> -	    refcount_count(&rrl->rr_linked_rcount) > 0 ||
> +	while (rrl->rr_anon_rcount > 0 ||
> +	    rrl->rr_linked_rcount > 0 ||
>  	    rrl->rr_writer !=3D NULL) {
>  		rrl->rr_writer_wanted =3D B_TRUE;
>  		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
> @@ -224,22 +223,22 @@
>  	}
>  	DTRACE_PROBE(zfs__rrwfastpath__exitmiss);
>  #endif
> -	ASSERT(!refcount_is_zero(&rrl->rr_anon_rcount) ||
> -	    !refcount_is_zero(&rrl->rr_linked_rcount) ||
> +	ASSERT(rrl->rr_anon_rcount !=3D 0 ||
> +	    rrl->rr_linked_rcount !=3D 0 ||
>  	    rrl->rr_writer !=3D NULL);
> =20
>  	if (rrl->rr_writer =3D=3D NULL) {
> -		int64_t count;
> +		uint64_t count;
>  		if (rrn_find_and_remove(rrl))
> -			count =3D refcount_remove(&rrl->rr_linked_rcount, tag);
> +			count =3D rrl->rr_linked_rcount--;
>  		else
> -			count =3D refcount_remove(&rrl->rr_anon_rcount, tag);
> +			count =3D rrl->rr_anon_rcount--;
>  		if (count =3D=3D 0)
>  			cv_broadcast(&rrl->rr_cv);
>  	} else {
>  		ASSERT(rrl->rr_writer =3D=3D curthread);
> -		ASSERT(refcount_is_zero(&rrl->rr_anon_rcount) &&
> -		    refcount_is_zero(&rrl->rr_linked_rcount));
> +		ASSERT(rrl->rr_anon_rcount =3D=3D 0 &&
> +		    rrl->rr_linked_rcount =3D=3D 0);
>  		rrl->rr_writer =3D NULL;
>  		cv_broadcast(&rrl->rr_cv);
>  	}
> @@ -255,8 +254,8 @@
>  	if (rw =3D=3D RW_WRITER) {
>  		held =3D (rrl->rr_writer =3D=3D curthread);
>  	} else {
> -		held =3D (!refcount_is_zero(&rrl->rr_anon_rcount) ||
> -		    !refcount_is_zero(&rrl->rr_linked_rcount));
> +		held =3D (rrl->rr_anon_rcount !=3D 0 ||
> +		    rrl->rr_linked_rcount !=3D 0);
>  	}
>  	mutex_exit(&rrl->rr_lock);
> =20
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(revisi=
on 228798)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(workin=
g copy)
> @@ -31,10 +31,6 @@
>  #include <sys/list.h>
>  #include <sys/zfs_context.h>
> =20
> -#ifdef	__cplusplus
> -extern "C" {
> -#endif
> -
>  /*
>   * If the reference is held only by the calling function and not any
>   * particular object, use FTAG (which is a string) for the holder_tag.
> @@ -42,68 +38,21 @@
>   */
>  #define	FTAG ((char *)__func__)
> =20
> -#ifdef	ZFS_DEBUG
> -typedef struct reference {
> -	list_node_t ref_link;
> -	void *ref_holder;
> -	uint64_t ref_number;
> -	uint8_t *ref_removed;
> -} reference_t;
> -
> -typedef struct refcount {
> -	kmutex_t rc_mtx;
> -	list_t rc_list;
> -	list_t rc_removed;
> -	int64_t rc_count;
> -	int64_t rc_removed_count;
> -} refcount_t;
> -
> -/* Note: refcount_t must be initialized with refcount_create() */
> -
> -void refcount_create(refcount_t *rc);
> -void refcount_destroy(refcount_t *rc);
> -void refcount_destroy_many(refcount_t *rc, uint64_t number);
> -int refcount_is_zero(refcount_t *rc);
> -int64_t refcount_count(refcount_t *rc);
> -int64_t refcount_add(refcount_t *rc, void *holder_tag);
> -int64_t refcount_remove(refcount_t *rc, void *holder_tag);
> -int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_=
tag);
> -int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *hold=
er_tag);
> -void refcount_transfer(refcount_t *dst, refcount_t *src);
> -
> -void refcount_sysinit(void);
> -void refcount_fini(void);
> -
> -#else	/* ZFS_DEBUG */
> -
> -typedef struct refcount {
> -	uint64_t rc_count;
> -} refcount_t;
> -
> -#define	refcount_create(rc) ((rc)->rc_count =3D 0)
> -#define	refcount_destroy(rc) ((rc)->rc_count =3D 0)
> -#define	refcount_destroy_many(rc, number) ((rc)->rc_count =3D 0)
> -#define	refcount_is_zero(rc) ((rc)->rc_count =3D=3D 0)
> -#define	refcount_count(rc) ((rc)->rc_count)
> -#define	refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
> -#define	refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
> +#define	refcount_create(rc)		refcount_init(rc, 0)
> +#define	refcount_destroy(rc)		refcount_init(rc, 0)
> +#define	refcount_destroy_many(rc, number) refcount_init(rc, 0)
> +#define	refcount_is_zero(rc)		((*rc) =3D=3D 0)
> +#define	refcount_count(rc)		(uint64_t)(*rc)
> +#define	refcount_add(rc, holder)	refcount_add_many(rc, 1, holder)
> +#define	refcount_remove(rc, holder)	refcount_remove_many(rc, 1, holder)
>  #define	refcount_add_many(rc, number, holder) \
> -	atomic_add_64_nv(&(rc)->rc_count, number)
> +	(uint64_t)(atomic_fetchadd_int(rc, number) + (number))
>  #define	refcount_remove_many(rc, number, holder) \
> -	atomic_add_64_nv(&(rc)->rc_count, -number)
> -#define	refcount_transfer(dst, src) { \
> -	uint64_t __tmp =3D (src)->rc_count; \
> -	atomic_add_64(&(src)->rc_count, -__tmp); \
> -	atomic_add_64(&(dst)->rc_count, __tmp); \
> -}
> +	(uint64_t)(atomic_fetchadd_int(rc, -(number)) - (number))
> +#define	refcount_transfer(dst, src) \
> +	atomic_add_int(dst, atomic_readandclear_int(src))
> =20
>  #define	refcount_sysinit()
>  #define	refcount_fini()
> =20
> -#endif	/* ZFS_DEBUG */
> -
> -#ifdef	__cplusplus
> -}
> -#endif
> -
>  #endif /* _SYS_REFCOUNT_H */
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h	(revisio=
n 228798)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h	(working=
 copy)
> @@ -33,7 +33,6 @@
>  #endif
> =20
>  #include <sys/zfs_context.h>
> -#include <sys/refcount.h>
> =20
>  /*
>   * A reader-writer lock implementation that allows re-entrant reads, but
> @@ -53,8 +52,8 @@
>  	kmutex_t	rr_lock;
>  	kcondvar_t	rr_cv;
>  	kthread_t	*rr_writer;
> -	refcount_t	rr_anon_rcount;
> -	refcount_t	rr_linked_rcount;
> +	uint64_t	rr_anon_rcount;
> +	uint64_t	rr_linked_rcount;
>  	boolean_t	rr_writer_wanted;
>  } rrwlock_t;
> =20
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c	(revision 2=
28798)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c	(working co=
py)
> @@ -1,223 +0,0 @@
> -/*
> - * CDDL HEADER START
> - *
> - * The contents of this file are subject to the terms of the
> - * Common Development and Distribution License (the "License").
> - * You may not use this file except in compliance with the License.
> - *
> - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
> - * or http://www.opensolaris.org/os/licensing.
> - * See the License for the specific language governing permissions
> - * and limitations under the License.
> - *
> - * When distributing Covered Code, include this CDDL HEADER in each
> - * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
> - * If applicable, add the following below this CDDL HEADER, with the
> - * fields enclosed by brackets "[]" replaced with your own identifying
> - * information: Portions Copyright [yyyy] [name of copyright owner]
> - *
> - * CDDL HEADER END
> - */
> -/*
> - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights re=
served.
> - */
> -
> -#include <sys/zfs_context.h>
> -#include <sys/refcount.h>
> -
> -#ifdef	ZFS_DEBUG
> -
> -#ifdef _KERNEL
> -int reference_tracking_enable =3D FALSE; /* runs out of memory too easil=
y */
> -#else
> -int reference_tracking_enable =3D TRUE;
> -#endif
> -int reference_history =3D 4; /* tunable */
> -
> -static kmem_cache_t *reference_cache;
> -static kmem_cache_t *reference_history_cache;
> -
> -void
> -refcount_sysinit(void)
> -{
> -	reference_cache =3D kmem_cache_create("reference_cache",
> -	    sizeof (reference_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
> -
> -	reference_history_cache =3D kmem_cache_create("reference_history_cache",
> -	    sizeof (uint64_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
> -}
> -
> -void
> -refcount_fini(void)
> -{
> -	kmem_cache_destroy(reference_cache);
> -	kmem_cache_destroy(reference_history_cache);
> -}
> -
> -void
> -refcount_create(refcount_t *rc)
> -{
> -	mutex_init(&rc->rc_mtx, NULL, MUTEX_DEFAULT, NULL);
> -	list_create(&rc->rc_list, sizeof (reference_t),
> -	    offsetof(reference_t, ref_link));
> -	list_create(&rc->rc_removed, sizeof (reference_t),
> -	    offsetof(reference_t, ref_link));
> -	rc->rc_count =3D 0;
> -	rc->rc_removed_count =3D 0;
> -}
> -
> -void
> -refcount_destroy_many(refcount_t *rc, uint64_t number)
> -{
> -	reference_t *ref;
> -
> -	ASSERT(rc->rc_count =3D=3D number);
> -	while (ref =3D list_head(&rc->rc_list)) {
> -		list_remove(&rc->rc_list, ref);
> -		kmem_cache_free(reference_cache, ref);
> -	}
> -	list_destroy(&rc->rc_list);
> -
> -	while (ref =3D list_head(&rc->rc_removed)) {
> -		list_remove(&rc->rc_removed, ref);
> -		kmem_cache_free(reference_history_cache, ref->ref_removed);
> -		kmem_cache_free(reference_cache, ref);
> -	}
> -	list_destroy(&rc->rc_removed);
> -	mutex_destroy(&rc->rc_mtx);
> -}
> -
> -void
> -refcount_destroy(refcount_t *rc)
> -{
> -	refcount_destroy_many(rc, 0);
> -}
> -
> -int
> -refcount_is_zero(refcount_t *rc)
> -{
> -	ASSERT(rc->rc_count >=3D 0);
> -	return (rc->rc_count =3D=3D 0);
> -}
> -
> -int64_t
> -refcount_count(refcount_t *rc)
> -{
> -	ASSERT(rc->rc_count >=3D 0);
> -	return (rc->rc_count);
> -}
> -
> -int64_t
> -refcount_add_many(refcount_t *rc, uint64_t number, void *holder)
> -{
> -	reference_t *ref;
> -	int64_t count;
> -
> -	if (reference_tracking_enable) {
> -		ref =3D kmem_cache_alloc(reference_cache, KM_SLEEP);
> -		ref->ref_holder =3D holder;
> -		ref->ref_number =3D number;
> -	}
> -	mutex_enter(&rc->rc_mtx);
> -	ASSERT(rc->rc_count >=3D 0);
> -	if (reference_tracking_enable)
> -		list_insert_head(&rc->rc_list, ref);
> -	rc->rc_count +=3D number;
> -	count =3D rc->rc_count;
> -	mutex_exit(&rc->rc_mtx);
> -
> -	return (count);
> -}
> -
> -int64_t
> -refcount_add(refcount_t *rc, void *holder)
> -{
> -	return (refcount_add_many(rc, 1, holder));
> -}
> -
> -int64_t
> -refcount_remove_many(refcount_t *rc, uint64_t number, void *holder)
> -{
> -	reference_t *ref;
> -	int64_t count;
> -
> -	mutex_enter(&rc->rc_mtx);
> -	ASSERT(rc->rc_count >=3D number);
> -
> -	if (!reference_tracking_enable) {
> -		rc->rc_count -=3D number;
> -		count =3D rc->rc_count;
> -		mutex_exit(&rc->rc_mtx);
> -		return (count);
> -	}
> -
> -	for (ref =3D list_head(&rc->rc_list); ref;
> -	    ref =3D list_next(&rc->rc_list, ref)) {
> -		if (ref->ref_holder =3D=3D holder && ref->ref_number =3D=3D number) {
> -			list_remove(&rc->rc_list, ref);
> -			if (reference_history > 0) {
> -				ref->ref_removed =3D
> -				    kmem_cache_alloc(reference_history_cache,
> -				    KM_SLEEP);
> -				list_insert_head(&rc->rc_removed, ref);
> -				rc->rc_removed_count++;
> -				if (rc->rc_removed_count >=3D reference_history) {
> -					ref =3D list_tail(&rc->rc_removed);
> -					list_remove(&rc->rc_removed, ref);
> -					kmem_cache_free(reference_history_cache,
> -					    ref->ref_removed);
> -					kmem_cache_free(reference_cache, ref);
> -					rc->rc_removed_count--;
> -				}
> -			} else {
> -				kmem_cache_free(reference_cache, ref);
> -			}
> -			rc->rc_count -=3D number;
> -			count =3D rc->rc_count;
> -			mutex_exit(&rc->rc_mtx);
> -			return (count);
> -		}
> -	}
> -	panic("No such hold %p on refcount %llx", holder,
> -	    (u_longlong_t)(uintptr_t)rc);
> -	return (-1);
> -}
> -
> -int64_t
> -refcount_remove(refcount_t *rc, void *holder)
> -{
> -	return (refcount_remove_many(rc, 1, holder));
> -}
> -
> -void
> -refcount_transfer(refcount_t *dst, refcount_t *src)
> -{
> -	int64_t count, removed_count;
> -	list_t list, removed;
> -
> -	list_create(&list, sizeof (reference_t),
> -	    offsetof(reference_t, ref_link));
> -	list_create(&removed, sizeof (reference_t),
> -	    offsetof(reference_t, ref_link));
> -
> -	mutex_enter(&src->rc_mtx);
> -	count =3D src->rc_count;
> -	removed_count =3D src->rc_removed_count;
> -	src->rc_count =3D 0;
> -	src->rc_removed_count =3D 0;
> -	list_move_tail(&list, &src->rc_list);
> -	list_move_tail(&removed, &src->rc_removed);
> -	mutex_exit(&src->rc_mtx);
> -
> -	mutex_enter(&dst->rc_mtx);
> -	dst->rc_count +=3D count;
> -	dst->rc_removed_count +=3D removed_count;
> -	list_move_tail(&dst->rc_list, &list);
> -	list_move_tail(&dst->rc_removed, &removed);
> -	mutex_exit(&dst->rc_mtx);
> -
> -	list_destroy(&list);
> -	list_destroy(&removed);
> -}
> -
> -#endif	/* ZFS_DEBUG */
> Index: sys/cddl/contrib/opensolaris/uts/common/Makefile.files
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/cddl/contrib/opensolaris/uts/common/Makefile.files	(revision 2287=
98)
> +++ sys/cddl/contrib/opensolaris/uts/common/Makefile.files	(working copy)
> @@ -55,7 +55,6 @@
>  	gzip.o			\
>  	lzjb.o			\
>  	metaslab.o		\
> -	refcount.o		\
>  	sa.o			\
>  	sha256.o		\
>  	spa.o			\
> Index: sys/sys/refcount.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- sys/sys/refcount.h	(revision 228798)
> +++ sys/sys/refcount.h	(working copy)
> @@ -40,22 +40,24 @@
>  #define	KASSERT(exp, msg)	/* */
>  #endif
> =20
> +typedef volatile u_int refcount_t;
> +
>  static __inline void
> -refcount_init(volatile u_int *count, u_int value)
> +refcount_init(refcount_t *count, u_int value)
>  {
> =20
>  	*count =3D value;
>  }
> =20
>  static __inline void
> -refcount_acquire(volatile u_int *count)
> +refcount_acquire(refcount_t *count)
>  {
> =20
>  	atomic_add_acq_int(count, 1);=09
>  }
> =20
>  static __inline int
> -refcount_release(volatile u_int *count)
> +refcount_release(refcount_t *count)
>  {
>  	u_int old;
> =20




--=20
;s =3D;

--Q68bSM7Ycu6FN28Q
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="ref.diff"
Content-Transfer-Encoding: quoted-printable

Index: share/man/man9/refcount.9
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- share/man/man9/refcount.9	(revision 228798)
+++ share/man/man9/refcount.9	(working copy)
@@ -39,11 +39,11 @@
 .In sys/param.h
 .In sys/refcount.h
 .Ft void
-.Fn refcount_init "volatile u_int *count, u_int value"
+.Fn refcount_init "refcount_t *count, u_int value"
 .Ft void
-.Fn refcount_acquire "volatile u_int *count"
+.Fn refcount_acquire "refcount_t *count"
 .Ft int
-.Fn refcount_release "volatile u_int *count"
+.Fn refcount_release "refcount_t *count"
 .Sh DESCRIPTION
 The
 .Nm
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c	(revision 2287=
98)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c	(working copy)
@@ -23,7 +23,6 @@
  * Use is subject to license terms.
  */
=20
-#include <sys/refcount.h>
 #include <sys/rrwlock.h>
=20
 /*
@@ -81,7 +80,7 @@
 {
 	rrw_node_t *rn;
=20
-	if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0)
+	if (rrl->rr_linked_rcount =3D=3D 0)
 		return (NULL);
=20
 	for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) {
@@ -115,7 +114,7 @@
 	rrw_node_t *rn;
 	rrw_node_t *prev =3D NULL;
=20
-	if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0)
+	if (rrl->rr_linked_rcount =3D=3D 0)
 		return (B_FALSE);
=20
 	for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) {
@@ -138,8 +137,8 @@
 	mutex_init(&rrl->rr_lock, NULL, MUTEX_DEFAULT, NULL);
 	cv_init(&rrl->rr_cv, NULL, CV_DEFAULT, NULL);
 	rrl->rr_writer =3D NULL;
-	refcount_create(&rrl->rr_anon_rcount);
-	refcount_create(&rrl->rr_linked_rcount);
+	rrl->rr_anon_rcount =3D 0;
+	rrl->rr_linked_rcount =3D 0;
 	rrl->rr_writer_wanted =3D B_FALSE;
 }
=20
@@ -149,8 +148,8 @@
 	mutex_destroy(&rrl->rr_lock);
 	cv_destroy(&rrl->rr_cv);
 	ASSERT(rrl->rr_writer =3D=3D NULL);
-	refcount_destroy(&rrl->rr_anon_rcount);
-	refcount_destroy(&rrl->rr_linked_rcount);
+	rrl->rr_anon_rcount =3D 0;
+	rrl->rr_linked_rcount =3D 0;
 }
=20
 static void
@@ -159,26 +158,26 @@
 	mutex_enter(&rrl->rr_lock);
 #if !defined(DEBUG) && defined(_KERNEL)
 	if (!rrl->rr_writer && !rrl->rr_writer_wanted) {
-		rrl->rr_anon_rcount.rc_count++;
+		rrl->rr_anon_rcount++;
 		mutex_exit(&rrl->rr_lock);
 		return;
 	}
 	DTRACE_PROBE(zfs__rrwfastpath__rdmiss);
 #endif
 	ASSERT(rrl->rr_writer !=3D curthread);
-	ASSERT(refcount_count(&rrl->rr_anon_rcount) >=3D 0);
+	ASSERT(rrl->rr_anon_rcount >=3D 0);
=20
 	while (rrl->rr_writer || (rrl->rr_writer_wanted &&
-	    refcount_is_zero(&rrl->rr_anon_rcount) &&
+	    rrl->rr_anon_rcount =3D=3D 0 &&
 	    rrn_find(rrl) =3D=3D NULL))
 		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
=20
 	if (rrl->rr_writer_wanted) {
 		/* may or may not be a re-entrant enter */
 		rrn_add(rrl);
-		(void) refcount_add(&rrl->rr_linked_rcount, tag);
+		rrl->rr_linked_rcount++;
 	} else {
-		(void) refcount_add(&rrl->rr_anon_rcount, tag);
+		rrl->rr_anon_rcount++;
 	}
 	ASSERT(rrl->rr_writer =3D=3D NULL);
 	mutex_exit(&rrl->rr_lock);
@@ -190,8 +189,8 @@
 	mutex_enter(&rrl->rr_lock);
 	ASSERT(rrl->rr_writer !=3D curthread);
=20
-	while (refcount_count(&rrl->rr_anon_rcount) > 0 ||
-	    refcount_count(&rrl->rr_linked_rcount) > 0 ||
+	while (rrl->rr_anon_rcount > 0 ||
+	    rrl->rr_linked_rcount > 0 ||
 	    rrl->rr_writer !=3D NULL) {
 		rrl->rr_writer_wanted =3D B_TRUE;
 		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
@@ -224,22 +223,22 @@
 	}
 	DTRACE_PROBE(zfs__rrwfastpath__exitmiss);
 #endif
-	ASSERT(!refcount_is_zero(&rrl->rr_anon_rcount) ||
-	    !refcount_is_zero(&rrl->rr_linked_rcount) ||
+	ASSERT(rrl->rr_anon_rcount !=3D 0 ||
+	    rrl->rr_linked_rcount !=3D 0 ||
 	    rrl->rr_writer !=3D NULL);
=20
 	if (rrl->rr_writer =3D=3D NULL) {
-		int64_t count;
+		uint64_t count;
 		if (rrn_find_and_remove(rrl))
-			count =3D refcount_remove(&rrl->rr_linked_rcount, tag);
+			count =3D rrl->rr_linked_rcount--;
 		else
-			count =3D refcount_remove(&rrl->rr_anon_rcount, tag);
+			count =3D rrl->rr_anon_rcount--;
 		if (count =3D=3D 0)
 			cv_broadcast(&rrl->rr_cv);
 	} else {
 		ASSERT(rrl->rr_writer =3D=3D curthread);
-		ASSERT(refcount_is_zero(&rrl->rr_anon_rcount) &&
-		    refcount_is_zero(&rrl->rr_linked_rcount));
+		ASSERT(rrl->rr_anon_rcount =3D=3D 0 &&
+		    rrl->rr_linked_rcount =3D=3D 0);
 		rrl->rr_writer =3D NULL;
 		cv_broadcast(&rrl->rr_cv);
 	}
@@ -255,8 +254,8 @@
 	if (rw =3D=3D RW_WRITER) {
 		held =3D (rrl->rr_writer =3D=3D curthread);
 	} else {
-		held =3D (!refcount_is_zero(&rrl->rr_anon_rcount) ||
-		    !refcount_is_zero(&rrl->rr_linked_rcount));
+		held =3D (rrl->rr_anon_rcount !=3D 0 ||
+		    rrl->rr_linked_rcount !=3D 0);
 	}
 	mutex_exit(&rrl->rr_lock);
=20
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(revision=
 228798)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(working =
copy)
@@ -31,10 +31,6 @@
 #include <sys/list.h>
 #include <sys/zfs_context.h>
=20
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
 /*
  * If the reference is held only by the calling function and not any
  * particular object, use FTAG (which is a string) for the holder_tag.
@@ -42,68 +38,21 @@
  */
 #define	FTAG ((char *)__func__)
=20
-#ifdef	ZFS_DEBUG
-typedef struct reference {
-	list_node_t ref_link;
-	void *ref_holder;
-	uint64_t ref_number;
-	uint8_t *ref_removed;
-} reference_t;
-
-typedef struct refcount {
-	kmutex_t rc_mtx;
-	list_t rc_list;
-	list_t rc_removed;
-	int64_t rc_count;
-	int64_t rc_removed_count;
-} refcount_t;
-
-/* Note: refcount_t must be initialized with refcount_create() */
-
-void refcount_create(refcount_t *rc);
-void refcount_destroy(refcount_t *rc);
-void refcount_destroy_many(refcount_t *rc, uint64_t number);
-int refcount_is_zero(refcount_t *rc);
-int64_t refcount_count(refcount_t *rc);
-int64_t refcount_add(refcount_t *rc, void *holder_tag);
-int64_t refcount_remove(refcount_t *rc, void *holder_tag);
-int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_ta=
g);
-int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder=
_tag);
-void refcount_transfer(refcount_t *dst, refcount_t *src);
-
-void refcount_sysinit(void);
-void refcount_fini(void);
-
-#else	/* ZFS_DEBUG */
-
-typedef struct refcount {
-	uint64_t rc_count;
-} refcount_t;
-
-#define	refcount_create(rc) ((rc)->rc_count =3D 0)
-#define	refcount_destroy(rc) ((rc)->rc_count =3D 0)
-#define	refcount_destroy_many(rc, number) ((rc)->rc_count =3D 0)
-#define	refcount_is_zero(rc) ((rc)->rc_count =3D=3D 0)
-#define	refcount_count(rc) ((rc)->rc_count)
-#define	refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
-#define	refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
+#define	refcount_create(rc)		refcount_init(rc, 0)
+#define	refcount_destroy(rc)		refcount_init(rc, 0)
+#define	refcount_destroy_many(rc, number) refcount_init(rc, 0)
+#define	refcount_is_zero(rc)		((*rc) =3D=3D 0)
+#define	refcount_count(rc)		(uint64_t)(*rc)
+#define	refcount_add(rc, holder)	refcount_add_many(rc, 1, holder)
+#define	refcount_remove(rc, holder)	refcount_remove_many(rc, 1, holder)
 #define	refcount_add_many(rc, number, holder) \
-	atomic_add_64_nv(&(rc)->rc_count, number)
+	(uint64_t)(atomic_fetchadd_int(rc, number) + (number))
 #define	refcount_remove_many(rc, number, holder) \
-	atomic_add_64_nv(&(rc)->rc_count, -number)
-#define	refcount_transfer(dst, src) { \
-	uint64_t __tmp =3D (src)->rc_count; \
-	atomic_add_64(&(src)->rc_count, -__tmp); \
-	atomic_add_64(&(dst)->rc_count, __tmp); \
-}
+	(uint64_t)(atomic_fetchadd_int(rc, -(number)) - (number))
+#define	refcount_transfer(dst, src) \
+	atomic_add_int(dst, atomic_readandclear_int(src))
=20
 #define	refcount_sysinit()
 #define	refcount_fini()
=20
-#endif	/* ZFS_DEBUG */
-
-#ifdef	__cplusplus
-}
-#endif
-
 #endif /* _SYS_REFCOUNT_H */
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h	(revision =
228798)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h	(working c=
opy)
@@ -33,7 +33,6 @@
 #endif
=20
 #include <sys/zfs_context.h>
-#include <sys/refcount.h>
=20
 /*
  * A reader-writer lock implementation that allows re-entrant reads, but
@@ -53,8 +52,8 @@
 	kmutex_t	rr_lock;
 	kcondvar_t	rr_cv;
 	kthread_t	*rr_writer;
-	refcount_t	rr_anon_rcount;
-	refcount_t	rr_linked_rcount;
+	uint64_t	rr_anon_rcount;
+	uint64_t	rr_linked_rcount;
 	boolean_t	rr_writer_wanted;
 } rrwlock_t;
=20
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c	(revision 228=
798)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c	(working copy)
@@ -1,223 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights rese=
rved.
- */
-
-#include <sys/zfs_context.h>
-#include <sys/refcount.h>
-
-#ifdef	ZFS_DEBUG
-
-#ifdef _KERNEL
-int reference_tracking_enable =3D FALSE; /* runs out of memory too easily =
*/
-#else
-int reference_tracking_enable =3D TRUE;
-#endif
-int reference_history =3D 4; /* tunable */
-
-static kmem_cache_t *reference_cache;
-static kmem_cache_t *reference_history_cache;
-
-void
-refcount_sysinit(void)
-{
-	reference_cache =3D kmem_cache_create("reference_cache",
-	    sizeof (reference_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
-
-	reference_history_cache =3D kmem_cache_create("reference_history_cache",
-	    sizeof (uint64_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
-}
-
-void
-refcount_fini(void)
-{
-	kmem_cache_destroy(reference_cache);
-	kmem_cache_destroy(reference_history_cache);
-}
-
-void
-refcount_create(refcount_t *rc)
-{
-	mutex_init(&rc->rc_mtx, NULL, MUTEX_DEFAULT, NULL);
-	list_create(&rc->rc_list, sizeof (reference_t),
-	    offsetof(reference_t, ref_link));
-	list_create(&rc->rc_removed, sizeof (reference_t),
-	    offsetof(reference_t, ref_link));
-	rc->rc_count =3D 0;
-	rc->rc_removed_count =3D 0;
-}
-
-void
-refcount_destroy_many(refcount_t *rc, uint64_t number)
-{
-	reference_t *ref;
-
-	ASSERT(rc->rc_count =3D=3D number);
-	while (ref =3D list_head(&rc->rc_list)) {
-		list_remove(&rc->rc_list, ref);
-		kmem_cache_free(reference_cache, ref);
-	}
-	list_destroy(&rc->rc_list);
-
-	while (ref =3D list_head(&rc->rc_removed)) {
-		list_remove(&rc->rc_removed, ref);
-		kmem_cache_free(reference_history_cache, ref->ref_removed);
-		kmem_cache_free(reference_cache, ref);
-	}
-	list_destroy(&rc->rc_removed);
-	mutex_destroy(&rc->rc_mtx);
-}
-
-void
-refcount_destroy(refcount_t *rc)
-{
-	refcount_destroy_many(rc, 0);
-}
-
-int
-refcount_is_zero(refcount_t *rc)
-{
-	ASSERT(rc->rc_count >=3D 0);
-	return (rc->rc_count =3D=3D 0);
-}
-
-int64_t
-refcount_count(refcount_t *rc)
-{
-	ASSERT(rc->rc_count >=3D 0);
-	return (rc->rc_count);
-}
-
-int64_t
-refcount_add_many(refcount_t *rc, uint64_t number, void *holder)
-{
-	reference_t *ref;
-	int64_t count;
-
-	if (reference_tracking_enable) {
-		ref =3D kmem_cache_alloc(reference_cache, KM_SLEEP);
-		ref->ref_holder =3D holder;
-		ref->ref_number =3D number;
-	}
-	mutex_enter(&rc->rc_mtx);
-	ASSERT(rc->rc_count >=3D 0);
-	if (reference_tracking_enable)
-		list_insert_head(&rc->rc_list, ref);
-	rc->rc_count +=3D number;
-	count =3D rc->rc_count;
-	mutex_exit(&rc->rc_mtx);
-
-	return (count);
-}
-
-int64_t
-refcount_add(refcount_t *rc, void *holder)
-{
-	return (refcount_add_many(rc, 1, holder));
-}
-
-int64_t
-refcount_remove_many(refcount_t *rc, uint64_t number, void *holder)
-{
-	reference_t *ref;
-	int64_t count;
-
-	mutex_enter(&rc->rc_mtx);
-	ASSERT(rc->rc_count >=3D number);
-
-	if (!reference_tracking_enable) {
-		rc->rc_count -=3D number;
-		count =3D rc->rc_count;
-		mutex_exit(&rc->rc_mtx);
-		return (count);
-	}
-
-	for (ref =3D list_head(&rc->rc_list); ref;
-	    ref =3D list_next(&rc->rc_list, ref)) {
-		if (ref->ref_holder =3D=3D holder && ref->ref_number =3D=3D number) {
-			list_remove(&rc->rc_list, ref);
-			if (reference_history > 0) {
-				ref->ref_removed =3D
-				    kmem_cache_alloc(reference_history_cache,
-				    KM_SLEEP);
-				list_insert_head(&rc->rc_removed, ref);
-				rc->rc_removed_count++;
-				if (rc->rc_removed_count >=3D reference_history) {
-					ref =3D list_tail(&rc->rc_removed);
-					list_remove(&rc->rc_removed, ref);
-					kmem_cache_free(reference_history_cache,
-					    ref->ref_removed);
-					kmem_cache_free(reference_cache, ref);
-					rc->rc_removed_count--;
-				}
-			} else {
-				kmem_cache_free(reference_cache, ref);
-			}
-			rc->rc_count -=3D number;
-			count =3D rc->rc_count;
-			mutex_exit(&rc->rc_mtx);
-			return (count);
-		}
-	}
-	panic("No such hold %p on refcount %llx", holder,
-	    (u_longlong_t)(uintptr_t)rc);
-	return (-1);
-}
-
-int64_t
-refcount_remove(refcount_t *rc, void *holder)
-{
-	return (refcount_remove_many(rc, 1, holder));
-}
-
-void
-refcount_transfer(refcount_t *dst, refcount_t *src)
-{
-	int64_t count, removed_count;
-	list_t list, removed;
-
-	list_create(&list, sizeof (reference_t),
-	    offsetof(reference_t, ref_link));
-	list_create(&removed, sizeof (reference_t),
-	    offsetof(reference_t, ref_link));
-
-	mutex_enter(&src->rc_mtx);
-	count =3D src->rc_count;
-	removed_count =3D src->rc_removed_count;
-	src->rc_count =3D 0;
-	src->rc_removed_count =3D 0;
-	list_move_tail(&list, &src->rc_list);
-	list_move_tail(&removed, &src->rc_removed);
-	mutex_exit(&src->rc_mtx);
-
-	mutex_enter(&dst->rc_mtx);
-	dst->rc_count +=3D count;
-	dst->rc_removed_count +=3D removed_count;
-	list_move_tail(&dst->rc_list, &list);
-	list_move_tail(&dst->rc_removed, &removed);
-	mutex_exit(&dst->rc_mtx);
-
-	list_destroy(&list);
-	list_destroy(&removed);
-}
-
-#endif	/* ZFS_DEBUG */
Index: sys/cddl/contrib/opensolaris/uts/common/Makefile.files
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/Makefile.files	(revision 228798)
+++ sys/cddl/contrib/opensolaris/uts/common/Makefile.files	(working copy)
@@ -55,7 +55,6 @@
 	gzip.o			\
 	lzjb.o			\
 	metaslab.o		\
-	refcount.o		\
 	sa.o			\
 	sha256.o		\
 	spa.o			\
Index: sys/sys/refcount.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/sys/refcount.h	(revision 228798)
+++ sys/sys/refcount.h	(working copy)
@@ -40,22 +40,24 @@
 #define	KASSERT(exp, msg)	/* */
 #endif
=20
+typedef volatile u_int refcount_t;
+
 static __inline void
-refcount_init(volatile u_int *count, u_int value)
+refcount_init(refcount_t *count, u_int value)
 {
=20
 	*count =3D value;
 }
=20
 static __inline void
-refcount_acquire(volatile u_int *count)
+refcount_acquire(refcount_t *count)
 {
=20
 	atomic_add_acq_int(count, 1);=09
 }
=20
 static __inline int
-refcount_release(volatile u_int *count)
+refcount_release(refcount_t *count)
 {
 	u_int old;
=20
Index: share/man/man9/refcount.9
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- share/man/man9/refcount.9	(revision 228798)
+++ share/man/man9/refcount.9	(working copy)
@@ -39,11 +39,11 @@
 .In sys/param.h
 .In sys/refcount.h
 .Ft void
-.Fn refcount_init "volatile u_int *count, u_int value"
+.Fn refcount_init "refcount_t *count, u_int value"
 .Ft void
-.Fn refcount_acquire "volatile u_int *count"
+.Fn refcount_acquire "refcount_t *count"
 .Ft int
-.Fn refcount_release "volatile u_int *count"
+.Fn refcount_release "refcount_t *count"
 .Sh DESCRIPTION
 The
 .Nm
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(revision=
 228798)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h	(working =
copy)
@@ -31,10 +31,6 @@
 #include <sys/list.h>
 #include <sys/zfs_context.h>
=20
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
 /*
  * If the reference is held only by the calling function and not any
  * particular object, use FTAG (which is a string) for the holder_tag.
@@ -42,68 +38,21 @@
  */
 #define	FTAG ((char *)__func__)
=20
-#ifdef	ZFS_DEBUG
-typedef struct reference {
-	list_node_t ref_link;
-	void *ref_holder;
-	uint64_t ref_number;
-	uint8_t *ref_removed;
-} reference_t;
-
-typedef struct refcount {
-	kmutex_t rc_mtx;
-	list_t rc_list;
-	list_t rc_removed;
-	int64_t rc_count;
-	int64_t rc_removed_count;
-} refcount_t;
-
-/* Note: refcount_t must be initialized with refcount_create() */
-
-void refcount_create(refcount_t *rc);
-void refcount_destroy(refcount_t *rc);
-void refcount_destroy_many(refcount_t *rc, uint64_t number);
-int refcount_is_zero(refcount_t *rc);
-int64_t refcount_count(refcount_t *rc);
-int64_t refcount_add(refcount_t *rc, void *holder_tag);
-int64_t refcount_remove(refcount_t *rc, void *holder_tag);
-int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_ta=
g);
-int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder=
_tag);
-void refcount_transfer(refcount_t *dst, refcount_t *src);
-
-void refcount_sysinit(void);
-void refcount_fini(void);
-
-#else	/* ZFS_DEBUG */
-
-typedef struct refcount {
-	uint64_t rc_count;
-} refcount_t;
-
-#define	refcount_create(rc) ((rc)->rc_count =3D 0)
-#define	refcount_destroy(rc) ((rc)->rc_count =3D 0)
-#define	refcount_destroy_many(rc, number) ((rc)->rc_count =3D 0)
-#define	refcount_is_zero(rc) ((rc)->rc_count =3D=3D 0)
-#define	refcount_count(rc) ((rc)->rc_count)
-#define	refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
-#define	refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
+#define	refcount_create(rc)		refcount_init(rc, 0)
+#define	refcount_destroy(rc)		refcount_init(rc, 0)
+#define	refcount_destroy_many(rc, number) refcount_init(rc, 0)
+#define	refcount_is_zero(rc)		((*rc) =3D=3D 0)
+#define	refcount_count(rc)		(uint64_t)(*rc)
+#define	refcount_add(rc, holder)	refcount_add_many(rc, 1, holder)
+#define	refcount_remove(rc, holder)	refcount_remove_many(rc, 1, holder)
 #define	refcount_add_many(rc, number, holder) \
-	atomic_add_64_nv(&(rc)->rc_count, number)
+	(uint64_t)(atomic_fetchadd_int(rc, number) + (number))
 #define	refcount_remove_many(rc, number, holder) \
-	atomic_add_64_nv(&(rc)->rc_count, -number)
-#define	refcount_transfer(dst, src) { \
-	uint64_t __tmp =3D (src)->rc_count; \
-	atomic_add_64(&(src)->rc_count, -__tmp); \
-	atomic_add_64(&(dst)->rc_count, __tmp); \
-}
+	(uint64_t)(atomic_fetchadd_int(rc, -(number)) - (number))
+#define	refcount_transfer(dst, src) \
+	atomic_add_int(dst, atomic_readandclear_int(src))
=20
 #define	refcount_sysinit()
 #define	refcount_fini()
=20
-#endif	/* ZFS_DEBUG */
-
-#ifdef	__cplusplus
-}
-#endif
-
 #endif /* _SYS_REFCOUNT_H */
Index: sys/sys/refcount.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/sys/refcount.h	(revision 228798)
+++ sys/sys/refcount.h	(working copy)
@@ -40,22 +40,24 @@
 #define	KASSERT(exp, msg)	/* */
 #endif
=20
+typedef volatile u_int refcount_t;
+
 static __inline void
-refcount_init(volatile u_int *count, u_int value)
+refcount_init(refcount_t *count, u_int value)
 {
=20
 	*count =3D value;
 }
=20
 static __inline void
-refcount_acquire(volatile u_int *count)
+refcount_acquire(refcount_t *count)
 {
=20
 	atomic_add_acq_int(count, 1);=09
 }
=20
 static __inline int
-refcount_release(volatile u_int *count)
+refcount_release(refcount_t *count)
 {
 	u_int old;
=20

--Q68bSM7Ycu6FN28Q--

--l76fUT7nc3MelDdI
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----

iQEbBAEBAgAGBQJO9A0wAAoJEJBXh4mJ2FR+RUEH9i3WwPABKGwt2gUFbB6P/upv
Rs3nOi8u8srpykiEa7lWQ6Oe7HwcDh6nhdTd8OxCAfy8+eZu/C4nz/npFRy0d1Kr
zH//wpEhSHom8odqVGGNMgerZrxCfHKxnji94zSUMSdY49PKBGKOia9aCzf7IJ6i
nNRXaO36Ryt0Kpny9kBqKByLs9Zb7d0hrowRHwaepiaHZJ7IObKIi7Rpnw2daqsc
+n9rxz4QVd2pmhtuib265Ci04BAkCrwO9GmVS6dSJh9jq1X3oYMSEMBsrFJnr948
IvAoImV+itrAMM3K9dRlERtMXSJZ4sHvSS66y8CREhOHwsmoU6nvQkPVCf8jPw==
=d/j5
-----END PGP SIGNATURE-----

--l76fUT7nc3MelDdI--



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