Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Jul 2019 17:09:58 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r350450 - head/sys/kern
Message-ID:  <201907301709.x6UH9wTT021842@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Jul 30 17:09:58 2019
New Revision: 350450
URL: https://svnweb.freebsd.org/changeset/base/350450

Log:
  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

Modified:
  head/sys/kern/subr_witness.c

Modified: head/sys/kern/subr_witness.c
==============================================================================
--- head/sys/kern/subr_witness.c	Tue Jul 30 16:40:33 2019	(r350449)
+++ head/sys/kern/subr_witness.c	Tue Jul 30 17:09:58 2019	(r350450)
@@ -132,9 +132,6 @@ __FBSDID("$FreeBSD$");
 #define	LI_EXCLUSIVE	0x00010000	/* Exclusive lock instance. */
 #define	LI_NORELEASE	0x00020000	/* Lock not allowed to be released. */
 
-/* Define this to check for blessed mutexes */
-#undef BLESSING
-
 #ifndef WITNESS_COUNT
 #define	WITNESS_COUNT 		1536
 #endif
@@ -278,12 +275,10 @@ struct witness_lock_order_hash {
 	u_int	wloh_count;
 };
 
-#ifdef BLESSING
 struct witness_blessed {
 	const char	*b_lock1;
 	const char	*b_lock2;
 };
-#endif
 
 struct witness_pendhelp {
 	const char		*wh_type;
@@ -318,9 +313,7 @@ witness_lock_order_key_equal(const struct witness_lock
 static int	_isitmyx(struct witness *w1, struct witness *w2, int rmask,
 		    const char *fname);
 static void	adopt(struct witness *parent, struct witness *child);
-#ifdef BLESSING
 static int	blessed(struct witness *, struct witness *);
-#endif
 static void	depart(struct witness *w);
 static struct witness	*enroll(const char *description,
 			    struct lock_class *lock_class);
@@ -726,14 +719,25 @@ static struct witness_order_list_entry order_lists[] =
 	{ NULL, NULL }
 };
 
-#ifdef BLESSING
 /*
- * Pairs of locks which have been blessed
- * Don't complain about order problems with blessed locks
+ * Pairs of locks which have been blessed.  Witness does not complain about
+ * 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[] = {
+	/*
+	 * 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.
@@ -1339,7 +1343,6 @@ witness_checkorder(struct lock_object *lock, int flags
 			 * We have a lock order violation, check to see if it
 			 * is allowed or has already been yelled about.
 			 */
-#ifdef BLESSING
 
 			/*
 			 * If the lock order is blessed, just bail.  We don't
@@ -1348,7 +1351,6 @@ witness_checkorder(struct lock_object *lock, int flags
 			 */
 			if (blessed(w, w1))
 				goto out;
-#endif
 
 			/* Bail if this violation is known */
 			if (w_rmatrix[w1->w_index][w->w_index] & WITNESS_REVERSAL)
@@ -2084,7 +2086,6 @@ isitmydescendant(struct witness *ancestor, struct witn
 	    __func__));
 }
 
-#ifdef BLESSING
 static int
 blessed(struct witness *w1, struct witness *w2)
 {
@@ -2104,7 +2105,6 @@ blessed(struct witness *w1, struct witness *w2)
 	}
 	return (0);
 }
-#endif
 
 static struct witness *
 witness_get(void)



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