kern_mutex.c revision 165265
1/*-
2 * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 * 3. Berkeley Software Design Inc's name may not be used to endorse or
13 *    promote products derived from this software without specific prior
14 *    written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *	from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
29 *	and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
30 */
31
32/*
33 * Machine independent bits of mutex implementation.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/kern/kern_mutex.c 165265 2006-12-16 02:37:58Z kmacy $");
38
39#include "opt_adaptive_mutexes.h"
40#include "opt_ddb.h"
41#include "opt_global.h"
42#include "opt_mutex_wake_all.h"
43#include "opt_sched.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/bus.h>
48#include <sys/conf.h>
49#include <sys/kdb.h>
50#include <sys/kernel.h>
51#include <sys/ktr.h>
52#include <sys/lock.h>
53#include <sys/malloc.h>
54#include <sys/mutex.h>
55#include <sys/proc.h>
56#include <sys/resourcevar.h>
57#include <sys/sched.h>
58#include <sys/sbuf.h>
59#include <sys/sysctl.h>
60#include <sys/turnstile.h>
61#include <sys/vmmeter.h>
62#include <sys/lock_profile.h>
63
64#include <machine/atomic.h>
65#include <machine/bus.h>
66#include <machine/cpu.h>
67
68#include <ddb/ddb.h>
69
70#include <fs/devfs/devfs_int.h>
71
72#include <vm/vm.h>
73#include <vm/vm_extern.h>
74
75/*
76 * Force MUTEX_WAKE_ALL for now.
77 * single thread wakeup needs fixes to avoid race conditions with
78 * priority inheritance.
79 */
80#ifndef MUTEX_WAKE_ALL
81#define MUTEX_WAKE_ALL
82#endif
83
84/*
85 * Internal utility macros.
86 */
87#define mtx_unowned(m)	((m)->mtx_lock == MTX_UNOWNED)
88
89#define	mtx_owner(m)	((struct thread *)((m)->mtx_lock & ~MTX_FLAGMASK))
90
91#ifdef DDB
92static void	db_show_mtx(struct lock_object *lock);
93#endif
94
95/*
96 * Lock classes for sleep and spin mutexes.
97 */
98struct lock_class lock_class_mtx_sleep = {
99	"sleep mutex",
100	LC_SLEEPLOCK | LC_RECURSABLE,
101#ifdef DDB
102	db_show_mtx
103#endif
104};
105struct lock_class lock_class_mtx_spin = {
106	"spin mutex",
107	LC_SPINLOCK | LC_RECURSABLE,
108#ifdef DDB
109	db_show_mtx
110#endif
111};
112
113/*
114 * System-wide mutexes
115 */
116struct mtx sched_lock;
117struct mtx Giant;
118
119#ifdef LOCK_PROFILING
120static inline void lock_profile_init(void)
121{
122        int i;
123        /* Initialize the mutex profiling locks */
124        for (i = 0; i < LPROF_LOCK_SIZE; i++) {
125                mtx_init(&lprof_locks[i], "mprof lock",
126                    NULL, MTX_SPIN|MTX_QUIET|MTX_NOPROFILE);
127        }
128}
129#else
130static inline void lock_profile_init(void) {;}
131#endif
132
133/*
134 * Function versions of the inlined __mtx_* macros.  These are used by
135 * modules and can also be called from assembly language if needed.
136 */
137void
138_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
139{
140	uint64_t waittime;
141
142	MPASS(curthread != NULL);
143	KASSERT(m->mtx_lock != MTX_DESTROYED,
144	    ("mtx_lock() of destroyed mutex @ %s:%d", file, line));
145	KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
146	    ("mtx_lock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
147	    file, line));
148	WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
149	    file, line);
150
151	lock_profile_waitstart(&waittime);
152	_get_sleep_lock(m, curthread, opts, file, line);
153	LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
154	    line);
155	WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
156	curthread->td_locks++;
157	lock_profile_obtain_lock_success(&m->mtx_object, waittime, file, line);
158}
159
160void
161_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
162{
163
164	MPASS(curthread != NULL);
165	KASSERT(m->mtx_lock != MTX_DESTROYED,
166	    ("mtx_unlock() of destroyed mutex @ %s:%d", file, line));
167	KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
168	    ("mtx_unlock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
169	    file, line));
170	curthread->td_locks--;
171	WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
172	LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
173	    line);
174	mtx_assert(m, MA_OWNED);
175
176	lock_profile_release_lock(&m->mtx_object);
177	_rel_sleep_lock(m, curthread, opts, file, line);
178}
179
180void
181_mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, int line)
182{
183
184	uint64_t waittime;
185
186	MPASS(curthread != NULL);
187	KASSERT(m->mtx_lock != MTX_DESTROYED,
188	    ("mtx_lock_spin() of destroyed mutex @ %s:%d", file, line));
189	KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin,
190	    ("mtx_lock_spin() of sleep mutex %s @ %s:%d",
191	    m->mtx_object.lo_name, file, line));
192	WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
193	    file, line);
194	lock_profile_waitstart(&waittime);
195	_get_spin_lock(m, curthread, opts, file, line);
196	LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
197	    line);
198	WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
199	lock_profile_obtain_lock_success(&m->mtx_object, waittime, file, line);
200}
201
202void
203_mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, int line)
204{
205
206	MPASS(curthread != NULL);
207	KASSERT(m->mtx_lock != MTX_DESTROYED,
208	    ("mtx_unlock_spin() of destroyed mutex @ %s:%d", file, line));
209	KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin,
210	    ("mtx_unlock_spin() of sleep mutex %s @ %s:%d",
211	    m->mtx_object.lo_name, file, line));
212	WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
213	LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
214	    line);
215	mtx_assert(m, MA_OWNED);
216	lock_profile_release_lock(&m->mtx_object);
217	_rel_spin_lock(m);
218}
219
220/*
221 * The important part of mtx_trylock{,_flags}()
222 * Tries to acquire lock `m.'  If this function is called on a mutex that
223 * is already owned, it will recursively acquire the lock.
224 */
225int
226_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
227{
228	int rval;
229	uint64_t waittime = 0;
230
231	MPASS(curthread != NULL);
232	KASSERT(m->mtx_lock != MTX_DESTROYED,
233	    ("mtx_trylock() of destroyed mutex @ %s:%d", file, line));
234	KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
235	    ("mtx_trylock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
236	    file, line));
237
238	if (mtx_owned(m) && (m->mtx_object.lo_flags & LO_RECURSABLE) != 0) {
239		m->mtx_recurse++;
240		atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
241		rval = 1;
242	} else
243		rval = _obtain_lock(m, (uintptr_t)curthread);
244
245	LOCK_LOG_TRY("LOCK", &m->mtx_object, opts, rval, file, line);
246	if (rval) {
247		WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE | LOP_TRYLOCK,
248		    file, line);
249		curthread->td_locks++;
250		lock_profile_obtain_lock_success(&m->mtx_object, waittime, file, line);
251
252	}
253
254	return (rval);
255}
256
257/*
258 * _mtx_lock_sleep: the tougher part of acquiring an MTX_DEF lock.
259 *
260 * We call this if the lock is either contested (i.e. we need to go to
261 * sleep waiting for it), or if we need to recurse on it.
262 */
263void
264_mtx_lock_sleep(struct mtx *m, uintptr_t tid, int opts, const char *file,
265    int line)
266{
267#if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
268	volatile struct thread *owner;
269#endif
270#ifdef KTR
271	int cont_logged = 0;
272#endif
273	uintptr_t v;
274	int contested = 0;
275
276	if (mtx_owned(m)) {
277		KASSERT((m->mtx_object.lo_flags & LO_RECURSABLE) != 0,
278	    ("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
279		    m->mtx_object.lo_name, file, line));
280		m->mtx_recurse++;
281		atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
282		if (LOCK_LOG_TEST(&m->mtx_object, opts))
283			CTR1(KTR_LOCK, "_mtx_lock_sleep: %p recursing", m);
284		return;
285	}
286
287	if (LOCK_LOG_TEST(&m->mtx_object, opts))
288		CTR4(KTR_LOCK,
289		    "_mtx_lock_sleep: %s contested (lock=%p) at %s:%d",
290		    m->mtx_object.lo_name, (void *)m->mtx_lock, file, line);
291
292	while (!_obtain_lock(m, tid)) {
293		lock_profile_obtain_lock_failed(&m->mtx_object, &contested);
294		turnstile_lock(&m->mtx_object);
295		v = m->mtx_lock;
296
297		/*
298		 * Check if the lock has been released while spinning for
299		 * the turnstile chain lock.
300		 */
301		if (v == MTX_UNOWNED) {
302			turnstile_release(&m->mtx_object);
303			cpu_spinwait();
304			continue;
305		}
306
307#ifdef MUTEX_WAKE_ALL
308		MPASS(v != MTX_CONTESTED);
309#else
310		/*
311		 * The mutex was marked contested on release. This means that
312		 * there are other threads blocked on it.  Grab ownership of
313		 * it and propagate its priority to the current thread if
314		 * necessary.
315		 */
316		if (v == MTX_CONTESTED) {
317			m->mtx_lock = tid | MTX_CONTESTED;
318			turnstile_claim(&m->mtx_object);
319			break;
320		}
321#endif
322
323		/*
324		 * If the mutex isn't already contested and a failure occurs
325		 * setting the contested bit, the mutex was either released
326		 * or the state of the MTX_RECURSED bit changed.
327		 */
328		if ((v & MTX_CONTESTED) == 0 &&
329		    !atomic_cmpset_ptr(&m->mtx_lock, v, v | MTX_CONTESTED)) {
330			turnstile_release(&m->mtx_object);
331			cpu_spinwait();
332			continue;
333		}
334
335#if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
336		/*
337		 * If the current owner of the lock is executing on another
338		 * CPU, spin instead of blocking.
339		 */
340		owner = (struct thread *)(v & ~MTX_FLAGMASK);
341#ifdef ADAPTIVE_GIANT
342		if (TD_IS_RUNNING(owner))
343#else
344		if (m != &Giant && TD_IS_RUNNING(owner))
345#endif
346		{
347			turnstile_release(&m->mtx_object);
348			while (mtx_owner(m) == owner && TD_IS_RUNNING(owner)) {
349				cpu_spinwait();
350			}
351			continue;
352		}
353#endif	/* SMP && !NO_ADAPTIVE_MUTEXES */
354
355		/*
356		 * We definitely must sleep for this lock.
357		 */
358		mtx_assert(m, MA_NOTOWNED);
359
360#ifdef KTR
361		if (!cont_logged) {
362			CTR6(KTR_CONTENTION,
363			    "contention: %p at %s:%d wants %s, taken by %s:%d",
364			    (void *)tid, file, line, m->mtx_object.lo_name,
365			    WITNESS_FILE(&m->mtx_object),
366			    WITNESS_LINE(&m->mtx_object));
367			cont_logged = 1;
368		}
369#endif
370
371		/*
372		 * Block on the turnstile.
373		 */
374		turnstile_wait(&m->mtx_object, mtx_owner(m),
375		    TS_EXCLUSIVE_QUEUE);
376	}
377#ifdef KTR
378	if (cont_logged) {
379		CTR4(KTR_CONTENTION,
380		    "contention end: %s acquired by %p at %s:%d",
381		    m->mtx_object.lo_name, (void *)tid, file, line);
382	}
383#endif
384#ifdef LOCK_PROFILING
385	m->mtx_object.lo_profile_obj.lpo_contest_holding = 0;
386	if (contested)
387		m->mtx_object.lo_profile_obj.lpo_contest_locking++;
388#endif
389	return;
390}
391
392#ifdef SMP
393/*
394 * _mtx_lock_spin: the tougher part of acquiring an MTX_SPIN lock.
395 *
396 * This is only called if we need to actually spin for the lock. Recursion
397 * is handled inline.
398 */
399void
400_mtx_lock_spin(struct mtx *m, uintptr_t tid, int opts, const char *file,
401    int line)
402{
403	struct thread *td;
404	int contested = 0, i = 0;
405
406	if (LOCK_LOG_TEST(&m->mtx_object, opts))
407		CTR1(KTR_LOCK, "_mtx_lock_spin: %p spinning", m);
408
409	while (!_obtain_lock(m, tid)) {
410		lock_profile_obtain_lock_failed(&m->mtx_object, &contested);
411
412		/* Give interrupts a chance while we spin. */
413		spinlock_exit();
414		while (m->mtx_lock != MTX_UNOWNED) {
415			if (i++ < 10000000) {
416				cpu_spinwait();
417				continue;
418			}
419			if (i < 60000000 || kdb_active || panicstr != NULL)
420				DELAY(1);
421			else {
422				td = mtx_owner(m);
423
424				/* If the mutex is unlocked, try again. */
425				if (td == NULL)
426					continue;
427				printf(
428			"spin lock %p (%s) held by %p (tid %d) too long\n",
429				    m, m->mtx_object.lo_name, td, td->td_tid);
430#ifdef WITNESS
431				witness_display_spinlock(&m->mtx_object, td);
432#endif
433				panic("spin lock held too long");
434			}
435			cpu_spinwait();
436		}
437		spinlock_enter();
438	}
439
440	if (LOCK_LOG_TEST(&m->mtx_object, opts))
441		CTR1(KTR_LOCK, "_mtx_lock_spin: %p spin done", m);
442
443	return;
444}
445#endif /* SMP */
446
447/*
448 * _mtx_unlock_sleep: the tougher part of releasing an MTX_DEF lock.
449 *
450 * We are only called here if the lock is recursed or contested (i.e. we
451 * need to wake up a blocked thread).
452 */
453void
454_mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line)
455{
456	struct turnstile *ts;
457#ifndef PREEMPTION
458	struct thread *td, *td1;
459#endif
460
461	if (mtx_recursed(m)) {
462		if (--(m->mtx_recurse) == 0)
463			atomic_clear_ptr(&m->mtx_lock, MTX_RECURSED);
464		if (LOCK_LOG_TEST(&m->mtx_object, opts))
465			CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p unrecurse", m);
466		return;
467	}
468
469	turnstile_lock(&m->mtx_object);
470	ts = turnstile_lookup(&m->mtx_object);
471	if (LOCK_LOG_TEST(&m->mtx_object, opts))
472		CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p contested", m);
473
474#if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
475	if (ts == NULL) {
476		_release_lock_quick(m);
477		if (LOCK_LOG_TEST(&m->mtx_object, opts))
478			CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p no sleepers", m);
479		turnstile_release(&m->mtx_object);
480		return;
481	}
482#else
483	MPASS(ts != NULL);
484#endif
485#ifndef PREEMPTION
486	/* XXX */
487	td1 = turnstile_head(ts, TS_EXCLUSIVE_QUEUE);
488#endif
489#ifdef MUTEX_WAKE_ALL
490	turnstile_broadcast(ts, TS_EXCLUSIVE_QUEUE);
491	_release_lock_quick(m);
492#else
493	if (turnstile_signal(ts, TS_EXCLUSIVE_QUEUE)) {
494		_release_lock_quick(m);
495		if (LOCK_LOG_TEST(&m->mtx_object, opts))
496			CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p not held", m);
497	} else {
498		m->mtx_lock = MTX_CONTESTED;
499		if (LOCK_LOG_TEST(&m->mtx_object, opts))
500			CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p still contested",
501			    m);
502	}
503#endif
504	turnstile_unpend(ts, TS_EXCLUSIVE_LOCK);
505
506#ifndef PREEMPTION
507	/*
508	 * XXX: This is just a hack until preemption is done.  However,
509	 * once preemption is done we need to either wrap the
510	 * turnstile_signal() and release of the actual lock in an
511	 * extra critical section or change the preemption code to
512	 * always just set a flag and never do instant-preempts.
513	 */
514	td = curthread;
515	if (td->td_critnest > 0 || td1->td_priority >= td->td_priority)
516		return;
517	mtx_lock_spin(&sched_lock);
518	if (!TD_IS_RUNNING(td1)) {
519#ifdef notyet
520		if (td->td_ithd != NULL) {
521			struct ithd *it = td->td_ithd;
522
523			if (it->it_interrupted) {
524				if (LOCK_LOG_TEST(&m->mtx_object, opts))
525					CTR2(KTR_LOCK,
526				    "_mtx_unlock_sleep: %p interrupted %p",
527					    it, it->it_interrupted);
528				intr_thd_fixup(it);
529			}
530		}
531#endif
532		if (LOCK_LOG_TEST(&m->mtx_object, opts))
533			CTR2(KTR_LOCK,
534			    "_mtx_unlock_sleep: %p switching out lock=%p", m,
535			    (void *)m->mtx_lock);
536
537		mi_switch(SW_INVOL, NULL);
538		if (LOCK_LOG_TEST(&m->mtx_object, opts))
539			CTR2(KTR_LOCK, "_mtx_unlock_sleep: %p resuming lock=%p",
540			    m, (void *)m->mtx_lock);
541	}
542	mtx_unlock_spin(&sched_lock);
543#endif
544
545	return;
546}
547
548/*
549 * All the unlocking of MTX_SPIN locks is done inline.
550 * See the _rel_spin_lock() macro for the details.
551 */
552
553/*
554 * The backing function for the INVARIANTS-enabled mtx_assert()
555 */
556#ifdef INVARIANT_SUPPORT
557void
558_mtx_assert(struct mtx *m, int what, const char *file, int line)
559{
560
561	if (panicstr != NULL || dumping)
562		return;
563	switch (what) {
564	case MA_OWNED:
565	case MA_OWNED | MA_RECURSED:
566	case MA_OWNED | MA_NOTRECURSED:
567		if (!mtx_owned(m))
568			panic("mutex %s not owned at %s:%d",
569			    m->mtx_object.lo_name, file, line);
570		if (mtx_recursed(m)) {
571			if ((what & MA_NOTRECURSED) != 0)
572				panic("mutex %s recursed at %s:%d",
573				    m->mtx_object.lo_name, file, line);
574		} else if ((what & MA_RECURSED) != 0) {
575			panic("mutex %s unrecursed at %s:%d",
576			    m->mtx_object.lo_name, file, line);
577		}
578		break;
579	case MA_NOTOWNED:
580		if (mtx_owned(m))
581			panic("mutex %s owned at %s:%d",
582			    m->mtx_object.lo_name, file, line);
583		break;
584	default:
585		panic("unknown mtx_assert at %s:%d", file, line);
586	}
587}
588#endif
589
590/*
591 * The MUTEX_DEBUG-enabled mtx_validate()
592 *
593 * Most of these checks have been moved off into the LO_INITIALIZED flag
594 * maintained by the witness code.
595 */
596#ifdef MUTEX_DEBUG
597
598void	mtx_validate(struct mtx *);
599
600void
601mtx_validate(struct mtx *m)
602{
603
604/*
605 * XXX: When kernacc() does not require Giant we can reenable this check
606 */
607#ifdef notyet
608	/*
609	 * Can't call kernacc() from early init386(), especially when
610	 * initializing Giant mutex, because some stuff in kernacc()
611	 * requires Giant itself.
612	 */
613	if (!cold)
614		if (!kernacc((caddr_t)m, sizeof(m),
615		    VM_PROT_READ | VM_PROT_WRITE))
616			panic("Can't read and write to mutex %p", m);
617#endif
618}
619#endif
620
621/*
622 * General init routine used by the MTX_SYSINIT() macro.
623 */
624void
625mtx_sysinit(void *arg)
626{
627	struct mtx_args *margs = arg;
628
629	mtx_init(margs->ma_mtx, margs->ma_desc, NULL, margs->ma_opts);
630}
631
632/*
633 * Mutex initialization routine; initialize lock `m' of type contained in
634 * `opts' with options contained in `opts' and name `name.'  The optional
635 * lock type `type' is used as a general lock category name for use with
636 * witness.
637 */
638void
639mtx_init(struct mtx *m, const char *name, const char *type, int opts)
640{
641	struct lock_class *class;
642	int flags;
643
644	MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE |
645		MTX_NOWITNESS | MTX_DUPOK | MTX_NOPROFILE)) == 0);
646
647#ifdef MUTEX_DEBUG
648	/* Diagnostic and error correction */
649	mtx_validate(m);
650#endif
651
652	/* Determine lock class and lock flags. */
653	if (opts & MTX_SPIN)
654		class = &lock_class_mtx_spin;
655	else
656		class = &lock_class_mtx_sleep;
657	flags = 0;
658	if (opts & MTX_QUIET)
659		flags |= LO_QUIET;
660	if (opts & MTX_RECURSE)
661		flags |= LO_RECURSABLE;
662	if ((opts & MTX_NOWITNESS) == 0)
663		flags |= LO_WITNESS;
664	if (opts & MTX_DUPOK)
665		flags |= LO_DUPOK;
666	if (opts & MTX_NOPROFILE)
667		flags |= LO_NOPROFILE;
668
669	/* Initialize mutex. */
670	m->mtx_lock = MTX_UNOWNED;
671	m->mtx_recurse = 0;
672
673	lock_profile_object_init(&m->mtx_object, class, name);
674	lock_init(&m->mtx_object, class, name, type, flags);
675}
676
677/*
678 * Remove lock `m' from all_mtx queue.  We don't allow MTX_QUIET to be
679 * passed in as a flag here because if the corresponding mtx_init() was
680 * called with MTX_QUIET set, then it will already be set in the mutex's
681 * flags.
682 */
683void
684mtx_destroy(struct mtx *m)
685{
686
687	if (!mtx_owned(m))
688		MPASS(mtx_unowned(m));
689	else {
690		MPASS((m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0);
691
692		/* Perform the non-mtx related part of mtx_unlock_spin(). */
693		if (LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin)
694			spinlock_exit();
695		else
696			curthread->td_locks--;
697
698		/* Tell witness this isn't locked to make it happy. */
699		WITNESS_UNLOCK(&m->mtx_object, LOP_EXCLUSIVE, __FILE__,
700		    __LINE__);
701	}
702
703	m->mtx_lock = MTX_DESTROYED;
704	lock_profile_object_destroy(&m->mtx_object);
705	lock_destroy(&m->mtx_object);
706}
707
708/*
709 * Intialize the mutex code and system mutexes.  This is called from the MD
710 * startup code prior to mi_startup().  The per-CPU data space needs to be
711 * setup before this is called.
712 */
713void
714mutex_init(void)
715{
716
717	/* Setup turnstiles so that sleep mutexes work. */
718	init_turnstiles();
719
720	/*
721	 * Initialize mutexes.
722	 */
723	mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
724	mtx_init(&sched_lock, "sched lock", NULL, MTX_SPIN | MTX_RECURSE);
725	mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
726	mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
727	mtx_lock(&Giant);
728
729	lock_profile_init();
730}
731
732#ifdef DDB
733void
734db_show_mtx(struct lock_object *lock)
735{
736	struct thread *td;
737	struct mtx *m;
738
739	m = (struct mtx *)lock;
740
741	db_printf(" flags: {");
742	if (LOCK_CLASS(lock) == &lock_class_mtx_spin)
743		db_printf("SPIN");
744	else
745		db_printf("DEF");
746	if (m->mtx_object.lo_flags & LO_RECURSABLE)
747		db_printf(", RECURSE");
748	if (m->mtx_object.lo_flags & LO_DUPOK)
749		db_printf(", DUPOK");
750	db_printf("}\n");
751	db_printf(" state: {");
752	if (mtx_unowned(m))
753		db_printf("UNOWNED");
754	else {
755		db_printf("OWNED");
756		if (m->mtx_lock & MTX_CONTESTED)
757			db_printf(", CONTESTED");
758		if (m->mtx_lock & MTX_RECURSED)
759			db_printf(", RECURSED");
760	}
761	db_printf("}\n");
762	if (!mtx_unowned(m)) {
763		td = mtx_owner(m);
764		db_printf(" owner: %p (tid %d, pid %d, \"%s\")\n", td,
765		    td->td_tid, td->td_proc->p_pid, td->td_proc->p_comm);
766		if (mtx_recursed(m))
767			db_printf(" recursed: %d\n", m->mtx_recurse);
768	}
769}
770#endif
771