Module Name: src Committed By: martin Date: Thu Nov 30 14:31:04 UTC 2017
Modified Files: src/sys/kern [netbsd-8]: subr_localcount.c src/sys/sys [netbsd-8]: localcount.h Log Message: Pull up following revision(s) (requested by ozaki-r in ticket #404): sys/sys/localcount.h: revision 1.5 sys/kern/subr_localcount.c: revision 1.7 Implement a debugging facility (overflow/underflow detection) for localcount We cannot get an accurate count from a localcount instance because it consists of per-cpu counters and we have no way to sum them up atomically. So we cannot detect counter overflow/underflow as we can do on a normal refcount. The facility adds an atomic counter to each localcount instance to enable the validations. The counter ups and downs in synchronization with the per-CPU counters. The counter is used iff both DEBUG and LOCKDEBUG are enabled in the kernel. Discussed on tech-kern@ To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/kern/subr_localcount.c cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/sys/localcount.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_localcount.c diff -u src/sys/kern/subr_localcount.c:1.4 src/sys/kern/subr_localcount.c:1.4.2.1 --- src/sys/kern/subr_localcount.c:1.4 Fri Jun 2 00:32:12 2017 +++ src/sys/kern/subr_localcount.c Thu Nov 30 14:31:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_localcount.c,v 1.4 2017/06/02 00:32:12 chs Exp $ */ +/* $NetBSD: subr_localcount.c,v 1.4.2.1 2017/11/30 14:31:04 martin Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.4 2017/06/02 00:32:12 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.4.2.1 2017/11/30 14:31:04 martin Exp $"); #include <sys/param.h> #include <sys/localcount.h> @@ -54,6 +54,9 @@ __KERNEL_RCSID(0, "$NetBSD: subr_localco #include <sys/mutex.h> #include <sys/percpu.h> #include <sys/xcall.h> +#if defined(DEBUG) && defined(LOCKDEBUG) +#include <sys/atomic.h> +#endif /* * localcount_init(lc) @@ -203,6 +206,10 @@ localcount_acquire(struct localcount *lc KASSERT(lc->lc_totalp == NULL); localcount_adjust(lc, +1); +#if defined(DEBUG) && defined(LOCKDEBUG) + if (atomic_inc_32_nv(&lc->lc_refcnt) == 0) + panic("counter overflow"); +#endif } /* @@ -247,5 +254,26 @@ localcount_release(struct localcount *lc } localcount_adjust(lc, -1); +#if defined(DEBUG) && defined(LOCKDEBUG) + if (atomic_dec_32_nv(&lc->lc_refcnt) == UINT_MAX) + panic("counter underflow"); +#endif out: kpreempt_enable(); } + +/* + * localcount_debug_refcnt(lc) + * + * Return a total reference count of lc. It returns a correct value + * only if DEBUG and LOCKDEBUG enabled. Otherwise always return 0. + */ +uint32_t +localcount_debug_refcnt(const struct localcount *lc) +{ + +#if defined(DEBUG) && defined(LOCKDEBUG) + return lc->lc_refcnt; +#else + return 0; +#endif +} Index: src/sys/sys/localcount.h diff -u src/sys/sys/localcount.h:1.4 src/sys/sys/localcount.h:1.4.2.1 --- src/sys/sys/localcount.h:1.4 Fri Jun 2 00:32:12 2017 +++ src/sys/sys/localcount.h Thu Nov 30 14:31:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: localcount.h,v 1.4 2017/06/02 00:32:12 chs Exp $ */ +/* $NetBSD: localcount.h,v 1.4.2.1 2017/11/30 14:31:04 martin Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -43,8 +43,9 @@ struct kmutex; struct percpu; struct localcount { - int64_t *lc_totalp; - struct percpu *lc_percpu; /* int64_t */ + int64_t *lc_totalp; + struct percpu *lc_percpu; /* int64_t */ + volatile uint32_t lc_refcnt; /* only for debugging */ }; void localcount_init(struct localcount *); @@ -55,4 +56,7 @@ void localcount_acquire(struct localcoun void localcount_release(struct localcount *, struct kcondvar *, struct kmutex *); +uint32_t + localcount_debug_refcnt(const struct localcount *); + #endif /* _SYS_LOCALCOUNT_H */