174912Sjhb/*- 274912Sjhb * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 324269Speter * 424269Speter * Redistribution and use in source and binary forms, with or without 524269Speter * modification, are permitted provided that the following conditions 624269Speter * are met: 724269Speter * 1. Redistributions of source code must retain the above copyright 824269Speter * notice, this list of conditions and the following disclaimer. 924269Speter * 2. Redistributions in binary form must reproduce the above copyright 1024269Speter * notice, this list of conditions and the following disclaimer in the 1124269Speter * documentation and/or other materials provided with the distribution. 1274912Sjhb * 3. Berkeley Software Design Inc's name may not be used to endorse or 1374912Sjhb * promote products derived from this software without specific prior 1474912Sjhb * written permission. 1524269Speter * 1674912Sjhb * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1724269Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1824269Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1974912Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2024269Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2124269Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2224269Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2324269Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2424269Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2524269Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2624269Speter * SUCH DAMAGE. 2724269Speter * 28212408Sobrien * from BSDI Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp 2950477Speter * $FreeBSD$ 3024269Speter */ 3124269Speter 3274912Sjhb#ifndef _SYS_LOCK_H_ 3374912Sjhb#define _SYS_LOCK_H_ 3424269Speter 3574912Sjhb#include <sys/queue.h> 3676166Smarkm#include <sys/_lock.h> 3774912Sjhb 38178165Sattiliostruct lock_list_entry; 39102506Sbdestruct thread; 40102506Sbde 4124269Speter/* 4274912Sjhb * Lock classes. Each lock has a class which describes characteristics 4374912Sjhb * common to all types of locks of a given class. 4424269Speter * 4574912Sjhb * Spin locks in general must always protect against preemption, as it is 4674912Sjhb * an error to perform any type of context switch while holding a spin lock. 4774912Sjhb * Also, for an individual lock to be recursable, its class must allow 4874912Sjhb * recursion and the lock itself must explicitly allow recursion. 49167368Sjhb * 50167368Sjhb * The 'lc_ddb_show' function pointer is used to dump class-specific 51167368Sjhb * data for the 'show lock' DDB command. The 'lc_lock' and 52167368Sjhb * 'lc_unlock' function pointers are used in sleep(9) and cv_wait(9) 53167368Sjhb * to lock and unlock locks while blocking on a sleep queue. The 54167368Sjhb * return value of 'lc_unlock' will be passed to 'lc_lock' on resume 55167368Sjhb * to allow communication of state between the two routines. 5624269Speter */ 5774912Sjhb 5883045Sobrienstruct lock_class { 5974912Sjhb const char *lc_name; 6074912Sjhb u_int lc_flags; 61173733Sattilio void (*lc_assert)(struct lock_object *lock, int what); 62153395Sjhb void (*lc_ddb_show)(struct lock_object *lock); 63167368Sjhb void (*lc_lock)(struct lock_object *lock, int how); 64192853Ssson int (*lc_owner)(struct lock_object *lock, struct thread **owner); 65167368Sjhb int (*lc_unlock)(struct lock_object *lock); 6674912Sjhb}; 6774912Sjhb 6874912Sjhb#define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ 6974912Sjhb#define LC_SPINLOCK 0x00000002 /* Spin lock. */ 7074912Sjhb#define LC_SLEEPABLE 0x00000004 /* Sleeping allowed with this lock. */ 7174912Sjhb#define LC_RECURSABLE 0x00000008 /* Locks of this type may recurse. */ 7282244Sjhb#define LC_UPGRADABLE 0x00000010 /* Upgrades and downgrades permitted. */ 7374912Sjhb 7474912Sjhb#define LO_CLASSFLAGS 0x0000ffff /* Class specific flags. */ 7574912Sjhb#define LO_INITIALIZED 0x00010000 /* Lock has been initialized. */ 7674912Sjhb#define LO_WITNESS 0x00020000 /* Should witness monitor this lock. */ 7774912Sjhb#define LO_QUIET 0x00040000 /* Don't log locking operations. */ 7874912Sjhb#define LO_RECURSABLE 0x00080000 /* Lock may recurse. */ 7974912Sjhb#define LO_SLEEPABLE 0x00100000 /* Lock may be held while sleeping. */ 8082244Sjhb#define LO_UPGRADABLE 0x00200000 /* Lock may be upgraded/downgraded. */ 8193273Sjeff#define LO_DUPOK 0x00400000 /* Don't check for duplicate acquires */ 82154077Sjhb#define LO_CLASSMASK 0x0f000000 /* Class index bitmask. */ 83164159Skmacy#define LO_NOPROFILE 0x10000000 /* Don't profile this lock */ 8474912Sjhb 85154077Sjhb/* 86154077Sjhb * Lock classes are statically assigned an index into the gobal lock_classes 87154077Sjhb * array. Debugging code looks up the lock class for a given lock object 88154077Sjhb * by indexing the array. 89154077Sjhb */ 90154077Sjhb#define LO_CLASSSHIFT 24 91154077Sjhb#define LO_CLASSINDEX(lock) ((((lock)->lo_flags) & LO_CLASSMASK) >> LO_CLASSSHIFT) 92154077Sjhb#define LOCK_CLASS(lock) (lock_classes[LO_CLASSINDEX((lock))]) 93154484Sjhb#define LOCK_CLASS_MAX (LO_CLASSMASK >> LO_CLASSSHIFT) 94154077Sjhb 9524269Speter/* 9674912Sjhb * Option flags passed to lock operations that witness also needs to know 9774912Sjhb * about or that are generic across all locks. 9824269Speter */ 99125160Sjhb#define LOP_NEWORDER 0x00000001 /* Define a new lock order. */ 10074912Sjhb#define LOP_QUIET 0x00000002 /* Don't log locking operations. */ 10174912Sjhb#define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ 10276272Sjhb#define LOP_EXCLUSIVE 0x00000008 /* Exclusive lock. */ 103145421Sjeff#define LOP_DUPOK 0x00000010 /* Don't check for duplicate acquires */ 10424269Speter 10578871Sjhb/* Flags passed to witness_assert. */ 106176249Sattilio#define LA_MASKASSERT 0x000000ff /* Mask for witness defined asserts. */ 10778871Sjhb#define LA_UNLOCKED 0x00000000 /* Lock is unlocked. */ 10878871Sjhb#define LA_LOCKED 0x00000001 /* Lock is at least share locked. */ 10978871Sjhb#define LA_SLOCKED 0x00000002 /* Lock is exactly share locked. */ 11078871Sjhb#define LA_XLOCKED 0x00000004 /* Lock is exclusively locked. */ 11178871Sjhb#define LA_RECURSED 0x00000008 /* Lock is recursed. */ 11278871Sjhb#define LA_NOTRECURSED 0x00000010 /* Lock is not recursed. */ 11378871Sjhb 11474912Sjhb#ifdef _KERNEL 11524269Speter/* 11685186Sjhb * If any of WITNESS, INVARIANTS, or KTR_LOCK KTR tracing has been enabled, 11785186Sjhb * then turn on LOCK_DEBUG. When this option is on, extra debugging 11885186Sjhb * facilities such as tracking the file and line number of lock operations 11985186Sjhb * are enabled. Also, mutex locking operations are not inlined to avoid 12085186Sjhb * bloat from all the extra debugging code. We also have to turn on all the 12185186Sjhb * calling conventions for this debugging code in modules so that modules can 12285186Sjhb * work with both debug and non-debug kernels. 12385186Sjhb */ 124164159Skmacy#if defined(KLD_MODULE) || defined(WITNESS) || defined(INVARIANTS) || defined(INVARIANT_SUPPORT) || defined(KTR) || defined(LOCK_PROFILING) 12585186Sjhb#define LOCK_DEBUG 1 12685186Sjhb#else 12785186Sjhb#define LOCK_DEBUG 0 12885186Sjhb#endif 12985186Sjhb 13085186Sjhb/* 13183593Sjhb * In the LOCK_DEBUG case, use the filename and line numbers for debugging 13283593Sjhb * operations. Otherwise, use default values to avoid the unneeded bloat. 13383593Sjhb */ 13485186Sjhb#if LOCK_DEBUG > 0 13583593Sjhb#define LOCK_FILE __FILE__ 13683593Sjhb#define LOCK_LINE __LINE__ 13783593Sjhb#else 13883593Sjhb#define LOCK_FILE NULL 13983593Sjhb#define LOCK_LINE 0 14083593Sjhb#endif 14183593Sjhb 14283593Sjhb/* 14374912Sjhb * Macros for KTR_LOCK tracing. 14424269Speter * 14574912Sjhb * opname - name of this operation (LOCK/UNLOCK/SLOCK, etc.) 14674912Sjhb * lo - struct lock_object * for this lock 14774912Sjhb * flags - flags passed to the lock operation 14874912Sjhb * recurse - this locks recursion level (or 0 if class is not recursable) 14974912Sjhb * result - result of a try lock operation 15074912Sjhb * file - file name 15174912Sjhb * line - line number 15224269Speter */ 15374912Sjhb#define LOCK_LOG_TEST(lo, flags) \ 15474912Sjhb (((flags) & LOP_QUIET) == 0 && ((lo)->lo_flags & LO_QUIET) == 0) 15524269Speter 15674912Sjhb#define LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do { \ 15774912Sjhb if (LOCK_LOG_TEST((lo), (flags))) \ 158196204Skib CTR6(KTR_LOCK, opname " (%s) %s %p r = %d at %s:%d", \ 159154077Sjhb LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ 160196204Skib (lo), (u_int)(recurse), (file), (line)); \ 16174912Sjhb} while (0) 16274912Sjhb 16374912Sjhb#define LOCK_LOG_TRY(opname, lo, flags, result, file, line) do { \ 16474912Sjhb if (LOCK_LOG_TEST((lo), (flags))) \ 165196204Skib CTR6(KTR_LOCK, "TRY_" opname " (%s) %s %p result=%d at %s:%d",\ 166154077Sjhb LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ 167196204Skib (lo), (u_int)(result), (file), (line)); \ 16874912Sjhb} while (0) 16974912Sjhb 17074912Sjhb#define LOCK_LOG_INIT(lo, flags) do { \ 17174912Sjhb if (LOCK_LOG_TEST((lo), (flags))) \ 17288661Sjake CTR4(KTR_LOCK, "%s: %p (%s) %s", __func__, (lo), \ 173154077Sjhb LOCK_CLASS(lo)->lc_name, (lo)->lo_name); \ 17474912Sjhb} while (0) 17574912Sjhb 17674912Sjhb#define LOCK_LOG_DESTROY(lo, flags) LOCK_LOG_INIT(lo, flags) 17774912Sjhb 178154484Sjhb#define lock_initalized(lo) ((lo)->lo_flags & LO_INITIALIZED) 179154484Sjhb 18024269Speter/* 18174912Sjhb * Helpful macros for quickly coming up with assertions with informative 18274912Sjhb * panic messages. 18324269Speter */ 18474912Sjhb#define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) 18574912Sjhb#define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) 18674912Sjhb#define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) 18774912Sjhb#define MPASS4(ex, what, file, line) \ 18874912Sjhb KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) 18924269Speter 19074912Sjhbextern struct lock_class lock_class_mtx_sleep; 19174912Sjhbextern struct lock_class lock_class_mtx_spin; 19274912Sjhbextern struct lock_class lock_class_sx; 193154941Sjhbextern struct lock_class lock_class_rw; 194173444Supsextern struct lock_class lock_class_rm; 195256001Sjhbextern struct lock_class lock_class_rm_sleepable; 196164246Skmacyextern struct lock_class lock_class_lockmgr; 19770140Sjake 198154077Sjhbextern struct lock_class *lock_classes[]; 199154077Sjhb 200166455Sbmsvoid lock_init(struct lock_object *, struct lock_class *, 201207925Sattilio const char *, const char *, int); 202166455Sbmsvoid lock_destroy(struct lock_object *); 203144637Sjhbvoid spinlock_enter(void); 204144637Sjhbvoid spinlock_exit(void); 205179025Sattiliovoid witness_init(struct lock_object *, const char *); 20674912Sjhbvoid witness_destroy(struct lock_object *); 207125160Sjhbint witness_defineorder(struct lock_object *, struct lock_object *); 208182914Sjhbvoid witness_checkorder(struct lock_object *, int, const char *, int, 209207925Sattilio struct lock_object *); 21074912Sjhbvoid witness_lock(struct lock_object *, int, const char *, int); 21182244Sjhbvoid witness_upgrade(struct lock_object *, int, const char *, int); 21282244Sjhbvoid witness_downgrade(struct lock_object *, int, const char *, int); 21374912Sjhbvoid witness_unlock(struct lock_object *, int, const char *, int); 21474912Sjhbvoid witness_save(struct lock_object *, const char **, int *); 21574912Sjhbvoid witness_restore(struct lock_object *, const char *, int); 216207929Sattilioint witness_list_locks(struct lock_list_entry **, 217207929Sattilio int (*)(const char *, ...)); 218111881Sjhbint witness_warn(int, struct lock_object *, const char *, ...); 21978871Sjhbvoid witness_assert(struct lock_object *, int, const char *, int); 220207929Sattiliovoid witness_display_spinlock(struct lock_object *, struct thread *, 221207929Sattilio int (*)(const char *, ...)); 222102448Siedowseint witness_line(struct lock_object *); 223187511Sthompsavoid witness_norelease(struct lock_object *); 224187511Sthompsavoid witness_releaseok(struct lock_object *); 225102448Siedowseconst char *witness_file(struct lock_object *); 226181695Sattiliovoid witness_thread_exit(struct thread *); 22724269Speter 22874912Sjhb#ifdef WITNESS 229111881Sjhb 230111881Sjhb/* Flags for witness_warn(). */ 231111881Sjhb#define WARN_GIANTOK 0x01 /* Giant is exempt from this check. */ 232111881Sjhb#define WARN_PANIC 0x02 /* Panic if check fails. */ 233111881Sjhb#define WARN_SLEEPOK 0x04 /* Sleepable locks are exempt from check. */ 234111881Sjhb 235179025Sattilio#define WITNESS_INIT(lock, type) \ 236179025Sattilio witness_init((lock), (type)) 23766615Sjasone 23874912Sjhb#define WITNESS_DESTROY(lock) \ 23974912Sjhb witness_destroy(lock) 24024269Speter 241182914Sjhb#define WITNESS_CHECKORDER(lock, flags, file, line, interlock) \ 242182914Sjhb witness_checkorder((lock), (flags), (file), (line), (interlock)) 243125160Sjhb 244125160Sjhb#define WITNESS_DEFINEORDER(lock1, lock2) \ 245125160Sjhb witness_defineorder((struct lock_object *)(lock1), \ 246125160Sjhb (struct lock_object *)(lock2)) 247125160Sjhb 24874912Sjhb#define WITNESS_LOCK(lock, flags, file, line) \ 24974912Sjhb witness_lock((lock), (flags), (file), (line)) 25074912Sjhb 25182244Sjhb#define WITNESS_UPGRADE(lock, flags, file, line) \ 25282244Sjhb witness_upgrade((lock), (flags), (file), (line)) 25382244Sjhb 25482244Sjhb#define WITNESS_DOWNGRADE(lock, flags, file, line) \ 25582244Sjhb witness_downgrade((lock), (flags), (file), (line)) 25682244Sjhb 25774912Sjhb#define WITNESS_UNLOCK(lock, flags, file, line) \ 25874912Sjhb witness_unlock((lock), (flags), (file), (line)) 25974912Sjhb 260154934Sjhb#define WITNESS_CHECK(flags, lock, fmt, ...) \ 261154934Sjhb witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 262154934Sjhb 263111881Sjhb#define WITNESS_WARN(flags, lock, fmt, ...) \ 264111881Sjhb witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 26574912Sjhb 26674912Sjhb#define WITNESS_SAVE_DECL(n) \ 26774912Sjhb const char * __CONCAT(n, __wf); \ 26874912Sjhb int __CONCAT(n, __wl) 26974912Sjhb 27074912Sjhb#define WITNESS_SAVE(lock, n) \ 27174912Sjhb witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl)) 27274912Sjhb 27374912Sjhb#define WITNESS_RESTORE(lock, n) \ 27474912Sjhb witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl)) 27574912Sjhb 276187511Sthompsa#define WITNESS_NORELEASE(lock) \ 277187511Sthompsa witness_norelease(&(lock)->lock_object) 278187511Sthompsa 279187511Sthompsa#define WITNESS_RELEASEOK(lock) \ 280187511Sthompsa witness_releaseok(&(lock)->lock_object) 281187511Sthompsa 282102448Siedowse#define WITNESS_FILE(lock) \ 283102448Siedowse witness_file(lock) 284102448Siedowse 285102448Siedowse#define WITNESS_LINE(lock) \ 286102448Siedowse witness_line(lock) 287102448Siedowse 28874912Sjhb#else /* WITNESS */ 289194578Srdivacky#define WITNESS_INIT(lock, type) (void)0 290194578Srdivacky#define WITNESS_DESTROY(lock) (void)0 291125160Sjhb#define WITNESS_DEFINEORDER(lock1, lock2) 0 292194578Srdivacky#define WITNESS_CHECKORDER(lock, flags, file, line, interlock) (void)0 293194578Srdivacky#define WITNESS_LOCK(lock, flags, file, line) (void)0 294194578Srdivacky#define WITNESS_UPGRADE(lock, flags, file, line) (void)0 295194578Srdivacky#define WITNESS_DOWNGRADE(lock, flags, file, line) (void)0 296194578Srdivacky#define WITNESS_UNLOCK(lock, flags, file, line) (void)0 297154934Sjhb#define WITNESS_CHECK(flags, lock, fmt, ...) 0 298194578Srdivacky#define WITNESS_WARN(flags, lock, fmt, ...) (void)0 299194578Srdivacky#define WITNESS_SAVE_DECL(n) (void)0 300194578Srdivacky#define WITNESS_SAVE(lock, n) (void)0 301194578Srdivacky#define WITNESS_RESTORE(lock, n) (void)0 302194578Srdivacky#define WITNESS_NORELEASE(lock) (void)0 303194578Srdivacky#define WITNESS_RELEASEOK(lock) (void)0 304102448Siedowse#define WITNESS_FILE(lock) ("?") 305102448Siedowse#define WITNESS_LINE(lock) (0) 30674912Sjhb#endif /* WITNESS */ 30774912Sjhb 308125160Sjhb/* 309125160Sjhb * Helper macros to allow developers to add explicit lock order checks 310125160Sjhb * wherever they please without having to actually grab a lock to do so. 311125160Sjhb */ 312167788Sjhb#define witness_check(l) \ 313167788Sjhb WITNESS_CHECKORDER(&(l)->lock_object, LOP_EXCLUSIVE, LOCK_FILE, \ 314182914Sjhb LOCK_LINE, NULL) 315125160Sjhb 316167788Sjhb#define witness_check_shared(l) \ 317182914Sjhb WITNESS_CHECKORDER(&(l)->lock_object, 0, LOCK_FILE, LOCK_LINE, NULL) 318125160Sjhb 31974912Sjhb#endif /* _KERNEL */ 32074912Sjhb#endif /* _SYS_LOCK_H_ */ 321