]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_mutex.c
This commit was generated by cvs2svn to compensate for changes in r166124,
[FreeBSD/FreeBSD.git] / sys / kern / kern_mutex.c
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$");
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
92 static void     db_show_mtx(struct lock_object *lock);
93 #endif
94
95 /*
96  * Lock classes for sleep and spin mutexes.
97  */
98 struct lock_class lock_class_mtx_sleep = {
99         "sleep mutex",
100         LC_SLEEPLOCK | LC_RECURSABLE,
101 #ifdef DDB
102         db_show_mtx
103 #endif
104 };
105 struct 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  */
116 struct mtx sched_lock;
117 struct mtx Giant;
118
119 #ifdef LOCK_PROFILING
120 static 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
130 static 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  */
137 void
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
160 void
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
180 void
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
202 void
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  */
225 int
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  */
263 void
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  */
399 void
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  */
453 void
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
557 void
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
598 void    mtx_validate(struct mtx *);
599
600 void
601 mtx_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  */
624 void
625 mtx_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  */
638 void
639 mtx_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  */
683 void
684 mtx_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  */
713 void
714 mutex_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
733 void
734 db_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