Date: Sun, 7 Jun 2015 18:59:48 +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: r284127 - head/sys/kern Message-ID: <201506071859.t57Ixm6T036074@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Sun Jun 7 18:59:47 2015 New Revision: 284127 URL: https://svnweb.freebsd.org/changeset/base/284127 Log: 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. Differential Revision: https://reviews.freebsd.org/D2713 Reviewed by: jhb MFC after: 2 weeks Sponsored by: EMC / Isilon Storage Division Modified: head/sys/kern/subr_witness.c Modified: head/sys/kern/subr_witness.c ============================================================================== --- head/sys/kern/subr_witness.c Sun Jun 7 15:54:57 2015 (r284126) +++ head/sys/kern/subr_witness.c Sun Jun 7 18:59:47 2015 (r284127) @@ -1170,19 +1170,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) && @@ -1996,7 +2002,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?201506071859.t57Ixm6T036074>