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:
parent
d30cc7112b
commit
6936206ebd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69429
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user