kern_lock.c (162941) | kern_lock.c (164159) |
---|---|
1/*- 2 * Copyright (c) 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Copyright (C) 1997 6 * John S. Dyson. All rights reserved. 7 * 8 * This code contains ideas from software contributed to Berkeley by --- 27 unchanged lines hidden (view full) --- 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95 41 */ 42 43#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Copyright (C) 1997 6 * John S. Dyson. All rights reserved. 7 * 8 * This code contains ideas from software contributed to Berkeley by --- 27 unchanged lines hidden (view full) --- 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95 41 */ 42 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: head/sys/kern/kern_lock.c 162941 2006-10-02 02:06:27Z tegge $"); | 44__FBSDID("$FreeBSD: head/sys/kern/kern_lock.c 164159 2006-11-11 03:18:07Z kmacy $"); |
45 46#include "opt_ddb.h" | 45 46#include "opt_ddb.h" |
47#include "opt_global.h" |
|
47 48#include <sys/param.h> 49#include <sys/kdb.h> 50#include <sys/kernel.h> 51#include <sys/ktr.h> 52#include <sys/lock.h> 53#include <sys/lockmgr.h> 54#include <sys/mutex.h> 55#include <sys/proc.h> 56#include <sys/systm.h> | 48 49#include <sys/param.h> 50#include <sys/kdb.h> 51#include <sys/kernel.h> 52#include <sys/ktr.h> 53#include <sys/lock.h> 54#include <sys/lockmgr.h> 55#include <sys/mutex.h> 56#include <sys/proc.h> 57#include <sys/systm.h> |
58#include <sys/lock_profile.h> |
|
57#ifdef DEBUG_LOCKS 58#include <sys/stack.h> 59#endif 60 61#ifdef DDB 62#include <ddb/ddb.h> 63#endif 64 --- 78 unchanged lines hidden (view full) --- 143/* 144 * Set, change, or release a lock. 145 * 146 * Shared requests increment the shared count. Exclusive requests set the 147 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already 148 * accepted shared locks and shared-to-exclusive upgrades to go away. 149 */ 150int | 59#ifdef DEBUG_LOCKS 60#include <sys/stack.h> 61#endif 62 63#ifdef DDB 64#include <ddb/ddb.h> 65#endif 66 --- 78 unchanged lines hidden (view full) --- 145/* 146 * Set, change, or release a lock. 147 * 148 * Shared requests increment the shared count. Exclusive requests set the 149 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already 150 * accepted shared locks and shared-to-exclusive upgrades to go away. 151 */ 152int |
151lockmgr(lkp, flags, interlkp, td) 152 struct lock *lkp; 153 u_int flags; 154 struct mtx *interlkp; 155 struct thread *td; | 153_lockmgr(struct lock *lkp, int flags, struct mtx *interlkp, 154 struct thread *td, char *file, int line) 155 |
156{ 157 int error; 158 struct thread *thr; 159 int extflags, lockflags; | 156{ 157 int error; 158 struct thread *thr; 159 int extflags, lockflags; |
160 uint64_t waitstart; |
|
160 161 error = 0; 162 if (td == NULL) 163 thr = LK_KERNPROC; 164 else 165 thr = td; 166 | 161 162 error = 0; 163 if (td == NULL) 164 thr = LK_KERNPROC; 165 else 166 thr = td; 167 |
168 lock_profile_waitstart(&waitstart); |
|
167 if ((flags & LK_INTERNAL) == 0) 168 mtx_lock(lkp->lk_interlock); 169 CTR6(KTR_LOCK, 170 "lockmgr(): lkp == %p (lk_wmesg == \"%s\"), owner == %p, exclusivecount == %d, flags == 0x%x, " 171 "td == %p", lkp, lkp->lk_wmesg, lkp->lk_lockholder, 172 lkp->lk_exclusivecount, flags, td); 173#ifdef DEBUG_LOCKS 174 { --- 39 unchanged lines hidden (view full) --- 214 if (lkp->lk_lockholder != thr) { 215 lockflags = LK_HAVE_EXCL; 216 if (td != NULL && !(td->td_pflags & TDP_DEADLKTREAT)) 217 lockflags |= LK_WANT_EXCL | LK_WANT_UPGRADE; 218 error = acquire(&lkp, extflags, lockflags); 219 if (error) 220 break; 221 sharelock(td, lkp, 1); | 169 if ((flags & LK_INTERNAL) == 0) 170 mtx_lock(lkp->lk_interlock); 171 CTR6(KTR_LOCK, 172 "lockmgr(): lkp == %p (lk_wmesg == \"%s\"), owner == %p, exclusivecount == %d, flags == 0x%x, " 173 "td == %p", lkp, lkp->lk_wmesg, lkp->lk_lockholder, 174 lkp->lk_exclusivecount, flags, td); 175#ifdef DEBUG_LOCKS 176 { --- 39 unchanged lines hidden (view full) --- 216 if (lkp->lk_lockholder != thr) { 217 lockflags = LK_HAVE_EXCL; 218 if (td != NULL && !(td->td_pflags & TDP_DEADLKTREAT)) 219 lockflags |= LK_WANT_EXCL | LK_WANT_UPGRADE; 220 error = acquire(&lkp, extflags, lockflags); 221 if (error) 222 break; 223 sharelock(td, lkp, 1); |
224 if (lkp->lk_sharecount == 1) 225 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line); 226 |
|
222#if defined(DEBUG_LOCKS) 223 stack_save(&lkp->lk_stack); 224#endif 225 break; 226 } 227 /* 228 * We hold an exclusive lock, so downgrade it to shared. 229 * An alternative would be to fail with EDEADLK. 230 */ 231 sharelock(td, lkp, 1); | 227#if defined(DEBUG_LOCKS) 228 stack_save(&lkp->lk_stack); 229#endif 230 break; 231 } 232 /* 233 * We hold an exclusive lock, so downgrade it to shared. 234 * An alternative would be to fail with EDEADLK. 235 */ 236 sharelock(td, lkp, 1); |
237 if (lkp->lk_sharecount == 1) 238 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line); |
|
232 /* FALLTHROUGH downgrade */ 233 234 case LK_DOWNGRADE: 235 KASSERT(lkp->lk_lockholder == thr && lkp->lk_exclusivecount != 0, 236 ("lockmgr: not holding exclusive lock " 237 "(owner thread (%p) != thread (%p), exlcnt (%d) != 0", 238 lkp->lk_lockholder, thr, lkp->lk_exclusivecount)); 239 sharelock(td, lkp, lkp->lk_exclusivecount); --- 27 unchanged lines hidden (view full) --- 267 * after the upgrade). If we return an error, the file 268 * will always be unlocked. 269 */ 270 if (lkp->lk_lockholder == thr) 271 panic("lockmgr: upgrade exclusive lock"); 272 if (lkp->lk_sharecount <= 0) 273 panic("lockmgr: upgrade without shared"); 274 shareunlock(td, lkp, 1); | 239 /* FALLTHROUGH downgrade */ 240 241 case LK_DOWNGRADE: 242 KASSERT(lkp->lk_lockholder == thr && lkp->lk_exclusivecount != 0, 243 ("lockmgr: not holding exclusive lock " 244 "(owner thread (%p) != thread (%p), exlcnt (%d) != 0", 245 lkp->lk_lockholder, thr, lkp->lk_exclusivecount)); 246 sharelock(td, lkp, lkp->lk_exclusivecount); --- 27 unchanged lines hidden (view full) --- 274 * after the upgrade). If we return an error, the file 275 * will always be unlocked. 276 */ 277 if (lkp->lk_lockholder == thr) 278 panic("lockmgr: upgrade exclusive lock"); 279 if (lkp->lk_sharecount <= 0) 280 panic("lockmgr: upgrade without shared"); 281 shareunlock(td, lkp, 1); |
282 if (lkp->lk_sharecount == 0) 283 lock_profile_release_lock(&lkp->lk_object); |
|
275 /* 276 * If we are just polling, check to see if we will block. 277 */ 278 if ((extflags & LK_NOWAIT) && 279 ((lkp->lk_flags & LK_WANT_UPGRADE) || 280 lkp->lk_sharecount > 1)) { 281 error = EBUSY; 282 break; --- 14 unchanged lines hidden (view full) --- 297 break; 298 } 299 if (lkp->lk_exclusivecount != 0) 300 panic("lockmgr: non-zero exclusive count"); 301 lkp->lk_flags |= LK_HAVE_EXCL; 302 lkp->lk_lockholder = thr; 303 lkp->lk_exclusivecount = 1; 304 COUNT(td, 1); | 284 /* 285 * If we are just polling, check to see if we will block. 286 */ 287 if ((extflags & LK_NOWAIT) && 288 ((lkp->lk_flags & LK_WANT_UPGRADE) || 289 lkp->lk_sharecount > 1)) { 290 error = EBUSY; 291 break; --- 14 unchanged lines hidden (view full) --- 306 break; 307 } 308 if (lkp->lk_exclusivecount != 0) 309 panic("lockmgr: non-zero exclusive count"); 310 lkp->lk_flags |= LK_HAVE_EXCL; 311 lkp->lk_lockholder = thr; 312 lkp->lk_exclusivecount = 1; 313 COUNT(td, 1); |
314 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line); |
|
305#if defined(DEBUG_LOCKS) 306 stack_save(&lkp->lk_stack); 307#endif 308 break; 309 } 310 /* 311 * Someone else has requested upgrade. Release our shared 312 * lock, awaken upgrade requestor if we are the last shared --- 43 unchanged lines hidden (view full) --- 356 break; 357 } 358 lkp->lk_flags |= LK_HAVE_EXCL; 359 lkp->lk_lockholder = thr; 360 if (lkp->lk_exclusivecount != 0) 361 panic("lockmgr: non-zero exclusive count"); 362 lkp->lk_exclusivecount = 1; 363 COUNT(td, 1); | 315#if defined(DEBUG_LOCKS) 316 stack_save(&lkp->lk_stack); 317#endif 318 break; 319 } 320 /* 321 * Someone else has requested upgrade. Release our shared 322 * lock, awaken upgrade requestor if we are the last shared --- 43 unchanged lines hidden (view full) --- 366 break; 367 } 368 lkp->lk_flags |= LK_HAVE_EXCL; 369 lkp->lk_lockholder = thr; 370 if (lkp->lk_exclusivecount != 0) 371 panic("lockmgr: non-zero exclusive count"); 372 lkp->lk_exclusivecount = 1; 373 COUNT(td, 1); |
374 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line); |
|
364#if defined(DEBUG_LOCKS) 365 stack_save(&lkp->lk_stack); 366#endif 367 break; 368 369 case LK_RELEASE: 370 if (lkp->lk_exclusivecount != 0) { 371 if (lkp->lk_lockholder != thr && 372 lkp->lk_lockholder != LK_KERNPROC) { 373 panic("lockmgr: thread %p, not %s %p unlocking", 374 thr, "exclusive lock holder", 375 lkp->lk_lockholder); 376 } 377 if (lkp->lk_lockholder != LK_KERNPROC) 378 COUNT(td, -1); 379 if (lkp->lk_exclusivecount == 1) { 380 lkp->lk_flags &= ~LK_HAVE_EXCL; 381 lkp->lk_lockholder = LK_NOPROC; 382 lkp->lk_exclusivecount = 0; | 375#if defined(DEBUG_LOCKS) 376 stack_save(&lkp->lk_stack); 377#endif 378 break; 379 380 case LK_RELEASE: 381 if (lkp->lk_exclusivecount != 0) { 382 if (lkp->lk_lockholder != thr && 383 lkp->lk_lockholder != LK_KERNPROC) { 384 panic("lockmgr: thread %p, not %s %p unlocking", 385 thr, "exclusive lock holder", 386 lkp->lk_lockholder); 387 } 388 if (lkp->lk_lockholder != LK_KERNPROC) 389 COUNT(td, -1); 390 if (lkp->lk_exclusivecount == 1) { 391 lkp->lk_flags &= ~LK_HAVE_EXCL; 392 lkp->lk_lockholder = LK_NOPROC; 393 lkp->lk_exclusivecount = 0; |
394 lock_profile_release_lock(&lkp->lk_object); |
|
383 } else { 384 lkp->lk_exclusivecount--; 385 } 386 } else if (lkp->lk_flags & LK_SHARE_NONZERO) 387 shareunlock(td, lkp, 1); 388 else { 389 printf("lockmgr: thread %p unlocking unheld lock\n", 390 thr); --- 113 unchanged lines hidden (view full) --- 504 lkp->lk_prio = prio; 505 lkp->lk_wmesg = wmesg; 506 lkp->lk_timo = timo; 507 lkp->lk_lockholder = LK_NOPROC; 508 lkp->lk_newlock = NULL; 509#ifdef DEBUG_LOCKS 510 stack_zero(&lkp->lk_stack); 511#endif | 395 } else { 396 lkp->lk_exclusivecount--; 397 } 398 } else if (lkp->lk_flags & LK_SHARE_NONZERO) 399 shareunlock(td, lkp, 1); 400 else { 401 printf("lockmgr: thread %p unlocking unheld lock\n", 402 thr); --- 113 unchanged lines hidden (view full) --- 516 lkp->lk_prio = prio; 517 lkp->lk_wmesg = wmesg; 518 lkp->lk_timo = timo; 519 lkp->lk_lockholder = LK_NOPROC; 520 lkp->lk_newlock = NULL; 521#ifdef DEBUG_LOCKS 522 stack_zero(&lkp->lk_stack); 523#endif |
524 lock_profile_object_init(&lkp->lk_object, wmesg); |
|
512} 513 514/* 515 * Destroy a lock. 516 */ 517void 518lockdestroy(lkp) 519 struct lock *lkp; 520{ 521 CTR2(KTR_LOCK, "lockdestroy(): lkp == %p (lk_wmesg == \"%s\")", 522 lkp, lkp->lk_wmesg); | 525} 526 527/* 528 * Destroy a lock. 529 */ 530void 531lockdestroy(lkp) 532 struct lock *lkp; 533{ 534 CTR2(KTR_LOCK, "lockdestroy(): lkp == %p (lk_wmesg == \"%s\")", 535 lkp, lkp->lk_wmesg); |
536 lock_profile_object_destroy(&lkp->lk_object); |
|
523} 524 525/* 526 * Determine the status of a lock. 527 */ 528int 529lockstatus(lkp, td) 530 struct lock *lkp; --- 128 unchanged lines hidden --- | 537} 538 539/* 540 * Determine the status of a lock. 541 */ 542int 543lockstatus(lkp, td) 544 struct lock *lkp; --- 128 unchanged lines hidden --- |