Deleted Added
full compact
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 ---