lock.h revision 111881
150276Speter/*- 2166124Srafan * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 350276Speter * 450276Speter * Redistribution and use in source and binary forms, with or without 550276Speter * modification, are permitted provided that the following conditions 650276Speter * are met: 750276Speter * 1. Redistributions of source code must retain the above copyright 850276Speter * notice, this list of conditions and the following disclaimer. 950276Speter * 2. Redistributions in binary form must reproduce the above copyright 1050276Speter * notice, this list of conditions and the following disclaimer in the 1150276Speter * documentation and/or other materials provided with the distribution. 1250276Speter * 3. Berkeley Software Design Inc's name may not be used to endorse or 1350276Speter * promote products derived from this software without specific prior 1450276Speter * written permission. 1550276Speter * 1650276Speter * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1750276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1850276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1950276Speter * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2050276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2150276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2250276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2350276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2450276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2550276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2650276Speter * SUCH DAMAGE. 2750276Speter * 2850276Speter * from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $ 2950276Speter * $FreeBSD: head/sys/sys/lock.h 111881 2003-03-04 20:56:39Z jhb $ 3050276Speter */ 3150276Speter 32166124Srafan#ifndef _SYS_LOCK_H_ 3350276Speter#define _SYS_LOCK_H_ 3450276Speter 3550276Speter#include <sys/queue.h> 3650276Speter#include <sys/_lock.h> 3750276Speter 3850276Speterstruct thread; 39166124Srafan 40166124Srafan/* 41166124Srafan * Lock classes. Each lock has a class which describes characteristics 4250276Speter * common to all types of locks of a given class. 4350276Speter * 4450276Speter * Spin locks in general must always protect against preemption, as it is 4597049Speter * an error to perform any type of context switch while holding a spin lock. 4697049Speter * Also, for an individual lock to be recursable, its class must allow 4756639Speter * recursion and the lock itself must explicitly allow recursion. 4897049Speter */ 4997049Speter 5056639Speterstruct lock_class { 5156639Speter const char *lc_name; 5256639Speter u_int lc_flags; 5350276Speter}; 5450276Speter 5550276Speter#define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ 5650276Speter#define LC_SPINLOCK 0x00000002 /* Spin lock. */ 5750276Speter#define LC_SLEEPABLE 0x00000004 /* Sleeping allowed with this lock. */ 5850276Speter#define LC_RECURSABLE 0x00000008 /* Locks of this type may recurse. */ 5950276Speter#define LC_UPGRADABLE 0x00000010 /* Upgrades and downgrades permitted. */ 6050276Speter 6150276Speter#define LO_CLASSFLAGS 0x0000ffff /* Class specific flags. */ 6250276Speter#define LO_INITIALIZED 0x00010000 /* Lock has been initialized. */ 6350276Speter#define LO_WITNESS 0x00020000 /* Should witness monitor this lock. */ 6450276Speter#define LO_QUIET 0x00040000 /* Don't log locking operations. */ 6550276Speter#define LO_RECURSABLE 0x00080000 /* Lock may recurse. */ 6650276Speter#define LO_SLEEPABLE 0x00100000 /* Lock may be held while sleeping. */ 6750276Speter#define LO_UPGRADABLE 0x00200000 /* Lock may be upgraded/downgraded. */ 6850276Speter#define LO_DUPOK 0x00400000 /* Don't check for duplicate acquires */ 6950276Speter 7050276Speter#define LI_RECURSEMASK 0x0000ffff /* Recursion depth of lock instance. */ 7150276Speter#define LI_EXCLUSIVE 0x00010000 /* Exclusive lock instance. */ 7250276Speter 7350276Speter/* 74166124Srafan * Option flags passed to lock operations that witness also needs to know 7550276Speter * about or that are generic across all locks. 7650276Speter */ 77166124Srafan#define LOP_QUIET 0x00000002 /* Don't log locking operations. */ 7850276Speter#define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ 7950276Speter#define LOP_EXCLUSIVE 0x00000008 /* Exclusive lock. */ 8050276Speter 8150276Speter/* Flags passed to witness_assert. */ 8250276Speter#define LA_UNLOCKED 0x00000000 /* Lock is unlocked. */ 8350276Speter#define LA_LOCKED 0x00000001 /* Lock is at least share locked. */ 8450276Speter#define LA_SLOCKED 0x00000002 /* Lock is exactly share locked. */ 8550276Speter#define LA_XLOCKED 0x00000004 /* Lock is exclusively locked. */ 8650276Speter#define LA_RECURSED 0x00000008 /* Lock is recursed. */ 8750276Speter#define LA_NOTRECURSED 0x00000010 /* Lock is not recursed. */ 8850276Speter 8950276Speter#ifdef _KERNEL 9062449Speter/* 9162449Speter * Lock instances. A lock instance is the data associated with a lock while 92166124Srafan * it is held by witness. For example, a lock instance will hold the 93166124Srafan * recursion count of a lock. Lock instances are held in lists. Spin locks 94166124Srafan * are held in a per-cpu list while sleep locks are held in per-process list. 9550276Speter */ 9650276Speterstruct lock_instance { 9750276Speter struct lock_object *li_lock; 9850276Speter const char *li_file; /* File and line of last acquire. */ 9950276Speter int li_line; 10050276Speter u_int li_flags; /* Recursion count and LI_* flags. */ 10150276Speter}; 102166124Srafan 10350276Speter/* 10497049Speter * A simple list type used to build the list of locks held by a process 10562449Speter * or CPU. We can't simply embed the list in struct lock_object since a 10662449Speter * lock may be held by more than one process if it is a shared lock. Locks 10797049Speter * are added to the head of the list, so we fill up each list entry from 10862449Speter * "the back" logically. To ease some of the arithmetic, we actually fill 10950276Speter * in each list entry the normal way (childer[0] then children[1], etc.) but 11050276Speter * when we traverse the list we read children[count-1] as the first entry 11150276Speter * down to children[0] as the final entry. 11250276Speter */ 11350276Speter#define LOCK_NCHILDREN 3 11450276Speter 11550276Speterstruct lock_list_entry { 11650276Speter struct lock_list_entry *ll_next; 11762449Speter struct lock_instance ll_children[LOCK_NCHILDREN]; 11862449Speter u_int ll_count; 11950276Speter}; 12050276Speter 12162449Speter/* 12266963Speter * If any of WITNESS, INVARIANTS, or KTR_LOCK KTR tracing has been enabled, 12350276Speter * then turn on LOCK_DEBUG. When this option is on, extra debugging 12450276Speter * facilities such as tracking the file and line number of lock operations 12556639Speter * are enabled. Also, mutex locking operations are not inlined to avoid 12650276Speter * bloat from all the extra debugging code. We also have to turn on all the 12750276Speter * calling conventions for this debugging code in modules so that modules can 12866963Speter * work with both debug and non-debug kernels. 12950276Speter */ 13062449Speter#if defined(KLD_MODULE) || defined(WITNESS) || defined(INVARIANTS) || defined(INVARIANT_SUPPORT) || defined(KTR) 13156639Speter#define LOCK_DEBUG 1 13266963Speter#else 13366963Speter#define LOCK_DEBUG 0 13466963Speter#endif 13566963Speter 13666963Speter/* 13766963Speter * In the LOCK_DEBUG case, use the filename and line numbers for debugging 13866963Speter * operations. Otherwise, use default values to avoid the unneeded bloat. 13966963Speter */ 14050276Speter#if LOCK_DEBUG > 0 14150276Speter#define LOCK_FILE __FILE__ 14250276Speter#define LOCK_LINE __LINE__ 14356639Speter#else 14450276Speter#define LOCK_FILE NULL 14556639Speter#define LOCK_LINE 0 14656639Speter#endif 14756639Speter 14856639Speter/* 14956639Speter * Macros for KTR_LOCK tracing. 15056639Speter * 15156639Speter * opname - name of this operation (LOCK/UNLOCK/SLOCK, etc.) 15266963Speter * lo - struct lock_object * for this lock 15356639Speter * flags - flags passed to the lock operation 15466963Speter * recurse - this locks recursion level (or 0 if class is not recursable) 15556639Speter * result - result of a try lock operation 15656639Speter * file - file name 15756639Speter * line - line number 15856639Speter */ 15950276Speter#define LOCK_LOG_TEST(lo, flags) \ 16056639Speter (((flags) & LOP_QUIET) == 0 && ((lo)->lo_flags & LO_QUIET) == 0) 16162449Speter 16250276Speter#define LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do { \ 16350276Speter if (LOCK_LOG_TEST((lo), (flags))) \ 16450276Speter CTR5(KTR_LOCK, opname " (%s) %s r = %d at %s:%d", \ 16550276Speter (lo)->lo_class->lc_name, (lo)->lo_name, \ 16650276Speter (u_int)(recurse), (file), (line)); \ 16750276Speter} while (0) 16850276Speter 16950276Speter#define LOCK_LOG_TRY(opname, lo, flags, result, file, line) do { \ 170166124Srafan if (LOCK_LOG_TEST((lo), (flags))) \ 17162449Speter CTR5(KTR_LOCK, "TRY_" opname " (%s) %s result=%d at %s:%d",\ 17250276Speter (lo)->lo_class->lc_name, (lo)->lo_name, \ 17362449Speter (u_int)(result), (file), (line)); \ 17466963Speter} while (0) 17550276Speter 17662449Speter#define LOCK_LOG_INIT(lo, flags) do { \ 17750276Speter if (LOCK_LOG_TEST((lo), (flags))) \ 17862449Speter CTR4(KTR_LOCK, "%s: %p (%s) %s", __func__, (lo), \ 17962449Speter (lo)->lo_class->lc_name, (lo)->lo_name); \ 18050276Speter} while (0) 18150276Speter 182166124Srafan#define LOCK_LOG_DESTROY(lo, flags) LOCK_LOG_INIT(lo, flags) 18397049Speter 18450276Speter/* 185166124Srafan * Helpful macros for quickly coming up with assertions with informative 186166124Srafan * panic messages. 18797049Speter */ 18897049Speter#define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) 189166124Srafan#define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) 19050276Speter#define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) 191166124Srafan#define MPASS4(ex, what, file, line) \ 192166124Srafan KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) 193166124Srafan 194166124Srafanextern struct lock_class lock_class_mtx_sleep; 195166124Srafanextern struct lock_class lock_class_mtx_spin; 196166124Srafanextern struct lock_class lock_class_sx; 197166124Srafan 198166124Srafanvoid witness_init(struct lock_object *); 199166124Srafanvoid witness_destroy(struct lock_object *); 200166124Srafanvoid witness_lock(struct lock_object *, int, const char *, int); 201166124Srafanvoid witness_upgrade(struct lock_object *, int, const char *, int); 202166124Srafanvoid witness_downgrade(struct lock_object *, int, const char *, int); 203166124Srafanvoid witness_unlock(struct lock_object *, int, const char *, int); 204166124Srafanvoid witness_save(struct lock_object *, const char **, int *); 205166124Srafanvoid witness_restore(struct lock_object *, const char *, int); 206166124Srafanint witness_list_locks(struct lock_list_entry **); 207166124Srafanint witness_warn(int, struct lock_object *, const char *, ...); 208166124Srafanvoid witness_assert(struct lock_object *, int, const char *, int); 209166124Srafanint witness_line(struct lock_object *); 210166124Srafanconst char *witness_file(struct lock_object *); 211166124Srafan 212166124Srafan#ifdef WITNESS 213166124Srafan 214166124Srafan/* Flags for witness_warn(). */ 215166124Srafan#define WARN_GIANTOK 0x01 /* Giant is exempt from this check. */ 216166124Srafan#define WARN_PANIC 0x02 /* Panic if check fails. */ 217166124Srafan#define WARN_SLEEPOK 0x04 /* Sleepable locks are exempt from check. */ 218166124Srafan 219166124Srafan#define WITNESS_INIT(lock) \ 220166124Srafan witness_init((lock)) 221166124Srafan 222166124Srafan#define WITNESS_DESTROY(lock) \ 223166124Srafan witness_destroy(lock) 224166124Srafan 225166124Srafan#define WITNESS_LOCK(lock, flags, file, line) \ 226166124Srafan witness_lock((lock), (flags), (file), (line)) 227166124Srafan 228166124Srafan#define WITNESS_UPGRADE(lock, flags, file, line) \ 229166124Srafan witness_upgrade((lock), (flags), (file), (line)) 230166124Srafan 231166124Srafan#define WITNESS_DOWNGRADE(lock, flags, file, line) \ 232166124Srafan witness_downgrade((lock), (flags), (file), (line)) 233166124Srafan 234166124Srafan#define WITNESS_UNLOCK(lock, flags, file, line) \ 235166124Srafan witness_unlock((lock), (flags), (file), (line)) 236166124Srafan 237166124Srafan#define WITNESS_WARN(flags, lock, fmt, ...) \ 238166124Srafan witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 239166124Srafan 240166124Srafan#define WITNESS_SAVE_DECL(n) \ 241166124Srafan const char * __CONCAT(n, __wf); \ 242166124Srafan int __CONCAT(n, __wl) 243166124Srafan 244166124Srafan#define WITNESS_SAVE(lock, n) \ 245166124Srafan witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl)) 246166124Srafan 247166124Srafan#define WITNESS_RESTORE(lock, n) \ 248166124Srafan witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl)) 249166124Srafan 250166124Srafan#define WITNESS_FILE(lock) \ 251166124Srafan witness_file(lock) 252166124Srafan 253166124Srafan#define WITNESS_LINE(lock) \ 254166124Srafan witness_line(lock) 255166124Srafan 256166124Srafan#else /* WITNESS */ 257166124Srafan#define WITNESS_INIT(lock) ((lock)->lo_flags |= LO_INITIALIZED) 258166124Srafan#define WITNESS_DESTROY(lock) ((lock)->lo_flags &= ~LO_INITIALIZED) 259166124Srafan#define WITNESS_LOCK(lock, flags, file, line) 260166124Srafan#define WITNESS_UPGRADE(lock, flags, file, line) 261166124Srafan#define WITNESS_DOWNGRADE(lock, flags, file, line) 262166124Srafan#define WITNESS_UNLOCK(lock, flags, file, line) 263166124Srafan#define WITNESS_WARN(flags, lock, fmt, ...) 264166124Srafan#define WITNESS_SAVE_DECL(n) 265166124Srafan#define WITNESS_SAVE(lock, n) 266166124Srafan#define WITNESS_RESTORE(lock, n) 267166124Srafan#define WITNESS_FILE(lock) ("?") 268166124Srafan#define WITNESS_LINE(lock) (0) 269166124Srafan#endif /* WITNESS */ 270166124Srafan 271166124Srafan#endif /* _KERNEL */ 272166124Srafan#endif /* _SYS_LOCK_H_ */ 273166124Srafan