Enable witness(4) blessings.
witness has long had a facility to "bless" designated lock pairs. Lock order reversals between a pair of blessed locks are not reported upon. We have a number of long-standing false positive LOR reports; start marking well-understood LORs as blessed. This change hides reports about UFS vnode locks and the UFS dirhash lock, and UFS vnode locks and buffer locks, since those are the two that I observe most often. In the long term it would be preferable to be able to limit blessings to a specific site where a lock is acquired, and/or extend witness to understand why some lock order reversals are valid (for example, if code paths with conflicting lock orders are serialized by a third lock), but in the meantime the false positives frequently confuse users and generate bug reports. Reviewed by: cem, kib, mckusick MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21039
This commit is contained in:
parent
98197770c9
commit
49c3e8c8d1
@ -132,9 +132,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define LI_EXCLUSIVE 0x00010000 /* Exclusive lock instance. */
|
#define LI_EXCLUSIVE 0x00010000 /* Exclusive lock instance. */
|
||||||
#define LI_NORELEASE 0x00020000 /* Lock not allowed to be released. */
|
#define LI_NORELEASE 0x00020000 /* Lock not allowed to be released. */
|
||||||
|
|
||||||
/* Define this to check for blessed mutexes */
|
|
||||||
#undef BLESSING
|
|
||||||
|
|
||||||
#ifndef WITNESS_COUNT
|
#ifndef WITNESS_COUNT
|
||||||
#define WITNESS_COUNT 1536
|
#define WITNESS_COUNT 1536
|
||||||
#endif
|
#endif
|
||||||
@ -278,12 +275,10 @@ struct witness_lock_order_hash {
|
|||||||
u_int wloh_count;
|
u_int wloh_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef BLESSING
|
|
||||||
struct witness_blessed {
|
struct witness_blessed {
|
||||||
const char *b_lock1;
|
const char *b_lock1;
|
||||||
const char *b_lock2;
|
const char *b_lock2;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct witness_pendhelp {
|
struct witness_pendhelp {
|
||||||
const char *wh_type;
|
const char *wh_type;
|
||||||
@ -318,9 +313,7 @@ witness_lock_order_key_equal(const struct witness_lock_order_key *a,
|
|||||||
static int _isitmyx(struct witness *w1, struct witness *w2, int rmask,
|
static int _isitmyx(struct witness *w1, struct witness *w2, int rmask,
|
||||||
const char *fname);
|
const char *fname);
|
||||||
static void adopt(struct witness *parent, struct witness *child);
|
static void adopt(struct witness *parent, struct witness *child);
|
||||||
#ifdef BLESSING
|
|
||||||
static int blessed(struct witness *, struct witness *);
|
static int blessed(struct witness *, struct witness *);
|
||||||
#endif
|
|
||||||
static void depart(struct witness *w);
|
static void depart(struct witness *w);
|
||||||
static struct witness *enroll(const char *description,
|
static struct witness *enroll(const char *description,
|
||||||
struct lock_class *lock_class);
|
struct lock_class *lock_class);
|
||||||
@ -726,14 +719,25 @@ static struct witness_order_list_entry order_lists[] = {
|
|||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef BLESSING
|
|
||||||
/*
|
/*
|
||||||
* Pairs of locks which have been blessed
|
* Pairs of locks which have been blessed. Witness does not complain about
|
||||||
* Don't complain about order problems with blessed locks
|
* order problems with blessed lock pairs. Please do not add an entry to the
|
||||||
|
* table without an explanatory comment.
|
||||||
*/
|
*/
|
||||||
static struct witness_blessed blessed_list[] = {
|
static struct witness_blessed blessed_list[] = {
|
||||||
|
/*
|
||||||
|
* See the comment in ufs_dirhash.c. Basically, a vnode lock serializes
|
||||||
|
* both lock orders, so a deadlock cannot happen as a result of this
|
||||||
|
* LOR.
|
||||||
|
*/
|
||||||
|
{ "dirhash", "bufwait" },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A UFS vnode may be locked in vget() while a buffer belonging to the
|
||||||
|
* parent directory vnode is locked.
|
||||||
|
*/
|
||||||
|
{ "ufs", "bufwait" },
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This global is set to 0 once it becomes safe to use the witness code.
|
* This global is set to 0 once it becomes safe to use the witness code.
|
||||||
@ -1339,7 +1343,6 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
* We have a lock order violation, check to see if it
|
* We have a lock order violation, check to see if it
|
||||||
* is allowed or has already been yelled about.
|
* is allowed or has already been yelled about.
|
||||||
*/
|
*/
|
||||||
#ifdef BLESSING
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the lock order is blessed, just bail. We don't
|
* If the lock order is blessed, just bail. We don't
|
||||||
@ -1348,7 +1351,6 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
*/
|
*/
|
||||||
if (blessed(w, w1))
|
if (blessed(w, w1))
|
||||||
goto out;
|
goto out;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Bail if this violation is known */
|
/* Bail if this violation is known */
|
||||||
if (w_rmatrix[w1->w_index][w->w_index] & WITNESS_REVERSAL)
|
if (w_rmatrix[w1->w_index][w->w_index] & WITNESS_REVERSAL)
|
||||||
@ -2084,7 +2086,6 @@ isitmydescendant(struct witness *ancestor, struct witness *descendant)
|
|||||||
__func__));
|
__func__));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BLESSING
|
|
||||||
static int
|
static int
|
||||||
blessed(struct witness *w1, struct witness *w2)
|
blessed(struct witness *w1, struct witness *w2)
|
||||||
{
|
{
|
||||||
@ -2104,7 +2105,6 @@ blessed(struct witness *w1, struct witness *w2)
|
|||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct witness *
|
static struct witness *
|
||||||
witness_get(void)
|
witness_get(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user