kern_lock.c revision 178159
1/*-
2 * Copyright (c) 2008 Attilio Rao <attilio@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice(s), this list of conditions and the following disclaimer as
10 *    the first lines of this file unmodified other than the possible
11 *    addition of one or more copyright notices.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice(s), this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 * DAMAGE.
27 */
28
29#include "opt_ddb.h"
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/kern/kern_lock.c 178159 2008-04-12 19:57:30Z attilio $");
33
34#include <sys/param.h>
35#include <sys/ktr.h>
36#include <sys/lock.h>
37#include <sys/lock_profile.h>
38#include <sys/lockmgr.h>
39#include <sys/mutex.h>
40#include <sys/proc.h>
41#include <sys/sleepqueue.h>
42#ifdef DEBUG_LOCKS
43#include <sys/stack.h>
44#endif
45#include <sys/systm.h>
46
47#include <machine/cpu.h>
48
49#ifdef DDB
50#include <ddb/ddb.h>
51#endif
52
53CTASSERT(((LK_CANRECURSE | LK_NOSHARE) & LO_CLASSFLAGS) ==
54    (LK_CANRECURSE | LK_NOSHARE));
55
56#define	SQ_EXCLUSIVE_QUEUE	0
57#define	SQ_SHARED_QUEUE		1
58
59#ifndef INVARIANTS
60#define	_lockmgr_assert(lk, what, file, line)
61#define	TD_LOCKS_INC(td)
62#define	TD_LOCKS_DEC(td)
63#else
64#define	TD_LOCKS_INC(td)	((td)->td_locks++)
65#define	TD_LOCKS_DEC(td)	((td)->td_locks--)
66#endif
67#define	TD_SLOCKS_INC(td)	((td)->td_lk_slocks++)
68#define	TD_SLOCKS_DEC(td)	((td)->td_lk_slocks--)
69
70#ifndef DEBUG_LOCKS
71#define	STACK_PRINT(lk)
72#define	STACK_SAVE(lk)
73#define	STACK_ZERO(lk)
74#else
75#define	STACK_PRINT(lk)	stack_print_ddb(&(lk)->lk_stack)
76#define	STACK_SAVE(lk)	stack_save(&(lk)->lk_stack)
77#define	STACK_ZERO(lk)	stack_zero(&(lk)->lk_stack)
78#endif
79
80#define	LOCK_LOG2(lk, string, arg1, arg2)				\
81	if (LOCK_LOG_TEST(&(lk)->lock_object, 0))			\
82		CTR2(KTR_LOCK, (string), (arg1), (arg2))
83#define	LOCK_LOG3(lk, string, arg1, arg2, arg3)				\
84	if (LOCK_LOG_TEST(&(lk)->lock_object, 0))			\
85		CTR3(KTR_LOCK, (string), (arg1), (arg2), (arg3))
86
87#define	GIANT_DECLARE							\
88	int _i = 0;							\
89	WITNESS_SAVE_DECL(Giant)
90#define	GIANT_RESTORE() do {						\
91	if (_i > 0) {							\
92		while (_i--)						\
93			mtx_lock(&Giant);				\
94		WITNESS_RESTORE(&Giant.lock_object, Giant);		\
95	}								\
96} while (0)
97#define	GIANT_SAVE() do {						\
98	if (mtx_owned(&Giant)) {					\
99		WITNESS_SAVE(&Giant.lock_object, Giant);		\
100		while (mtx_owned(&Giant)) {				\
101			_i++;						\
102			mtx_unlock(&Giant);				\
103		}							\
104	}								\
105} while (0)
106
107#define	LK_CAN_SHARE(x)							\
108	(((x) & LK_SHARE) && (((x) & LK_EXCLUSIVE_WAITERS) == 0 ||	\
109	curthread->td_lk_slocks || (curthread->td_pflags & TDP_DEADLKTREAT)))
110#define	LK_TRYOP(x)							\
111	((x) & LK_NOWAIT)
112
113#define	LK_CAN_WITNESS(x)						\
114	(((x) & LK_NOWITNESS) == 0 && !LK_TRYOP(x))
115#define	LK_TRYWIT(x)							\
116	(LK_TRYOP(x) ? LOP_TRYLOCK : 0)
117
118#define	lockmgr_disowned(lk)						\
119	(((lk)->lk_lock & ~(LK_FLAGMASK & ~LK_SHARE)) == LK_KERNPROC)
120
121#define	lockmgr_xlocked(lk)						\
122	(((lk)->lk_lock & ~(LK_FLAGMASK & ~LK_SHARE)) == (uintptr_t)curthread)
123
124static void	 assert_lockmgr(struct lock_object *lock, int how);
125#ifdef DDB
126static void	 db_show_lockmgr(struct lock_object *lock);
127#endif
128static void	 lock_lockmgr(struct lock_object *lock, int how);
129static int	 unlock_lockmgr(struct lock_object *lock);
130
131struct lock_class lock_class_lockmgr = {
132	.lc_name = "lockmgr",
133	.lc_flags = LC_RECURSABLE | LC_SLEEPABLE | LC_SLEEPLOCK | LC_UPGRADABLE,
134	.lc_assert = assert_lockmgr,
135#ifdef DDB
136	.lc_ddb_show = db_show_lockmgr,
137#endif
138	.lc_lock = lock_lockmgr,
139	.lc_unlock = unlock_lockmgr
140};
141
142static __inline struct thread *
143lockmgr_xholder(struct lock *lk)
144{
145	uintptr_t x;
146
147	x = lk->lk_lock;
148	return ((x & LK_SHARE) ? NULL : (struct thread *)LK_HOLDER(x));
149}
150
151/*
152 * It assumes sleepq_lock held and returns with this one unheld.
153 * It also assumes the generic interlock is sane and previously checked.
154 * If LK_INTERLOCK is specified the interlock is not reacquired after the
155 * sleep.
156 */
157static __inline int
158sleeplk(struct lock *lk, u_int flags, struct lock_object *ilk,
159    const char *wmesg, int pri, int timo, int queue)
160{
161	GIANT_DECLARE;
162	struct lock_class *class;
163	int catch, error;
164
165	class = (flags & LK_INTERLOCK) ? LOCK_CLASS(ilk) : NULL;
166	catch = (pri) ? (pri & PCATCH) : 0;
167	pri &= PRIMASK;
168	error = 0;
169
170	LOCK_LOG3(lk, "%s: %p blocking on the %s sleepqueue", __func__, lk,
171	    (queue == SQ_EXCLUSIVE_QUEUE) ? "exclusive" : "shared");
172
173	if (flags & LK_INTERLOCK)
174		class->lc_unlock(ilk);
175	GIANT_SAVE();
176	sleepq_add(&lk->lock_object, NULL, wmesg, SLEEPQ_LK | (catch ?
177	    SLEEPQ_INTERRUPTIBLE : 0), queue);
178	if ((flags & LK_TIMELOCK) && timo)
179		sleepq_set_timeout(&lk->lock_object, timo);
180
181	/*
182	 * Decisional switch for real sleeping.
183	 */
184	if ((flags & LK_TIMELOCK) && timo && catch)
185		error = sleepq_timedwait_sig(&lk->lock_object, pri);
186	else if ((flags & LK_TIMELOCK) && timo)
187		error = sleepq_timedwait(&lk->lock_object, pri);
188	else if (catch)
189		error = sleepq_wait_sig(&lk->lock_object, pri);
190	else
191		sleepq_wait(&lk->lock_object, pri);
192	GIANT_RESTORE();
193	if ((flags & LK_SLEEPFAIL) && error == 0)
194		error = ENOLCK;
195
196	return (error);
197}
198
199static __inline void
200wakeupshlk(struct lock *lk, const char *file, int line)
201{
202	uintptr_t v, x;
203	int queue;
204
205	TD_LOCKS_DEC(curthread);
206	TD_SLOCKS_DEC(curthread);
207	WITNESS_UNLOCK(&lk->lock_object, 0, file, line);
208	LOCK_LOG_LOCK("SUNLOCK", &lk->lock_object, 0, 0, file, line);
209
210	for (;;) {
211		x = lk->lk_lock;
212
213		/*
214		 * If there is more than one shared lock held, just drop one
215		 * and return.
216		 */
217		if (LK_SHARERS(x) > 1) {
218			if (atomic_cmpset_ptr(&lk->lk_lock, x,
219			    x - LK_ONE_SHARER))
220				break;
221			continue;
222		}
223
224		/*
225		 * If there are not waiters on the exclusive queue, drop the
226		 * lock quickly.
227		 */
228		if ((x & LK_ALL_WAITERS) == 0) {
229			MPASS(x == LK_SHARERS_LOCK(1));
230			if (atomic_cmpset_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1),
231			    LK_UNLOCKED))
232				break;
233			continue;
234		}
235
236		/*
237		 * We should have a sharer with waiters, so enter the hard
238		 * path in order to handle wakeups correctly.
239		 */
240		sleepq_lock(&lk->lock_object);
241		x = lk->lk_lock & LK_ALL_WAITERS;
242		v = LK_UNLOCKED;
243
244		/*
245		 * If the lock has exclusive waiters, give them preference in
246		 * order to avoid deadlock with shared runners up.
247		 */
248		if (x & LK_EXCLUSIVE_WAITERS) {
249			queue = SQ_EXCLUSIVE_QUEUE;
250			v |= (x & LK_SHARED_WAITERS);
251		} else {
252			MPASS(x == LK_SHARED_WAITERS);
253			queue = SQ_SHARED_QUEUE;
254		}
255
256		if (!atomic_cmpset_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1) | x,
257		    v)) {
258			sleepq_release(&lk->lock_object);
259			continue;
260		}
261		LOCK_LOG3(lk, "%s: %p waking up threads on the %s queue",
262		    __func__, lk, queue == SQ_SHARED_QUEUE ? "shared" :
263		    "exclusive");
264		sleepq_broadcast(&lk->lock_object, SLEEPQ_LK, 0, queue);
265		sleepq_release(&lk->lock_object);
266		break;
267	}
268
269	lock_profile_release_lock(&lk->lock_object);
270}
271
272static void
273assert_lockmgr(struct lock_object *lock, int what)
274{
275
276	panic("lockmgr locks do not support assertions");
277}
278
279static void
280lock_lockmgr(struct lock_object *lock, int how)
281{
282
283	panic("lockmgr locks do not support sleep interlocking");
284}
285
286static int
287unlock_lockmgr(struct lock_object *lock)
288{
289
290	panic("lockmgr locks do not support sleep interlocking");
291}
292
293void
294lockinit(struct lock *lk, int pri, const char *wmesg, int timo, int flags)
295{
296	int iflags;
297
298	MPASS((flags & ~LK_INIT_MASK) == 0);
299
300	iflags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE;
301	if ((flags & LK_NODUP) == 0)
302		iflags |= LO_DUPOK;
303	if (flags & LK_NOPROFILE)
304		iflags |= LO_NOPROFILE;
305	if ((flags & LK_NOWITNESS) == 0)
306		iflags |= LO_WITNESS;
307	if (flags & LK_QUIET)
308		iflags |= LO_QUIET;
309	iflags |= flags & (LK_CANRECURSE | LK_NOSHARE);
310
311	lk->lk_lock = LK_UNLOCKED;
312	lk->lk_recurse = 0;
313	lk->lk_timo = timo;
314	lk->lk_pri = pri;
315	lock_init(&lk->lock_object, &lock_class_lockmgr, wmesg, NULL, iflags);
316	STACK_ZERO(lk);
317}
318
319void
320lockdestroy(struct lock *lk)
321{
322
323	KASSERT(lk->lk_lock == LK_UNLOCKED, ("lockmgr still held"));
324	KASSERT(lk->lk_recurse == 0, ("lockmgr still recursed"));
325	lock_destroy(&lk->lock_object);
326}
327
328int
329__lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
330    const char *wmesg, int pri, int timo, const char *file, int line)
331{
332	GIANT_DECLARE;
333	uint64_t waittime;
334	struct lock_class *class;
335	const char *iwmesg;
336	uintptr_t tid, v, x;
337	u_int op;
338	int contested, error, ipri, itimo, queue;
339
340	contested = 0;
341	error = 0;
342	waittime = 0;
343	tid = (uintptr_t)curthread;
344	op = (flags & LK_TYPE_MASK);
345	iwmesg = (wmesg == LK_WMESG_DEFAULT) ? lk->lock_object.lo_name : wmesg;
346	ipri = (pri == LK_PRIO_DEFAULT) ? lk->lk_pri : pri;
347	itimo = (timo == LK_TIMO_DEFAULT) ? lk->lk_timo : timo;
348
349	MPASS((flags & ~LK_TOTAL_MASK) == 0);
350	KASSERT((op & (op - 1)) == 0,
351	    ("%s: Invalid requested operation @ %s:%d", __func__, file, line));
352	KASSERT((flags & (LK_NOWAIT | LK_SLEEPFAIL)) == 0 ||
353	    (op != LK_DOWNGRADE && op != LK_RELEASE),
354	    ("%s: Invalid flags in regard of the operation desired @ %s:%d",
355	    __func__, file, line));
356	KASSERT((flags & LK_INTERLOCK) == 0 || ilk != NULL,
357	    ("%s: LK_INTERLOCK passed without valid interlock @ %s:%d",
358	    __func__, file, line));
359
360	class = (flags & LK_INTERLOCK) ? LOCK_CLASS(ilk) : NULL;
361	if (panicstr != NULL) {
362		if (flags & LK_INTERLOCK)
363			class->lc_unlock(ilk);
364		return (0);
365	}
366
367	if (op == LK_SHARED && (lk->lock_object.lo_flags & LK_NOSHARE))
368		op = LK_EXCLUSIVE;
369
370	switch (op) {
371	case LK_SHARED:
372		if (LK_CAN_WITNESS(flags))
373			WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER,
374			    file, line);
375		for (;;) {
376			x = lk->lk_lock;
377
378			/*
379			 * If no other thread has an exclusive lock, or
380			 * no exclusive waiter is present, bump the count of
381			 * sharers.  Since we have to preserve the state of
382			 * waiters, if we fail to acquire the shared lock
383			 * loop back and retry.
384			 */
385			if (LK_CAN_SHARE(x)) {
386				if (atomic_cmpset_acq_ptr(&lk->lk_lock, x,
387				    x + LK_ONE_SHARER))
388					break;
389				continue;
390			}
391			lock_profile_obtain_lock_failed(&lk->lock_object,
392			    &contested, &waittime);
393
394			/*
395			 * If the lock is alredy held by curthread in
396			 * exclusive way avoid a deadlock.
397			 */
398			if (LK_HOLDER(x) == tid) {
399				LOCK_LOG2(lk,
400				    "%s: %p alredy held in exclusive mode",
401				    __func__, lk);
402				error = EDEADLK;
403				break;
404			}
405
406			/*
407			 * If the lock is expected to not sleep just give up
408			 * and return.
409			 */
410			if (LK_TRYOP(flags)) {
411				LOCK_LOG2(lk, "%s: %p fails the try operation",
412				    __func__, lk);
413				error = EBUSY;
414				break;
415			}
416
417			/*
418			 * Acquire the sleepqueue chain lock because we
419			 * probabilly will need to manipulate waiters flags.
420			 */
421			sleepq_lock(&lk->lock_object);
422			x = lk->lk_lock;
423
424			/*
425			 * if the lock can be acquired in shared mode, try
426			 * again.
427			 */
428			if (LK_CAN_SHARE(x)) {
429				sleepq_release(&lk->lock_object);
430				continue;
431			}
432
433			/*
434			 * Try to set the LK_SHARED_WAITERS flag.  If we fail,
435			 * loop back and retry.
436			 */
437			if ((x & LK_SHARED_WAITERS) == 0) {
438				if (!atomic_cmpset_acq_ptr(&lk->lk_lock, x,
439				    x | LK_SHARED_WAITERS)) {
440					sleepq_release(&lk->lock_object);
441					continue;
442				}
443				LOCK_LOG2(lk, "%s: %p set shared waiters flag",
444				    __func__, lk);
445			}
446
447			/*
448			 * As far as we have been unable to acquire the
449			 * shared lock and the shared waiters flag is set,
450			 * we will sleep.
451			 */
452			error = sleeplk(lk, flags, ilk, iwmesg, ipri, itimo,
453			    SQ_SHARED_QUEUE);
454			flags &= ~LK_INTERLOCK;
455			if (error) {
456				LOCK_LOG3(lk,
457				    "%s: interrupted sleep for %p with %d",
458				    __func__, lk, error);
459				break;
460			}
461			LOCK_LOG2(lk, "%s: %p resuming from the sleep queue",
462			    __func__, lk);
463		}
464		if (error == 0) {
465			lock_profile_obtain_lock_success(&lk->lock_object,
466			    contested, waittime, file, line);
467			LOCK_LOG_LOCK("SLOCK", &lk->lock_object, 0, 0, file,
468			    line);
469			WITNESS_LOCK(&lk->lock_object, LK_TRYWIT(flags), file,
470			    line);
471			TD_LOCKS_INC(curthread);
472			TD_SLOCKS_INC(curthread);
473			STACK_SAVE(lk);
474		}
475		break;
476	case LK_UPGRADE:
477		_lockmgr_assert(lk, KA_SLOCKED, file, line);
478		x = lk->lk_lock & LK_ALL_WAITERS;
479
480		/*
481		 * Try to switch from one shared lock to an exclusive one.
482		 * We need to preserve waiters flags during the operation.
483		 */
484		if (atomic_cmpset_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1) | x,
485		    tid | x)) {
486			LOCK_LOG_LOCK("XUPGRADE", &lk->lock_object, 0, 0, file,
487			    line);
488			WITNESS_UPGRADE(&lk->lock_object, LOP_EXCLUSIVE |
489			    LK_TRYWIT(flags), file, line);
490			TD_SLOCKS_DEC(curthread);
491			break;
492		}
493
494		/*
495		 * We have been unable to succeed in upgrading, so just
496		 * give up the shared lock.
497		 */
498		wakeupshlk(lk, file, line);
499
500		/* FALLTHROUGH */
501	case LK_EXCLUSIVE:
502		if (LK_CAN_WITNESS(flags))
503			WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
504			    LOP_EXCLUSIVE, file, line);
505
506		/*
507		 * If curthread alredy holds the lock and this one is
508		 * allowed to recurse, simply recurse on it.
509		 */
510		if (lockmgr_xlocked(lk)) {
511			if ((flags & LK_CANRECURSE) == 0 &&
512			    (lk->lock_object.lo_flags & LK_CANRECURSE) == 0) {
513
514				/*
515				 * If the lock is expected to not panic just
516				 * give up and return.
517				 */
518				if (LK_TRYOP(flags)) {
519					LOCK_LOG2(lk,
520					    "%s: %p fails the try operation",
521					    __func__, lk);
522					error = EBUSY;
523					break;
524				}
525				if (flags & LK_INTERLOCK)
526					class->lc_unlock(ilk);
527		panic("%s: recursing on non recursive lockmgr %s @ %s:%d\n",
528				    __func__, iwmesg, file, line);
529			}
530			lk->lk_recurse++;
531			LOCK_LOG2(lk, "%s: %p recursing", __func__, lk);
532			LOCK_LOG_LOCK("XLOCK", &lk->lock_object, 0,
533			    lk->lk_recurse, file, line);
534			WITNESS_LOCK(&lk->lock_object, LOP_EXCLUSIVE |
535			    LK_TRYWIT(flags), file, line);
536			TD_LOCKS_INC(curthread);
537			break;
538		}
539
540		while (!atomic_cmpset_acq_ptr(&lk->lk_lock, LK_UNLOCKED,
541		    tid)) {
542			lock_profile_obtain_lock_failed(&lk->lock_object,
543			    &contested, &waittime);
544
545			/*
546			 * If the lock is expected to not sleep just give up
547			 * and return.
548			 */
549			if (LK_TRYOP(flags)) {
550				LOCK_LOG2(lk, "%s: %p fails the try operation",
551				    __func__, lk);
552				error = EBUSY;
553				break;
554			}
555
556			/*
557			 * Acquire the sleepqueue chain lock because we
558			 * probabilly will need to manipulate waiters flags.
559			 */
560			sleepq_lock(&lk->lock_object);
561			x = lk->lk_lock;
562			v = x & LK_ALL_WAITERS;
563
564			/*
565			 * if the lock has been released while we spun on
566			 * the sleepqueue chain lock just try again.
567			 */
568			if (x == LK_UNLOCKED) {
569				sleepq_release(&lk->lock_object);
570				continue;
571			}
572
573			/*
574			 * The lock can be in the state where there is a
575			 * pending queue of waiters, but still no owner.
576			 * This happens when the lock is contested and an
577			 * owner is going to claim the lock.
578			 * If curthread is the one successfully acquiring it
579			 * claim lock ownership and return, preserving waiters
580			 * flags.
581			 */
582			if (x == (LK_UNLOCKED | v)) {
583				if (atomic_cmpset_acq_ptr(&lk->lk_lock, x,
584				    tid | v)) {
585					sleepq_release(&lk->lock_object);
586					LOCK_LOG2(lk,
587					    "%s: %p claimed by a new writer",
588					    __func__, lk);
589					break;
590				}
591				sleepq_release(&lk->lock_object);
592				continue;
593			}
594
595			/*
596			 * Try to set the LK_EXCLUSIVE_WAITERS flag.  If we
597			 * fail, loop back and retry.
598			 */
599			if ((x & LK_EXCLUSIVE_WAITERS) == 0) {
600				if (!atomic_cmpset_ptr(&lk->lk_lock, x,
601				    x | LK_EXCLUSIVE_WAITERS)) {
602					sleepq_release(&lk->lock_object);
603					continue;
604				}
605				LOCK_LOG2(lk, "%s: %p set excl waiters flag",
606				    __func__, lk);
607			}
608
609			/*
610			 * As far as we have been unable to acquire the
611			 * exclusive lock and the exclusive waiters flag
612			 * is set, we will sleep.
613			 */
614			error = sleeplk(lk, flags, ilk, iwmesg, ipri, itimo,
615			    SQ_EXCLUSIVE_QUEUE);
616			flags &= ~LK_INTERLOCK;
617			if (error) {
618				LOCK_LOG3(lk,
619				    "%s: interrupted sleep for %p with %d",
620				    __func__, lk, error);
621				break;
622			}
623			LOCK_LOG2(lk, "%s: %p resuming from the sleep queue",
624			    __func__, lk);
625		}
626		if (error == 0) {
627			lock_profile_obtain_lock_success(&lk->lock_object,
628			    contested, waittime, file, line);
629			LOCK_LOG_LOCK("XLOCK", &lk->lock_object, 0,
630			    lk->lk_recurse, file, line);
631			WITNESS_LOCK(&lk->lock_object, LOP_EXCLUSIVE |
632			    LK_TRYWIT(flags), file, line);
633			TD_LOCKS_INC(curthread);
634			STACK_SAVE(lk);
635		}
636		break;
637	case LK_DOWNGRADE:
638		_lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED, file, line);
639		LOCK_LOG_LOCK("XDOWNGRADE", &lk->lock_object, 0, 0, file, line);
640		WITNESS_DOWNGRADE(&lk->lock_object, 0, file, line);
641		TD_SLOCKS_INC(curthread);
642
643		/*
644		 * In order to preserve waiters flags, just spin.
645		 */
646		for (;;) {
647			x = lk->lk_lock & LK_ALL_WAITERS;
648			if (atomic_cmpset_rel_ptr(&lk->lk_lock, tid | x,
649			    LK_SHARERS_LOCK(1) | x))
650				break;
651			cpu_spinwait();
652		}
653		break;
654	case LK_RELEASE:
655		_lockmgr_assert(lk, KA_LOCKED, file, line);
656		x = lk->lk_lock;
657
658		if ((x & LK_SHARE) == 0) {
659
660			/*
661			 * As first option, treact the lock as if it has not
662			 * any waiter.
663			 * Fix-up the tid var if the lock has been disowned.
664			 */
665			if (LK_HOLDER(x) == LK_KERNPROC)
666				tid = LK_KERNPROC;
667			else {
668				WITNESS_UNLOCK(&lk->lock_object, LOP_EXCLUSIVE,
669				    file, line);
670				TD_LOCKS_DEC(curthread);
671			}
672			LOCK_LOG_LOCK("XUNLOCK", &lk->lock_object, 0,
673			    lk->lk_recurse, file, line);
674
675			/*
676			 * The lock is held in exclusive mode.
677			 * If the lock is recursed also, then unrecurse it.
678			 */
679			if (lockmgr_xlocked(lk) && lockmgr_recursed(lk)) {
680				LOCK_LOG2(lk, "%s: %p unrecursing", __func__,
681				    lk);
682				lk->lk_recurse--;
683				break;
684			}
685			lock_profile_release_lock(&lk->lock_object);
686
687			if (atomic_cmpset_rel_ptr(&lk->lk_lock, tid,
688			    LK_UNLOCKED))
689				break;
690
691			sleepq_lock(&lk->lock_object);
692			x = lk->lk_lock & LK_ALL_WAITERS;
693			v = LK_UNLOCKED;
694
695			/*
696		 	 * If the lock has exclusive waiters, give them
697			 * preference in order to avoid deadlock with
698			 * shared runners up.
699			 */
700			if (x & LK_EXCLUSIVE_WAITERS) {
701				queue = SQ_EXCLUSIVE_QUEUE;
702				v |= (x & LK_SHARED_WAITERS);
703			} else {
704				MPASS(x == LK_SHARED_WAITERS);
705				queue = SQ_SHARED_QUEUE;
706			}
707
708			LOCK_LOG3(lk,
709			    "%s: %p waking up threads on the %s queue",
710			    __func__, lk, queue == SQ_SHARED_QUEUE ? "shared" :
711			    "exclusive");
712			atomic_store_rel_ptr(&lk->lk_lock, v);
713			sleepq_broadcast(&lk->lock_object, SLEEPQ_LK, 0, queue);
714			sleepq_release(&lk->lock_object);
715			break;
716		} else
717			wakeupshlk(lk, file, line);
718		break;
719	case LK_DRAIN:
720		if (LK_CAN_WITNESS(flags))
721			WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
722			    LOP_EXCLUSIVE, file, line);
723
724		/*
725		 * Trying to drain a lock we alredy own will result in a
726		 * deadlock.
727		 */
728		if (lockmgr_xlocked(lk)) {
729			if (flags & LK_INTERLOCK)
730				class->lc_unlock(ilk);
731			panic("%s: draining %s with the lock held @ %s:%d\n",
732			    __func__, iwmesg, file, line);
733		}
734
735		while (!atomic_cmpset_acq_ptr(&lk->lk_lock, LK_UNLOCKED, tid)) {
736			lock_profile_obtain_lock_failed(&lk->lock_object,
737			    &contested, &waittime);
738
739			/*
740			 * If the lock is expected to not sleep just give up
741			 * and return.
742			 */
743			if (LK_TRYOP(flags)) {
744				LOCK_LOG2(lk, "%s: %p fails the try operation",
745				    __func__, lk);
746				error = EBUSY;
747				break;
748			}
749
750			/*
751			 * Acquire the sleepqueue chain lock because we
752			 * probabilly will need to manipulate waiters flags.
753			 */
754			sleepq_lock(&lk->lock_object);
755			x = lk->lk_lock;
756			v = x & LK_ALL_WAITERS;
757
758			/*
759			 * if the lock has been released while we spun on
760			 * the sleepqueue chain lock just try again.
761			 */
762			if (x == LK_UNLOCKED) {
763				sleepq_release(&lk->lock_object);
764				continue;
765			}
766
767			if (x == (LK_UNLOCKED | v)) {
768				v = x;
769				if (v & LK_EXCLUSIVE_WAITERS) {
770					queue = SQ_EXCLUSIVE_QUEUE;
771					v &= ~LK_EXCLUSIVE_WAITERS;
772				} else {
773					MPASS(v & LK_SHARED_WAITERS);
774					queue = SQ_SHARED_QUEUE;
775					v &= ~LK_SHARED_WAITERS;
776				}
777				if (!atomic_cmpset_ptr(&lk->lk_lock, x, v)) {
778					sleepq_release(&lk->lock_object);
779					continue;
780				}
781				LOCK_LOG3(lk,
782				"%s: %p waking up all threads on the %s queue",
783				    __func__, lk, queue == SQ_SHARED_QUEUE ?
784				    "shared" : "exclusive");
785				sleepq_broadcast(&lk->lock_object, SLEEPQ_LK,
786				    0, queue);
787
788				/*
789				 * If shared waiters have been woken up we need
790				 * to wait for one of them to acquire the lock
791				 * before to set the exclusive waiters in
792				 * order to avoid a deadlock.
793				 */
794				if (queue == SQ_SHARED_QUEUE) {
795					for (v = lk->lk_lock;
796					    (v & LK_SHARE) && !LK_SHARERS(v);
797					    v = lk->lk_lock)
798						cpu_spinwait();
799				}
800			}
801
802			/*
803			 * Try to set the LK_EXCLUSIVE_WAITERS flag.  If we
804			 * fail, loop back and retry.
805			 */
806			if ((x & LK_EXCLUSIVE_WAITERS) == 0) {
807				if (!atomic_cmpset_ptr(&lk->lk_lock, x,
808				    x | LK_EXCLUSIVE_WAITERS)) {
809					sleepq_release(&lk->lock_object);
810					continue;
811				}
812				LOCK_LOG2(lk, "%s: %p set drain waiters flag",
813				    __func__, lk);
814			}
815
816			/*
817			 * As far as we have been unable to acquire the
818			 * exclusive lock and the exclusive waiters flag
819			 * is set, we will sleep.
820			 */
821			if (flags & LK_INTERLOCK) {
822				class->lc_unlock(ilk);
823				flags &= ~LK_INTERLOCK;
824			}
825			GIANT_SAVE();
826			sleepq_add(&lk->lock_object, NULL, iwmesg, SLEEPQ_LK,
827			    SQ_EXCLUSIVE_QUEUE);
828			sleepq_wait(&lk->lock_object, ipri & PRIMASK);
829			GIANT_RESTORE();
830			LOCK_LOG2(lk, "%s: %p resuming from the sleep queue",
831			    __func__, lk);
832		}
833
834		if (error == 0) {
835			lock_profile_obtain_lock_success(&lk->lock_object,
836			    contested, waittime, file, line);
837			LOCK_LOG_LOCK("DRAIN", &lk->lock_object, 0,
838			    lk->lk_recurse, file, line);
839			WITNESS_LOCK(&lk->lock_object, LOP_EXCLUSIVE |
840			    LK_TRYWIT(flags), file, line);
841			TD_LOCKS_INC(curthread);
842			STACK_SAVE(lk);
843		}
844		break;
845	default:
846		if (flags & LK_INTERLOCK)
847			class->lc_unlock(ilk);
848		panic("%s: unknown lockmgr request 0x%x\n", __func__, op);
849	}
850
851	if (flags & LK_INTERLOCK)
852		class->lc_unlock(ilk);
853
854	return (error);
855}
856
857void
858_lockmgr_disown(struct lock *lk, const char *file, int line)
859{
860	uintptr_t tid, x;
861
862	tid = (uintptr_t)curthread;
863	_lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED, file, line);
864
865	/*
866	 * If the owner is alredy LK_KERNPROC just skip the whole operation.
867	 */
868	if (LK_HOLDER(lk->lk_lock) != tid)
869		return;
870	LOCK_LOG_LOCK("XDISOWN", &lk->lock_object, 0, 0, file, line);
871	WITNESS_UNLOCK(&lk->lock_object, LOP_EXCLUSIVE, file, line);
872	TD_LOCKS_DEC(curthread);
873
874	/*
875	 * In order to preserve waiters flags, just spin.
876	 */
877	for (;;) {
878		x = lk->lk_lock & LK_ALL_WAITERS;
879		if (atomic_cmpset_ptr(&lk->lk_lock, tid | x,
880		    LK_KERNPROC | x))
881			return;
882		cpu_spinwait();
883	}
884}
885
886void
887lockmgr_printinfo(struct lock *lk)
888{
889	struct thread *td;
890	uintptr_t x;
891
892	if (lk->lk_lock == LK_UNLOCKED)
893		printf(" lock type %s: UNLOCKED\n", lk->lock_object.lo_name);
894	else if (lk->lk_lock & LK_SHARE)
895		printf(" lock type %s: SHARED (count %ju)\n",
896		    lk->lock_object.lo_name,
897		    (uintmax_t)LK_SHARERS(lk->lk_lock));
898	else {
899		td = lockmgr_xholder(lk);
900		printf(" lock type %s: EXCL by thread %p (pid %d)\n",
901		    lk->lock_object.lo_name, td, td->td_proc->p_pid);
902	}
903
904	x = lk->lk_lock;
905	if (x & LK_EXCLUSIVE_WAITERS)
906		printf(" with exclusive waiters pending\n");
907	if (x & LK_SHARED_WAITERS)
908		printf(" with shared waiters pending\n");
909
910	STACK_PRINT(lk);
911}
912
913int
914lockstatus(struct lock *lk)
915{
916	uintptr_t v, x;
917	int ret;
918
919	ret = LK_SHARED;
920	x = lk->lk_lock;
921	v = LK_HOLDER(x);
922
923	if ((x & LK_SHARE) == 0) {
924		if (v == (uintptr_t)curthread || v == LK_KERNPROC)
925			ret = LK_EXCLUSIVE;
926		else
927			ret = LK_EXCLOTHER;
928	} else if (x == LK_UNLOCKED)
929		ret = 0;
930
931	return (ret);
932}
933
934#ifdef INVARIANT_SUPPORT
935#ifndef INVARIANTS
936#undef	_lockmgr_assert
937#endif
938
939void
940_lockmgr_assert(struct lock *lk, int what, const char *file, int line)
941{
942	int slocked = 0;
943
944	if (panicstr != NULL)
945		return;
946	switch (what) {
947	case KA_SLOCKED:
948	case KA_SLOCKED | KA_NOTRECURSED:
949	case KA_SLOCKED | KA_RECURSED:
950		slocked = 1;
951	case KA_LOCKED:
952	case KA_LOCKED | KA_NOTRECURSED:
953	case KA_LOCKED | KA_RECURSED:
954#ifdef WITNESS
955
956		/*
957		 * We cannot trust WITNESS if the lock is held in exclusive
958		 * mode and a call to lockmgr_disown() happened.
959		 * Workaround this skipping the check if the lock is held in
960		 * exclusive mode even for the KA_LOCKED case.
961		 */
962		if (slocked || (lk->lk_lock & LK_SHARE)) {
963			witness_assert(&lk->lock_object, what, file, line);
964			break;
965		}
966#endif
967		if (lk->lk_lock == LK_UNLOCKED ||
968		    ((lk->lk_lock & LK_SHARE) == 0 && (slocked ||
969		    (!lockmgr_xlocked(lk) && !lockmgr_disowned(lk)))))
970			panic("Lock %s not %slocked @ %s:%d\n",
971			    lk->lock_object.lo_name, slocked ? "share" : "",
972			    file, line);
973
974		if ((lk->lk_lock & LK_SHARE) == 0) {
975			if (lockmgr_recursed(lk)) {
976				if (what & KA_NOTRECURSED)
977					panic("Lock %s recursed @ %s:%d\n",
978					    lk->lock_object.lo_name, file,
979					    line);
980			} else if (what & KA_RECURSED)
981				panic("Lock %s not recursed @ %s:%d\n",
982				    lk->lock_object.lo_name, file, line);
983		}
984		break;
985	case KA_XLOCKED:
986	case KA_XLOCKED | KA_NOTRECURSED:
987	case KA_XLOCKED | KA_RECURSED:
988		if (!lockmgr_xlocked(lk) && !lockmgr_disowned(lk))
989			panic("Lock %s not exclusively locked @ %s:%d\n",
990			    lk->lock_object.lo_name, file, line);
991		if (lockmgr_recursed(lk)) {
992			if (what & KA_NOTRECURSED)
993				panic("Lock %s recursed @ %s:%d\n",
994				    lk->lock_object.lo_name, file, line);
995		} else if (what & KA_RECURSED)
996			panic("Lock %s not recursed @ %s:%d\n",
997			    lk->lock_object.lo_name, file, line);
998		break;
999	case KA_UNLOCKED:
1000		if (lockmgr_xlocked(lk) || lockmgr_disowned(lk))
1001			panic("Lock %s exclusively locked @ %s:%d\n",
1002			    lk->lock_object.lo_name, file, line);
1003		break;
1004	default:
1005		panic("Unknown lockmgr assertion: %d @ %s:%d\n", what, file,
1006		    line);
1007	}
1008}
1009#endif
1010
1011#ifdef DDB
1012int
1013lockmgr_chain(struct thread *td, struct thread **ownerp)
1014{
1015	struct lock *lk;
1016
1017	lk = td->td_wchan;
1018
1019	if (LOCK_CLASS(&lk->lock_object) != &lock_class_lockmgr)
1020		return (0);
1021	db_printf("blocked on lockmgr %s", lk->lock_object.lo_name);
1022	if (lk->lk_lock & LK_SHARE)
1023		db_printf("SHARED (count %ju)\n",
1024		    (uintmax_t)LK_SHARERS(lk->lk_lock));
1025	else
1026		db_printf("EXCL\n");
1027	*ownerp = lockmgr_xholder(lk);
1028
1029	return (1);
1030}
1031
1032static void
1033db_show_lockmgr(struct lock_object *lock)
1034{
1035	struct thread *td;
1036	struct lock *lk;
1037
1038	lk = (struct lock *)lock;
1039
1040	db_printf(" state: ");
1041	if (lk->lk_lock == LK_UNLOCKED)
1042		db_printf("UNLOCKED\n");
1043	else if (lk->lk_lock & LK_SHARE)
1044		db_printf("SLOCK: %ju\n", (uintmax_t)LK_SHARERS(lk->lk_lock));
1045	else {
1046		td = lockmgr_xholder(lk);
1047		if (td == (struct thread *)LK_KERNPROC)
1048			db_printf("XLOCK: LK_KERNPROC\n");
1049		else
1050			db_printf("XLOCK: %p (tid %d, pid %d, \"%s\")\n", td,
1051			    td->td_tid, td->td_proc->p_pid,
1052			    td->td_proc->p_comm);
1053		if (lockmgr_recursed(lk))
1054			db_printf(" recursed: %d\n", lk->lk_recurse);
1055	}
1056	db_printf(" waiters: ");
1057	switch (lk->lk_lock & LK_ALL_WAITERS) {
1058	case LK_SHARED_WAITERS:
1059		db_printf("shared\n");
1060	case LK_EXCLUSIVE_WAITERS:
1061		db_printf("exclusive\n");
1062		break;
1063	case LK_ALL_WAITERS:
1064		db_printf("shared and exclusive\n");
1065		break;
1066	default:
1067		db_printf("none\n");
1068	}
1069}
1070#endif
1071