Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Feb 2002 23:23:35 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        cvs-all@FreeBSD.org, cvs-committers@FreeBSD.org, Seigo Tanimura <tanimura@FreeBSD.org>, Alfred Perlstein <bright@mu.org>
Subject:   Re: cvs commit: src/sys/coda coda_venus.c src/sys/compat/linproc
Message-ID:  <200202260723.g1Q7NZI57016@apollo.backplane.com>
References:   <XFMail.020226020930.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

:>     This would be very easy to do.  Since witness already uses curthread
:>     we simply have a field in curthread indicating that we are holding a
:>     pool mutex.  If witness_lock() sees this set then it complains.  The
:>     pool mutexes could be init'd with another MTX flag indicating that
:>     they are leaf mutexes (i.e. MTX_LEAF).
:> 
:>     It is so easy it might be useful to do this test for INVARIANTS in
:>     general without requiring WITNESS to be turned on.
:> 
:>     What do you think John?
:
:The problem is that you are using mutex pool locks for two different types of
:locks: real leaf locks that need lock order checks, and locks used to implement
:higher level primitives such as sx locks and lockmgr locks.  These first locks
:need to be checked with witness, but the second do not.
:-- 
:
:John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
:"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

    I have a patch set to add MTX_LEAF support to the witness code, but
    at the moment it has been set aside (too many other fish to fry) and
    I don't know if I even have the test in the right place.  If you want
    to comment on that I can have another go at it later (or someone else
    can have a go at it).

    The patch adds support to WITNESS but was also designed to make it easy
    to add INVARIANTS support without WITNESS, but I hadn't gotten that far
    into the coding before I set it aside. 

						-Matt

Index: kern/kern_mtxpool.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_mtxpool.c,v
retrieving revision 1.3
diff -u -r1.3 kern_mtxpool.c
--- kern/kern_mtxpool.c	19 Nov 2001 00:20:36 -0000	1.3
+++ kern/kern_mtxpool.c	23 Feb 2002 23:49:46 -0000
@@ -63,7 +63,7 @@
     int i;
 
     for (i = 0; i < MTX_POOL_SIZE; ++i)
-	mtx_init(&mtx_pool_ary[i], "pool mutex", MTX_DEF | MTX_NOWITNESS | MTX_QUIET);
+	mtx_init(&mtx_pool_ary[i], "pool mutex", MTX_DEF | MTX_LEAF);
     mtx_pool_valid = 1;
 }
 
Index: kern/kern_mutex.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_mutex.c,v
retrieving revision 1.81
diff -u -r1.81 kern_mutex.c
--- kern/kern_mutex.c	20 Feb 2002 21:25:44 -0000	1.81
+++ kern/kern_mutex.c	23 Feb 2002 23:51:10 -0000
@@ -625,7 +625,7 @@
 	struct lock_object *lock;
 
 	MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE |
-	    MTX_SLEEPABLE | MTX_NOWITNESS)) == 0);
+	    MTX_SLEEPABLE | MTX_NOWITNESS | MTX_LEAF)) == 0);
 
 #ifdef MUTEX_DEBUG
 	/* Diagnostic and error correction */
@@ -643,6 +643,8 @@
 	lock->lo_name = description;
 	if (opts & MTX_QUIET)
 		lock->lo_flags = LO_QUIET;
+	if (opts & MTX_LEAF)
+		lock->lo_flags |= LO_LEAF;
 	if (opts & MTX_RECURSE)
 		lock->lo_flags |= LO_RECURSABLE;
 	if (opts & MTX_SLEEPABLE)
Index: kern/subr_witness.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_witness.c,v
retrieving revision 1.98
diff -u -r1.98 subr_witness.c
--- kern/subr_witness.c	23 Feb 2002 11:12:54 -0000	1.98
+++ kern/subr_witness.c	24 Feb 2002 00:00:47 -0000
@@ -489,6 +489,24 @@
 		lock_list = PCPU_PTR(spinlocks);
 
 	/*
+	 * Manage LO_LEAF locks.  It is not legal to obtain a new lock
+	 * if holding a leaf lock unless it is the scheduler.
+	 */
+	if (td->td_leafmtx && lock != &sched_lock.mtx_object) {
+		printf("warning, obtaining mutex %s while holding leaf mutex @ %s:%d\n", lock->lo_name, file, line);
+	}
+
+	/*
+	 * Leaf locks are, well, leaf locks.  They are always at the bottom
+	 * of the order except in regards to the scheduler lock so we do not
+	 * have to do any order checking.
+	 */
+	if (flags & LO_LEAF) {
+		++td->td_leafmtx;
+		goto out;
+	}
+
+	/*
 	 * Try locks do not block if they fail to acquire the lock, thus
 	 * there is no danger of deadlocks or of switching while holding a
 	 * spin lock if we acquire a lock via a try operation.
@@ -814,6 +832,11 @@
 					    instance->li_file,
 					    instance->li_line);
 					panic("share->uexcl");
+				}
+				if (flags & LO_LEAF) {
+					--td->td_leafmtx;
+					if (td->td_leafmtx < 0)
+						panic("leaf count negative");
 				}
 				/* If we are recursed, unrecurse. */
 				if ((instance->li_flags & LI_RECURSEMASK) > 0) {
Index: sys/lock.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/lock.h,v
retrieving revision 1.42
diff -u -r1.42 lock.h
--- sys/lock.h	5 Jan 2002 08:47:13 -0000	1.42
+++ sys/lock.h	23 Feb 2002 23:52:09 -0000
@@ -69,6 +69,7 @@
 #define	LO_RECURSABLE	0x00080000	/* Lock may recurse. */
 #define	LO_SLEEPABLE	0x00100000	/* Lock may be held while sleeping. */
 #define	LO_UPGRADABLE	0x00200000	/* Lock may be upgraded/downgraded. */
+#define	LO_LEAF		0x00400000	/* leaf lock (other then sched_lock) */
 
 #define	LI_RECURSEMASK	0x0000ffff	/* Recursion depth of lock instance. */
 #define	LI_SLEPT	0x00010000	/* Lock instance has been slept with. */
Index: sys/mutex.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/mutex.h,v
retrieving revision 1.49
diff -u -r1.49 mutex.h
--- sys/mutex.h	18 Feb 2002 17:51:46 -0000	1.49
+++ sys/mutex.h	23 Feb 2002 23:52:37 -0000
@@ -57,6 +57,7 @@
 #define MTX_RECURSE	0x00000004	/* Option: lock allowed to recurse */
 #define	MTX_NOWITNESS	0x00000008	/* Don't do any witness checking. */
 #define	MTX_SLEEPABLE	0x00000010	/* We can sleep with this lock. */
+#define MTX_LEAF	0x00000020	/* leaf mutex (other then sched_lock) */
 
 /*
  * Option flags passed to certain lock/unlock routines, through the use
Index: sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.206
diff -u -r1.206 proc.h
--- sys/proc.h	23 Feb 2002 11:12:57 -0000	1.206
+++ sys/proc.h	23 Feb 2002 23:27:27 -0000
@@ -273,6 +273,8 @@
 	const char	*td_mtxname;	/* (j) Name of mutex blocked on. */
 	LIST_HEAD(, mtx) td_contested;	/* (j) Contested locks. */
 	struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */
+	short		td_leafmtx;	/* (k) leaf mutex held */
+	short		td_unused01;
 	int		td_intr_nesting_level; /* (k) Interrupt recursion. */
 #define	td_endzero td_md
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




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