Split the WITNESS and MUTEX_DEBUG options apart so that WITNESS does not

depend on MUTEX_DEBUG.  The MUTEX_DEBUG option turns on extra assertions
and checks to verify that mutexes themselves are implemented properly.
The WITNESS option uses extra checks and diagnostics to verify that other
code is using mutexes properly.
This commit is contained in:
John Baldwin 2000-12-01 00:10:59 +00:00
parent d30cc7112b
commit 6936206ebd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69429
4 changed files with 42 additions and 36 deletions

View File

@ -85,17 +85,17 @@
* Machine independent bits of the mutex implementation
*/
/* All mutexes in system (used for debug/panic) */
#ifdef MUTEX_DEBUG
#ifdef WITNESS
static struct mtx_debug all_mtx_debug = { NULL, {NULL, NULL}, NULL, 0,
"All mutexes queue head" };
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, &all_mtx_debug,
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#else /* MUTEX_DEBUG */
#else /* WITNESS */
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, "All mutexes queue head",
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#endif /* MUTEX_DEBUG */
#endif /* WITNESS */
static int mtx_cur_cnt;
static int mtx_max_cnt;
@ -578,7 +578,7 @@ mtx_validate(struct mtx *m, int when)
void
mtx_init(struct mtx *m, const char *t, int flag)
{
#ifdef MUTEX_DEBUG
#ifdef WITNESS
struct mtx_debug *debug;
#endif
@ -586,6 +586,8 @@ mtx_init(struct mtx *m, const char *t, int flag)
#ifdef MUTEX_DEBUG
if (mtx_validate(m, MV_INIT)) /* diagnostic and error correction */
return;
#endif
#ifdef WITNESS
if (flag & MTX_COLD)
debug = m->mtx_debug;
else
@ -604,7 +606,7 @@ mtx_init(struct mtx *m, const char *t, int flag)
#endif
bzero((void *)m, sizeof *m);
TAILQ_INIT(&m->mtx_blocked);
#ifdef MUTEX_DEBUG
#ifdef WITNESS
m->mtx_debug = debug;
#endif
m->mtx_description = t;
@ -650,6 +652,8 @@ mtx_destroy(struct mtx *m)
m->mtx_prev->mtx_next = m->mtx_next;
#ifdef MUTEX_DEBUG
m->mtx_next = m->mtx_prev = NULL;
#endif
#ifdef WITNESS
free(m->mtx_debug, M_DEVBUF);
m->mtx_debug = NULL;
#endif
@ -659,10 +663,9 @@ mtx_destroy(struct mtx *m)
/*
* The non-inlined versions of the mtx_*() functions are always built (above),
* but the witness code depends on the MUTEX_DEBUG and WITNESS kernel options
* being specified.
* but the witness code depends on the WITNESS kernel option being specified.
*/
#if (defined(MUTEX_DEBUG) && defined(WITNESS))
#ifdef WITNESS
#define WITNESS_COUNT 200
#define WITNESS_NCHILDREN 2
@ -1377,4 +1380,4 @@ witness_restore(struct mtx *m, const char *file, int line)
m->mtx_witness->w_line = line;
}
#endif /* (defined(MUTEX_DEBUG) && defined(WITNESS)) */
#endif /* WITNESS */

View File

@ -85,17 +85,17 @@
* Machine independent bits of the mutex implementation
*/
/* All mutexes in system (used for debug/panic) */
#ifdef MUTEX_DEBUG
#ifdef WITNESS
static struct mtx_debug all_mtx_debug = { NULL, {NULL, NULL}, NULL, 0,
"All mutexes queue head" };
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, &all_mtx_debug,
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#else /* MUTEX_DEBUG */
#else /* WITNESS */
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, "All mutexes queue head",
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#endif /* MUTEX_DEBUG */
#endif /* WITNESS */
static int mtx_cur_cnt;
static int mtx_max_cnt;
@ -578,7 +578,7 @@ mtx_validate(struct mtx *m, int when)
void
mtx_init(struct mtx *m, const char *t, int flag)
{
#ifdef MUTEX_DEBUG
#ifdef WITNESS
struct mtx_debug *debug;
#endif
@ -586,6 +586,8 @@ mtx_init(struct mtx *m, const char *t, int flag)
#ifdef MUTEX_DEBUG
if (mtx_validate(m, MV_INIT)) /* diagnostic and error correction */
return;
#endif
#ifdef WITNESS
if (flag & MTX_COLD)
debug = m->mtx_debug;
else
@ -604,7 +606,7 @@ mtx_init(struct mtx *m, const char *t, int flag)
#endif
bzero((void *)m, sizeof *m);
TAILQ_INIT(&m->mtx_blocked);
#ifdef MUTEX_DEBUG
#ifdef WITNESS
m->mtx_debug = debug;
#endif
m->mtx_description = t;
@ -650,6 +652,8 @@ mtx_destroy(struct mtx *m)
m->mtx_prev->mtx_next = m->mtx_next;
#ifdef MUTEX_DEBUG
m->mtx_next = m->mtx_prev = NULL;
#endif
#ifdef WITNESS
free(m->mtx_debug, M_DEVBUF);
m->mtx_debug = NULL;
#endif
@ -659,10 +663,9 @@ mtx_destroy(struct mtx *m)
/*
* The non-inlined versions of the mtx_*() functions are always built (above),
* but the witness code depends on the MUTEX_DEBUG and WITNESS kernel options
* being specified.
* but the witness code depends on the WITNESS kernel option being specified.
*/
#if (defined(MUTEX_DEBUG) && defined(WITNESS))
#ifdef WITNESS
#define WITNESS_COUNT 200
#define WITNESS_NCHILDREN 2
@ -1377,4 +1380,4 @@ witness_restore(struct mtx *m, const char *file, int line)
m->mtx_witness->w_line = line;
}
#endif /* (defined(MUTEX_DEBUG) && defined(WITNESS)) */
#endif /* WITNESS */

View File

@ -85,17 +85,17 @@
* Machine independent bits of the mutex implementation
*/
/* All mutexes in system (used for debug/panic) */
#ifdef MUTEX_DEBUG
#ifdef WITNESS
static struct mtx_debug all_mtx_debug = { NULL, {NULL, NULL}, NULL, 0,
"All mutexes queue head" };
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, &all_mtx_debug,
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#else /* MUTEX_DEBUG */
#else /* WITNESS */
static struct mtx all_mtx = { MTX_UNOWNED, 0, 0, "All mutexes queue head",
TAILQ_HEAD_INITIALIZER(all_mtx.mtx_blocked),
{ NULL, NULL }, &all_mtx, &all_mtx };
#endif /* MUTEX_DEBUG */
#endif /* WITNESS */
static int mtx_cur_cnt;
static int mtx_max_cnt;
@ -578,7 +578,7 @@ mtx_validate(struct mtx *m, int when)
void
mtx_init(struct mtx *m, const char *t, int flag)
{
#ifdef MUTEX_DEBUG
#ifdef WITNESS
struct mtx_debug *debug;
#endif
@ -586,6 +586,8 @@ mtx_init(struct mtx *m, const char *t, int flag)
#ifdef MUTEX_DEBUG
if (mtx_validate(m, MV_INIT)) /* diagnostic and error correction */
return;
#endif
#ifdef WITNESS
if (flag & MTX_COLD)
debug = m->mtx_debug;
else
@ -604,7 +606,7 @@ mtx_init(struct mtx *m, const char *t, int flag)
#endif
bzero((void *)m, sizeof *m);
TAILQ_INIT(&m->mtx_blocked);
#ifdef MUTEX_DEBUG
#ifdef WITNESS
m->mtx_debug = debug;
#endif
m->mtx_description = t;
@ -650,6 +652,8 @@ mtx_destroy(struct mtx *m)
m->mtx_prev->mtx_next = m->mtx_next;
#ifdef MUTEX_DEBUG
m->mtx_next = m->mtx_prev = NULL;
#endif
#ifdef WITNESS
free(m->mtx_debug, M_DEVBUF);
m->mtx_debug = NULL;
#endif
@ -659,10 +663,9 @@ mtx_destroy(struct mtx *m)
/*
* The non-inlined versions of the mtx_*() functions are always built (above),
* but the witness code depends on the MUTEX_DEBUG and WITNESS kernel options
* being specified.
* but the witness code depends on the WITNESS kernel option being specified.
*/
#if (defined(MUTEX_DEBUG) && defined(WITNESS))
#ifdef WITNESS
#define WITNESS_COUNT 200
#define WITNESS_NCHILDREN 2
@ -1377,4 +1380,4 @@ witness_restore(struct mtx *m, const char *file, int line)
m->mtx_witness->w_line = line;
}
#endif /* (defined(MUTEX_DEBUG) && defined(WITNESS)) */
#endif /* WITNESS */

View File

@ -86,7 +86,7 @@
#endif /* _KERNEL */
#ifdef MUTEX_DEBUG
#ifdef WITNESS
struct mtx_debug {
/* If you add anything here, adjust the mtxf_t definition below */
struct witness *mtxd_witness;
@ -101,7 +101,7 @@ struct mtx_debug {
#define mtx_line mtx_debug->mtxd_line
#define mtx_file mtx_debug->mtxd_file
#define mtx_witness mtx_debug->mtxd_witness
#endif
#endif /* WITNESS */
/*
* Sleep/spin mutex
@ -110,7 +110,7 @@ struct mtx {
volatile uintptr_t mtx_lock; /* lock owner/gate/flags */
volatile u_int mtx_recurse; /* number of recursive holds */
u_int mtx_saveintr; /* saved flags (for spin locks) */
#ifdef MUTEX_DEBUG
#ifdef WITNESS
struct mtx_debug *mtx_debug;
#else
const char *mtx_description;
@ -121,7 +121,7 @@ struct mtx {
struct mtx *mtx_prev;
};
#ifdef MUTEX_DEBUG
#ifdef WITNESS
#define MUTEX_DECLARE(modifiers, name) \
static struct mtx_debug __mtx_debug_##name; \
modifiers struct mtx name = { 0, 0, 0, &__mtx_debug_##name }
@ -262,9 +262,6 @@ do { \
#endif /* MUTEX_DEBUG */
#ifdef WITNESS
#ifndef MUTEX_DEBUG
#error WITNESS requires MUTEX_DEBUG
#endif /* MUTEX_DEBUG */
#define WITNESS_ENTER(m, t, f, l) \
if ((m)->mtx_witness != NULL) \
witness_enter((m), (t), (f), (l))
@ -550,12 +547,12 @@ _mtx_try_enter(struct mtx *mtxp, int type, const char *file, int line)
int rval;
rval = _obtain_lock(mpp, CURTHD);
#ifdef MUTEX_DEBUG
#ifdef WITNESS
if (rval && mpp->mtx_witness != NULL) {
MPASS(mpp->mtx_recurse == 0);
witness_try_enter(mpp, type, file, line);
}
#endif
#endif /* WITNESS */
CTR5(KTR_LOCK, STR_mtx_try_enter_fmt,
mpp->mtx_description, mpp, rval, file, line);