lock.h revision 194578
1130803Smarcel/*- 2130803Smarcel * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 3130803Smarcel * 4130803Smarcel * Redistribution and use in source and binary forms, with or without 5130803Smarcel * modification, are permitted provided that the following conditions 6130803Smarcel * are met: 7130803Smarcel * 1. Redistributions of source code must retain the above copyright 8130803Smarcel * notice, this list of conditions and the following disclaimer. 9130803Smarcel * 2. Redistributions in binary form must reproduce the above copyright 10130803Smarcel * notice, this list of conditions and the following disclaimer in the 11130803Smarcel * documentation and/or other materials provided with the distribution. 12130803Smarcel * 3. Berkeley Software Design Inc's name may not be used to endorse or 13130803Smarcel * promote products derived from this software without specific prior 14130803Smarcel * written permission. 15130803Smarcel * 16130803Smarcel * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 17130803Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18130803Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19130803Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 20130803Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21130803Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22130803Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23130803Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24130803Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25130803Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26130803Smarcel * SUCH DAMAGE. 27130803Smarcel * 28130803Smarcel * from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $ 29130803Smarcel * $FreeBSD: head/sys/sys/lock.h 194578 2009-06-21 09:01:12Z rdivacky $ 30130803Smarcel */ 31130803Smarcel 32130803Smarcel#ifndef _SYS_LOCK_H_ 33130803Smarcel#define _SYS_LOCK_H_ 34130803Smarcel 35130803Smarcel#include <sys/queue.h> 36130803Smarcel#include <sys/_lock.h> 37130803Smarcel 38130803Smarcelstruct lock_list_entry; 39130803Smarcelstruct thread; 40130803Smarcel 41130803Smarcel/* 42130803Smarcel * Lock classes. Each lock has a class which describes characteristics 43130803Smarcel * common to all types of locks of a given class. 44130803Smarcel * 45130803Smarcel * Spin locks in general must always protect against preemption, as it is 46130803Smarcel * an error to perform any type of context switch while holding a spin lock. 47130803Smarcel * Also, for an individual lock to be recursable, its class must allow 48130803Smarcel * recursion and the lock itself must explicitly allow recursion. 49130803Smarcel * 50130803Smarcel * The 'lc_ddb_show' function pointer is used to dump class-specific 51130803Smarcel * data for the 'show lock' DDB command. The 'lc_lock' and 52130803Smarcel * 'lc_unlock' function pointers are used in sleep(9) and cv_wait(9) 53130803Smarcel * to lock and unlock locks while blocking on a sleep queue. The 54130803Smarcel * return value of 'lc_unlock' will be passed to 'lc_lock' on resume 55130803Smarcel * to allow communication of state between the two routines. 56130803Smarcel */ 57130803Smarcel 58130803Smarcelstruct lock_class { 59130803Smarcel const char *lc_name; 60130803Smarcel u_int lc_flags; 61130803Smarcel void (*lc_assert)(struct lock_object *lock, int what); 62130803Smarcel void (*lc_ddb_show)(struct lock_object *lock); 63130803Smarcel void (*lc_lock)(struct lock_object *lock, int how); 64130803Smarcel int (*lc_owner)(struct lock_object *lock, struct thread **owner); 65130803Smarcel int (*lc_unlock)(struct lock_object *lock); 66130803Smarcel}; 67130803Smarcel 68130803Smarcel#define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ 69130803Smarcel#define LC_SPINLOCK 0x00000002 /* Spin lock. */ 70130803Smarcel#define LC_SLEEPABLE 0x00000004 /* Sleeping allowed with this lock. */ 71130803Smarcel#define LC_RECURSABLE 0x00000008 /* Locks of this type may recurse. */ 72130803Smarcel#define LC_UPGRADABLE 0x00000010 /* Upgrades and downgrades permitted. */ 73130803Smarcel 74130803Smarcel#define LO_CLASSFLAGS 0x0000ffff /* Class specific flags. */ 75130803Smarcel#define LO_INITIALIZED 0x00010000 /* Lock has been initialized. */ 76130803Smarcel#define LO_WITNESS 0x00020000 /* Should witness monitor this lock. */ 77130803Smarcel#define LO_QUIET 0x00040000 /* Don't log locking operations. */ 78130803Smarcel#define LO_RECURSABLE 0x00080000 /* Lock may recurse. */ 79130803Smarcel#define LO_SLEEPABLE 0x00100000 /* Lock may be held while sleeping. */ 80130803Smarcel#define LO_UPGRADABLE 0x00200000 /* Lock may be upgraded/downgraded. */ 81130803Smarcel#define LO_DUPOK 0x00400000 /* Don't check for duplicate acquires */ 82130803Smarcel#define LO_CLASSMASK 0x0f000000 /* Class index bitmask. */ 83130803Smarcel#define LO_NOPROFILE 0x10000000 /* Don't profile this lock */ 84130803Smarcel 85130803Smarcel/* 86130803Smarcel * Lock classes are statically assigned an index into the gobal lock_classes 87130803Smarcel * array. Debugging code looks up the lock class for a given lock object 88130803Smarcel * by indexing the array. 89130803Smarcel */ 90130803Smarcel#define LO_CLASSSHIFT 24 91130803Smarcel#define LO_CLASSINDEX(lock) ((((lock)->lo_flags) & LO_CLASSMASK) >> LO_CLASSSHIFT) 92130803Smarcel#define LOCK_CLASS(lock) (lock_classes[LO_CLASSINDEX((lock))]) 93130803Smarcel#define LOCK_CLASS_MAX (LO_CLASSMASK >> LO_CLASSSHIFT) 94130803Smarcel 95130803Smarcel/* 96130803Smarcel * Option flags passed to lock operations that witness also needs to know 97130803Smarcel * about or that are generic across all locks. 98130803Smarcel */ 99130803Smarcel#define LOP_NEWORDER 0x00000001 /* Define a new lock order. */ 100130803Smarcel#define LOP_QUIET 0x00000002 /* Don't log locking operations. */ 101130803Smarcel#define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ 102130803Smarcel#define LOP_EXCLUSIVE 0x00000008 /* Exclusive lock. */ 103130803Smarcel#define LOP_DUPOK 0x00000010 /* Don't check for duplicate acquires */ 104130803Smarcel 105130803Smarcel/* Flags passed to witness_assert. */ 106130803Smarcel#define LA_MASKASSERT 0x000000ff /* Mask for witness defined asserts. */ 107130803Smarcel#define LA_UNLOCKED 0x00000000 /* Lock is unlocked. */ 108130803Smarcel#define LA_LOCKED 0x00000001 /* Lock is at least share locked. */ 109130803Smarcel#define LA_SLOCKED 0x00000002 /* Lock is exactly share locked. */ 110130803Smarcel#define LA_XLOCKED 0x00000004 /* Lock is exclusively locked. */ 111130803Smarcel#define LA_RECURSED 0x00000008 /* Lock is recursed. */ 112130803Smarcel#define LA_NOTRECURSED 0x00000010 /* Lock is not recursed. */ 113130803Smarcel 114130803Smarcel#ifdef _KERNEL 115130803Smarcel/* 116130803Smarcel * If any of WITNESS, INVARIANTS, or KTR_LOCK KTR tracing has been enabled, 117130803Smarcel * then turn on LOCK_DEBUG. When this option is on, extra debugging 118130803Smarcel * facilities such as tracking the file and line number of lock operations 119130803Smarcel * are enabled. Also, mutex locking operations are not inlined to avoid 120130803Smarcel * bloat from all the extra debugging code. We also have to turn on all the 121130803Smarcel * calling conventions for this debugging code in modules so that modules can 122130803Smarcel * work with both debug and non-debug kernels. 123130803Smarcel */ 124130803Smarcel#if defined(KLD_MODULE) || defined(WITNESS) || defined(INVARIANTS) || defined(INVARIANT_SUPPORT) || defined(KTR) || defined(LOCK_PROFILING) 125130803Smarcel#define LOCK_DEBUG 1 126130803Smarcel#else 127130803Smarcel#define LOCK_DEBUG 0 128130803Smarcel#endif 129130803Smarcel 130130803Smarcel/* 131130803Smarcel * In the LOCK_DEBUG case, use the filename and line numbers for debugging 132130803Smarcel * operations. Otherwise, use default values to avoid the unneeded bloat. 133130803Smarcel */ 134130803Smarcel#if LOCK_DEBUG > 0 135130803Smarcel#define LOCK_FILE __FILE__ 136130803Smarcel#define LOCK_LINE __LINE__ 137130803Smarcel#else 138130803Smarcel#define LOCK_FILE NULL 139130803Smarcel#define LOCK_LINE 0 140130803Smarcel#endif 141130803Smarcel 142130803Smarcel/* 143130803Smarcel * Macros for KTR_LOCK tracing. 144130803Smarcel * 145130803Smarcel * opname - name of this operation (LOCK/UNLOCK/SLOCK, etc.) 146130803Smarcel * lo - struct lock_object * for this lock 147130803Smarcel * flags - flags passed to the lock operation 148130803Smarcel * recurse - this locks recursion level (or 0 if class is not recursable) 149130803Smarcel * result - result of a try lock operation 150130803Smarcel * file - file name 151130803Smarcel * line - line number 152130803Smarcel */ 153130803Smarcel#define LOCK_LOG_TEST(lo, flags) \ 154130803Smarcel (((flags) & LOP_QUIET) == 0 && ((lo)->lo_flags & LO_QUIET) == 0) 155130803Smarcel 156130803Smarcel#define LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do { \ 157130803Smarcel if (LOCK_LOG_TEST((lo), (flags))) \ 158130803Smarcel CTR5(KTR_LOCK, opname " (%s) %s r = %d at %s:%d", \ 159130803Smarcel LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ 160130803Smarcel (u_int)(recurse), (file), (line)); \ 161130803Smarcel} while (0) 162130803Smarcel 163130803Smarcel#define LOCK_LOG_TRY(opname, lo, flags, result, file, line) do { \ 164130803Smarcel if (LOCK_LOG_TEST((lo), (flags))) \ 165130803Smarcel CTR5(KTR_LOCK, "TRY_" opname " (%s) %s result=%d at %s:%d",\ 166130803Smarcel LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ 167130803Smarcel (u_int)(result), (file), (line)); \ 168130803Smarcel} while (0) 169130803Smarcel 170130803Smarcel#define LOCK_LOG_INIT(lo, flags) do { \ 171130803Smarcel if (LOCK_LOG_TEST((lo), (flags))) \ 172130803Smarcel CTR4(KTR_LOCK, "%s: %p (%s) %s", __func__, (lo), \ 173130803Smarcel LOCK_CLASS(lo)->lc_name, (lo)->lo_name); \ 174130803Smarcel} while (0) 175130803Smarcel 176130803Smarcel#define LOCK_LOG_DESTROY(lo, flags) LOCK_LOG_INIT(lo, flags) 177130803Smarcel 178130803Smarcel#define lock_initalized(lo) ((lo)->lo_flags & LO_INITIALIZED) 179130803Smarcel 180130803Smarcel/* 181130803Smarcel * Helpful macros for quickly coming up with assertions with informative 182130803Smarcel * panic messages. 183130803Smarcel */ 184130803Smarcel#define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) 185130803Smarcel#define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) 186130803Smarcel#define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) 187130803Smarcel#define MPASS4(ex, what, file, line) \ 188130803Smarcel KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) 189130803Smarcel 190130803Smarcelextern struct lock_class lock_class_mtx_sleep; 191130803Smarcelextern struct lock_class lock_class_mtx_spin; 192130803Smarcelextern struct lock_class lock_class_sx; 193130803Smarcelextern struct lock_class lock_class_rw; 194130803Smarcelextern struct lock_class lock_class_rm; 195130803Smarcelextern struct lock_class lock_class_lockmgr; 196130803Smarcel 197130803Smarcelextern struct lock_class *lock_classes[]; 198130803Smarcel 199130803Smarcelvoid lock_init(struct lock_object *, struct lock_class *, 200130803Smarcel const char *, const char *, int); 201130803Smarcelvoid lock_destroy(struct lock_object *); 202130803Smarcelvoid spinlock_enter(void); 203130803Smarcelvoid spinlock_exit(void); 204130803Smarcelvoid witness_init(struct lock_object *, const char *); 205130803Smarcelvoid witness_destroy(struct lock_object *); 206130803Smarcelint witness_defineorder(struct lock_object *, struct lock_object *); 207130803Smarcelvoid witness_checkorder(struct lock_object *, int, const char *, int, 208130803Smarcel struct lock_object *); 209130803Smarcelvoid witness_lock(struct lock_object *, int, const char *, int); 210130803Smarcelvoid witness_upgrade(struct lock_object *, int, const char *, int); 211130803Smarcelvoid witness_downgrade(struct lock_object *, int, const char *, int); 212130803Smarcelvoid witness_unlock(struct lock_object *, int, const char *, int); 213130803Smarcelvoid witness_save(struct lock_object *, const char **, int *); 214130803Smarcelvoid witness_restore(struct lock_object *, const char *, int); 215130803Smarcelint witness_list_locks(struct lock_list_entry **); 216130803Smarcelint witness_warn(int, struct lock_object *, const char *, ...); 217130803Smarcelvoid witness_assert(struct lock_object *, int, const char *, int); 218130803Smarcelvoid witness_display_spinlock(struct lock_object *, struct thread *); 219130803Smarcelint witness_line(struct lock_object *); 220130803Smarcelvoid witness_norelease(struct lock_object *); 221130803Smarcelvoid witness_releaseok(struct lock_object *); 222130803Smarcelconst char *witness_file(struct lock_object *); 223130803Smarcelvoid witness_thread_exit(struct thread *); 224130803Smarcel 225130803Smarcel#ifdef WITNESS 226130803Smarcel 227130803Smarcel/* Flags for witness_warn(). */ 228130803Smarcel#define WARN_GIANTOK 0x01 /* Giant is exempt from this check. */ 229130803Smarcel#define WARN_PANIC 0x02 /* Panic if check fails. */ 230130803Smarcel#define WARN_SLEEPOK 0x04 /* Sleepable locks are exempt from check. */ 231130803Smarcel 232130803Smarcel#define WITNESS_INIT(lock, type) \ 233130803Smarcel witness_init((lock), (type)) 234130803Smarcel 235130803Smarcel#define WITNESS_DESTROY(lock) \ 236130803Smarcel witness_destroy(lock) 237130803Smarcel 238130803Smarcel#define WITNESS_CHECKORDER(lock, flags, file, line, interlock) \ 239130803Smarcel witness_checkorder((lock), (flags), (file), (line), (interlock)) 240130803Smarcel 241130803Smarcel#define WITNESS_DEFINEORDER(lock1, lock2) \ 242130803Smarcel witness_defineorder((struct lock_object *)(lock1), \ 243130803Smarcel (struct lock_object *)(lock2)) 244130803Smarcel 245130803Smarcel#define WITNESS_LOCK(lock, flags, file, line) \ 246130803Smarcel witness_lock((lock), (flags), (file), (line)) 247130803Smarcel 248130803Smarcel#define WITNESS_UPGRADE(lock, flags, file, line) \ 249130803Smarcel witness_upgrade((lock), (flags), (file), (line)) 250130803Smarcel 251130803Smarcel#define WITNESS_DOWNGRADE(lock, flags, file, line) \ 252130803Smarcel witness_downgrade((lock), (flags), (file), (line)) 253130803Smarcel 254130803Smarcel#define WITNESS_UNLOCK(lock, flags, file, line) \ 255130803Smarcel witness_unlock((lock), (flags), (file), (line)) 256130803Smarcel 257130803Smarcel#define WITNESS_CHECK(flags, lock, fmt, ...) \ 258130803Smarcel witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 259130803Smarcel 260130803Smarcel#define WITNESS_WARN(flags, lock, fmt, ...) \ 261130803Smarcel witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 262130803Smarcel 263130803Smarcel#define WITNESS_SAVE_DECL(n) \ 264130803Smarcel const char * __CONCAT(n, __wf); \ 265130803Smarcel int __CONCAT(n, __wl) 266130803Smarcel 267130803Smarcel#define WITNESS_SAVE(lock, n) \ 268130803Smarcel witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl)) 269130803Smarcel 270130803Smarcel#define WITNESS_RESTORE(lock, n) \ 271130803Smarcel witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl)) 272130803Smarcel 273130803Smarcel#define WITNESS_NORELEASE(lock) \ 274130803Smarcel witness_norelease(&(lock)->lock_object) 275130803Smarcel 276130803Smarcel#define WITNESS_RELEASEOK(lock) \ 277130803Smarcel witness_releaseok(&(lock)->lock_object) 278130803Smarcel 279130803Smarcel#define WITNESS_FILE(lock) \ 280130803Smarcel witness_file(lock) 281130803Smarcel 282130803Smarcel#define WITNESS_LINE(lock) \ 283130803Smarcel witness_line(lock) 284130803Smarcel 285130803Smarcel#else /* WITNESS */ 286130803Smarcel#define WITNESS_INIT(lock, type) (void)0 287130803Smarcel#define WITNESS_DESTROY(lock) (void)0 288130803Smarcel#define WITNESS_DEFINEORDER(lock1, lock2) 0 289130803Smarcel#define WITNESS_CHECKORDER(lock, flags, file, line, interlock) (void)0 290130803Smarcel#define WITNESS_LOCK(lock, flags, file, line) (void)0 291130803Smarcel#define WITNESS_UPGRADE(lock, flags, file, line) (void)0 292130803Smarcel#define WITNESS_DOWNGRADE(lock, flags, file, line) (void)0 293130803Smarcel#define WITNESS_UNLOCK(lock, flags, file, line) (void)0 294130803Smarcel#define WITNESS_CHECK(flags, lock, fmt, ...) 0 295130803Smarcel#define WITNESS_WARN(flags, lock, fmt, ...) (void)0 296130803Smarcel#define WITNESS_SAVE_DECL(n) (void)0 297130803Smarcel#define WITNESS_SAVE(lock, n) (void)0 298130803Smarcel#define WITNESS_RESTORE(lock, n) (void)0 299130803Smarcel#define WITNESS_NORELEASE(lock) (void)0 300130803Smarcel#define WITNESS_RELEASEOK(lock) (void)0 301130803Smarcel#define WITNESS_FILE(lock) ("?") 302130803Smarcel#define WITNESS_LINE(lock) (0) 303130803Smarcel#endif /* WITNESS */ 304130803Smarcel 305130803Smarcel/* 306130803Smarcel * Helper macros to allow developers to add explicit lock order checks 307130803Smarcel * wherever they please without having to actually grab a lock to do so. 308130803Smarcel */ 309130803Smarcel#define witness_check(l) \ 310130803Smarcel WITNESS_CHECKORDER(&(l)->lock_object, LOP_EXCLUSIVE, LOCK_FILE, \ 311130803Smarcel LOCK_LINE, NULL) 312130803Smarcel 313130803Smarcel#define witness_check_shared(l) \ 314130803Smarcel WITNESS_CHECKORDER(&(l)->lock_object, 0, LOCK_FILE, LOCK_LINE, NULL) 315130803Smarcel 316130803Smarcel#endif /* _KERNEL */ 317130803Smarcel#endif /* _SYS_LOCK_H_ */ 318130803Smarcel