Date: Sun, 21 Jun 2015 00:36:03 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r284653 - stable/10/sys/kern Message-ID: <201506210036.t5L0a3Cd073891@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Sun Jun 21 00:36:02 2015 New Revision: 284653 URL: https://svnweb.freebsd.org/changeset/base/284653 Log: MFC r284127: witness: don't warn about matrix inconsistencies without holding the mutex Lock order checking is done without the witness mutex held, so multiple threads that are racing to establish a new lock order may read matrix entries that are in an inconsistent state. Don't print a warning in this case, but instead just redo the check after taking the witness lock. Modified: stable/10/sys/kern/subr_witness.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/subr_witness.c ============================================================================== --- stable/10/sys/kern/subr_witness.c Sat Jun 20 23:15:57 2015 (r284652) +++ stable/10/sys/kern/subr_witness.c Sun Jun 21 00:36:02 2015 (r284653) @@ -1167,19 +1167,25 @@ witness_checkorder(struct lock_object *l /* * Try to perform most checks without a lock. If this succeeds we - * can skip acquiring the lock and return success. + * can skip acquiring the lock and return success. Otherwise we redo + * the check with the lock held to handle races with concurrent updates. */ w1 = plock->li_lock->lo_witness; if (witness_lock_order_check(w1, w)) return; + mtx_lock_spin(&w_mtx); + if (witness_lock_order_check(w1, w)) { + mtx_unlock_spin(&w_mtx); + return; + } + witness_lock_order_add(w1, w); + /* * Check for duplicate locks of the same type. Note that we only * have to check for this on the last lock we just acquired. Any * other cases will be caught as lock order violations. */ - mtx_lock_spin(&w_mtx); - witness_lock_order_add(w1, w); if (w1 == w) { i = w->w_index; if (!(lock->lo_flags & LO_DUPOK) && !(flags & LOP_DUPOK) && @@ -1993,7 +1999,10 @@ _isitmyx(struct witness *w1, struct witn /* The flags on one better be the inverse of the flags on the other */ if (!((WITNESS_ATOD(r1) == r2 && WITNESS_DTOA(r2) == r1) || - (WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) { + (WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) { + /* Don't squawk if we're potentially racing with an update. */ + if (!mtx_owned(&w_mtx)) + return (0); printf("%s: rmatrix mismatch between %s (index %d) and %s " "(index %d): w_rmatrix[%d][%d] == %hhx but " "w_rmatrix[%d][%d] == %hhx\n",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506210036.t5L0a3Cd073891>