xref: /dragonfly/sys/kern/kern_lock.c (revision e26d350b)
1 /*
2  * Copyright (c) 1995
3  *	The Regents of the University of California.  All rights reserved.
4  * Copyright (C) 1997
5  *	John S. Dyson.  All rights reserved.
6  * Copyright (C) 2013-2017
7  *	Matthew Dillon, All rights reserved.
8  *
9  * This code contains ideas from software contributed to Berkeley by
10  * Avadis Tevanian, Jr., Michael Wayne Young, and the Mach Operating
11  * System project at Carnegie-Mellon University.
12  *
13  * This code is derived from software contributed to The DragonFly Project
14  * by Matthew Dillon <dillon@backplane.com>.  Extensively rewritten.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
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 
41 #include "opt_lint.h"
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/proc.h>
47 #include <sys/lock.h>
48 #include <sys/sysctl.h>
49 #include <sys/spinlock.h>
50 #include <sys/thread2.h>
51 #include <sys/spinlock2.h>
52 #include <sys/indefinite2.h>
53 
54 static void undo_shreq(struct lock *lkp);
55 static int undo_upreq(struct lock *lkp);
56 static int undo_exreq(struct lock *lkp);
57 
58 #ifdef DEBUG_CANCEL_LOCKS
59 
60 static int sysctl_cancel_lock(SYSCTL_HANDLER_ARGS);
61 static int sysctl_cancel_test(SYSCTL_HANDLER_ARGS);
62 
63 static struct lock cancel_lk;
64 LOCK_SYSINIT(cancellk, &cancel_lk, "cancel", 0);
65 SYSCTL_PROC(_kern, OID_AUTO, cancel_lock, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
66 	    sysctl_cancel_lock, "I", "test cancelable locks");
67 SYSCTL_PROC(_kern, OID_AUTO, cancel_test, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
68 	    sysctl_cancel_test, "I", "test cancelable locks");
69 
70 #endif
71 
72 int lock_test_mode;
73 SYSCTL_INT(_debug, OID_AUTO, lock_test_mode, CTLFLAG_RW,
74 	   &lock_test_mode, 0, "");
75 
76 /*
77  * Locking primitives implementation.
78  * Locks provide shared/exclusive sychronization.
79  */
80 
81 #ifdef DEBUG_LOCKS
82 #define COUNT(td, x) (td)->td_locks += (x)
83 #else
84 #define COUNT(td, x) do { } while (0)
85 #endif
86 
87 /*
88  * Helper, assert basic conditions
89  */
90 static __inline void
91 _lockmgr_assert(struct lock *lkp, u_int flags)
92 {
93 	if (mycpu->gd_intr_nesting_level &&
94 	    (flags & LK_NOWAIT) == 0 &&
95 	    (flags & LK_TYPE_MASK) != LK_RELEASE &&
96 	    panic_cpu_gd != mycpu
97 	) {
98 		panic("lockmgr %s from %p: called from interrupt, ipi, "
99 		      "or hard code section",
100 		      lkp->lk_wmesg, ((int **)&lkp)[-1]);
101 	}
102 }
103 
104 /*
105  * Acquire a shared lock
106  */
107 int
108 lockmgr_shared(struct lock *lkp, u_int flags)
109 {
110 	uint32_t extflags;
111 	thread_t td;
112 	uint64_t count;
113 	int error;
114 	int pflags;
115 	int timo;
116 	int didloop;
117 
118 	_lockmgr_assert(lkp, flags);
119 	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
120 	td = curthread;
121 
122 	count = lkp->lk_count;
123 	cpu_ccfence();
124 
125 	/*
126 	 * If the caller already holds the lock exclusively then
127 	 * we silently obtain another count on the exclusive lock.
128 	 * Avoid accessing lk_lockholder until testing exclusivity.
129 	 *
130 	 * WARNING!  The old FreeBSD behavior was to downgrade,
131 	 *	     but this creates a problem when recursions
132 	 *	     return to the caller and the caller expects
133 	 *	     its original exclusive lock to remain exclusively
134 	 *	     locked.
135 	 */
136 	if ((count & LKC_XMASK) && lkp->lk_lockholder == td) {
137 		KKASSERT(lkp->lk_count & LKC_XMASK);
138 		if ((extflags & LK_CANRECURSE) == 0) {
139 			if (extflags & LK_NOWAIT)
140 				return EBUSY;
141 			panic("lockmgr: locking against myself");
142 		}
143 		atomic_add_64(&lkp->lk_count, 1);
144 		COUNT(td, 1);
145 		return 0;
146 	}
147 
148 	/*
149 	 * Unless TDF_DEADLKTREAT is set, we cannot add LKC_SCOUNT while
150 	 * SHARED is set and either EXREQ or UPREQ are set.
151 	 *
152 	 * NOTE: In the race-to-0 case (see undo_shreq()), we could
153 	 *	 theoretically work the SMASK == 0 case here.
154 	 */
155 	if ((td->td_flags & TDF_DEADLKTREAT) == 0) {
156 		while ((count & LKC_SHARED) &&
157 		       (count & (LKC_EXREQ | LKC_UPREQ))) {
158 			/*
159 			 * Immediate failure conditions
160 			 */
161 			if (extflags & LK_CANCELABLE) {
162 				if (count & LKC_CANCEL)
163 					return ENOLCK;
164 			}
165 			if (extflags & LK_NOWAIT)
166 				return EBUSY;
167 
168 			/*
169 			 * Interlocked tsleep
170 			 */
171 			pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
172 			timo = (extflags & LK_TIMELOCK) ? lkp->lk_timo : 0;
173 
174 			tsleep_interlock(lkp, pflags);
175 			count = atomic_fetchadd_long(&lkp->lk_count, 0);
176 
177 			if ((count & LKC_SHARED) &&
178 			    (count & (LKC_EXREQ | LKC_UPREQ))) {
179 				error = tsleep(lkp, pflags | PINTERLOCKED,
180 					       lkp->lk_wmesg, timo);
181 				if (error)
182 					return error;
183 				count = lkp->lk_count;
184 				cpu_ccfence();
185 				continue;
186 			}
187 			break;
188 		}
189 	}
190 
191 	/*
192 	 * Bump the SCOUNT field.  The shared lock is granted only once
193 	 * the SHARED flag gets set.  If it is already set, we are done.
194 	 *
195 	 * (Racing an EXREQ or UPREQ operation is ok here, we already did
196 	 * our duty above).
197 	 */
198 	count = atomic_fetchadd_64(&lkp->lk_count, LKC_SCOUNT) + LKC_SCOUNT;
199 	error = 0;
200 	didloop = 0;
201 
202 	for (;;) {
203 		/*
204 		 * We may be able to grant ourselves the bit trivially.
205 		 * We're done once the SHARED bit is granted.
206 		 */
207 		if ((count & (LKC_XMASK | LKC_EXREQ |
208 			      LKC_UPREQ | LKC_SHARED)) == 0) {
209 			if (atomic_fcmpset_64(&lkp->lk_count,
210 					      &count, count | LKC_SHARED)) {
211 				/* count |= LKC_SHARED; NOT USED */
212 				break;
213 			}
214 			continue;
215 		}
216 		if ((td->td_flags & TDF_DEADLKTREAT) &&
217 		    (count & (LKC_XMASK | LKC_SHARED)) == 0) {
218 			if (atomic_fcmpset_64(&lkp->lk_count,
219 					      &count, count | LKC_SHARED)) {
220 				/* count |= LKC_SHARED; NOT USED */
221 				break;
222 			}
223 			continue;
224 		}
225 		if (count & LKC_SHARED)
226 			break;
227 
228 		/*
229 		 * Slow path
230 		 */
231 		pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
232 		timo = (extflags & LK_TIMELOCK) ? lkp->lk_timo : 0;
233 
234 		if (extflags & LK_CANCELABLE) {
235 			if (count & LKC_CANCEL) {
236 				undo_shreq(lkp);
237 				error = ENOLCK;
238 				break;
239 			}
240 		}
241 		if (extflags & LK_NOWAIT) {
242 			undo_shreq(lkp);
243 			error = EBUSY;
244 			break;
245 		}
246 
247 		/*
248 		 * Interlocked after the first loop.
249 		 */
250 		if (didloop) {
251 			error = tsleep(lkp, pflags | PINTERLOCKED,
252 				       lkp->lk_wmesg, timo);
253 			if (extflags & LK_SLEEPFAIL) {
254 				undo_shreq(lkp);
255 				error = ENOLCK;
256 				break;
257 			}
258 			if (error) {
259 				undo_shreq(lkp);
260 				break;
261 			}
262 		}
263 		didloop = 1;
264 
265 		/*
266 		 * Reload, shortcut grant case, then loop interlock
267 		 * and loop.
268 		 */
269 		count = lkp->lk_count;
270 		if (count & LKC_SHARED)
271 			break;
272 		tsleep_interlock(lkp, pflags);
273 		count = atomic_fetchadd_64(&lkp->lk_count, 0);
274 	}
275 	if (error == 0)
276 		COUNT(td, 1);
277 
278 	return error;
279 }
280 
281 /*
282  * Acquire an exclusive lock
283  */
284 int
285 lockmgr_exclusive(struct lock *lkp, u_int flags)
286 {
287 	uint64_t count;
288 	uint64_t ncount;
289 	uint32_t extflags;
290 	thread_t td;
291 	int error;
292 	int pflags;
293 	int timo;
294 
295 	_lockmgr_assert(lkp, flags);
296 	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
297 	td = curthread;
298 
299 	error = 0;
300 	count = lkp->lk_count;
301 	cpu_ccfence();
302 
303 	/*
304 	 * Recursive lock if we already hold it exclusively.  Avoid testing
305 	 * lk_lockholder until after testing lk_count.
306 	 */
307 	if ((count & LKC_XMASK) && lkp->lk_lockholder == td) {
308 		if ((extflags & LK_CANRECURSE) == 0) {
309 			if (extflags & LK_NOWAIT)
310 				return EBUSY;
311 			panic("lockmgr: locking against myself");
312 		}
313 		count = atomic_fetchadd_64(&lkp->lk_count, 1) + 1;
314 		KKASSERT((count & LKC_XMASK) > 1);
315 		COUNT(td, 1);
316 		return 0;
317 	}
318 
319 	/*
320 	 * Trivially acquire the lock, or block until we can set EXREQ.
321 	 * Set EXREQ2 if EXREQ is already set or the lock is already
322 	 * held exclusively.  EXREQ2 is an aggregation bit to request
323 	 * a wakeup.
324 	 *
325 	 * WARNING! We cannot set EXREQ if the lock is already held
326 	 *	    exclusively because it may race another EXREQ
327 	 *	    being cleared and granted.  We use the exclusivity
328 	 *	    to prevent both EXREQ and UPREQ from being set.
329 	 *
330 	 *	    This means that both shared and exclusive requests
331 	 *	    have equal priority against a current exclusive holder's
332 	 *	    release.  Exclusive requests still have priority over
333 	 *	    new shared requests when the lock is already held shared.
334 	 */
335 	for (;;) {
336 		/*
337 		 * Normal trivial case
338 		 */
339 		if ((count & (LKC_UPREQ | LKC_EXREQ |
340 			      LKC_XMASK)) == 0 &&
341 		    ((count & LKC_SHARED) == 0 ||
342 		     (count & LKC_SMASK) == 0)) {
343 			ncount = (count + 1) & ~LKC_SHARED;
344 			if (atomic_fcmpset_64(&lkp->lk_count,
345 					      &count, ncount)) {
346 				lkp->lk_lockholder = td;
347 				COUNT(td, 1);
348 				return 0;
349 			}
350 			continue;
351 		}
352 
353 		if (extflags & LK_CANCELABLE) {
354 			if (count & LKC_CANCEL)
355 				return ENOLCK;
356 		}
357 		if (extflags & LK_NOWAIT)
358 			return EBUSY;
359 
360 		/*
361 		 * Interlock to set EXREQ or EXREQ2
362 		 */
363 		pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
364 		timo = (extflags & LK_TIMELOCK) ? lkp->lk_timo : 0;
365 
366 		if (count & (LKC_EXREQ | LKC_XMASK))
367 			ncount = count | LKC_EXREQ2;
368 		else
369 			ncount = count | LKC_EXREQ;
370 		tsleep_interlock(lkp, pflags);
371 		if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
372 			/*
373 			 * If we successfully transitioned to EXREQ we
374 			 * can break out, otherwise we had set EXREQ2 and
375 			 * we block.
376 			 */
377 			if ((count & (LKC_EXREQ | LKC_XMASK)) == 0) {
378 				count = ncount;
379 				break;
380 			}
381 
382 			error = tsleep(lkp, pflags | PINTERLOCKED,
383 				       lkp->lk_wmesg, timo);
384 			count = lkp->lk_count;	/* relod */
385 			cpu_ccfence();
386 		}
387 #ifdef INVARIANTS
388 		if (lock_test_mode > 0) {
389 			--lock_test_mode;
390 			print_backtrace(8);
391 		}
392 #endif
393 		if (error)
394 			return error;
395 		if (extflags & LK_SLEEPFAIL)
396 			return ENOLCK;
397 	}
398 
399 	/*
400 	 * Once EXREQ has been set, wait for it to be granted
401 	 * We enter the loop with tsleep_interlock() already called.
402 	 */
403 	for (;;) {
404 		/*
405 		 * Waiting for EXREQ to be granted to us.
406 		 *
407 		 * NOTE! If we try to trivially get the exclusive lock
408 		 *	 (basically by racing undo_shreq()) and succeed,
409 		 *	 we must still wakeup(lkp) for another exclusive
410 		 *	 lock trying to acquire EXREQ.  Easier to simply
411 		 *	 wait for our own wakeup.
412 		 */
413 		if ((count & LKC_EXREQ) == 0) {
414 			KKASSERT(count & LKC_XMASK);
415 			lkp->lk_lockholder = td;
416 			COUNT(td, 1);
417 			break;
418 		}
419 
420 		/*
421 		 * Block waiting for our exreq to be granted.
422 		 * Check cancelation.  NOWAIT was already dealt with.
423 		 */
424 		if (extflags & LK_CANCELABLE) {
425 			if (count & LKC_CANCEL) {
426 				if (undo_exreq(lkp) == 0) {
427 					lkp->lk_lockholder = LK_KERNTHREAD;
428 					lockmgr_release(lkp, 0);
429 				}
430 				error = ENOLCK;
431 				break;
432 			}
433 		}
434 
435 		pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
436 		timo = (extflags & LK_TIMELOCK) ? lkp->lk_timo : 0;
437 
438 		error = tsleep(lkp, pflags | PINTERLOCKED, lkp->lk_wmesg, timo);
439 #ifdef INVARIANTS
440 		if (lock_test_mode > 0) {
441 			--lock_test_mode;
442 			print_backtrace(8);
443 		}
444 #endif
445 		/*
446 		 * A tsleep error is uncommon.  If it occurs we have to
447 		 * undo our EXREQ.  If we are granted the exclusive lock
448 		 * as we try to undo we have to deal with it.
449 		 */
450 		if (extflags & LK_SLEEPFAIL) {
451 			if (undo_exreq(lkp) == 0) {
452 				lkp->lk_lockholder = LK_KERNTHREAD;
453 				lockmgr_release(lkp, 0);
454 			}
455 			if (error == 0)
456 				error = ENOLCK;
457 			break;
458 		}
459 		if (error) {
460 			if (undo_exreq(lkp))
461 				break;
462 			lkp->lk_lockholder = td;
463 			COUNT(td, 1);
464 			error = 0;
465 			break;
466 		}
467 
468 		/*
469 		 * Reload after sleep, shortcut grant case.
470 		 * Then set the interlock and loop.
471 		 */
472 		count = lkp->lk_count;
473 		cpu_ccfence();
474 		if ((count & LKC_EXREQ) == 0) {
475 			KKASSERT(count & LKC_XMASK);
476 			lkp->lk_lockholder = td;
477 			COUNT(td, 1);
478 			break;
479 		}
480 		tsleep_interlock(lkp, pflags);
481 		count = atomic_fetchadd_64(&lkp->lk_count, 0);
482 	}
483 	return error;
484 }
485 
486 /*
487  * Downgrade an exclusive lock to shared.
488  *
489  * This function always succeeds as long as the caller owns a legal
490  * exclusive lock with one reference.  UPREQ and EXREQ is ignored.
491  */
492 int
493 lockmgr_downgrade(struct lock *lkp, u_int flags)
494 {
495 	uint64_t count;
496 	uint64_t ncount;
497 	uint32_t extflags;
498 	thread_t otd;
499 	thread_t td;
500 
501 	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
502 	td = curthread;
503 	count = lkp->lk_count;
504 
505 	for (;;) {
506 		cpu_ccfence();
507 
508 		/*
509 		 * Downgrade an exclusive lock into a shared lock.  All
510 		 * counts on a recursive exclusive lock become shared.
511 		 *
512 		 * NOTE: Currently to reduce confusion we only allow
513 		 *	 there to be one exclusive lock count, and panic
514 		 *	 if there are more.
515 		 */
516 		if (lkp->lk_lockholder != td || (count & LKC_XMASK) != 1) {
517 			panic("lockmgr: not holding exclusive lock: "
518 			      "%p/%p %016jx", lkp->lk_lockholder, td, count);
519 		}
520 
521 		/*
522 		 * NOTE! Must NULL-out lockholder before releasing the
523 		 *	 exclusive lock.
524 		 *
525 		 * NOTE! There might be pending shared requests, check
526 		 *	 and wake them up.
527 		 */
528 		otd = lkp->lk_lockholder;
529 		lkp->lk_lockholder = NULL;
530 		ncount = (count & ~(LKC_XMASK | LKC_EXREQ2)) +
531 			 ((count & LKC_XMASK) << LKC_SSHIFT);
532 		ncount |= LKC_SHARED;
533 
534 		if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
535 			/*
536 			 * Wakeup any shared waiters (prior SMASK), or
537 			 * any exclusive requests that couldn't set EXREQ
538 			 * because the lock had been held exclusively.
539 			 */
540 			if (count & (LKC_SMASK | LKC_EXREQ2))
541 				wakeup(lkp);
542 			/* count = ncount; NOT USED */
543 			break;
544 		}
545 		lkp->lk_lockholder = otd;
546 		/* retry */
547 	}
548 	return 0;
549 }
550 
551 /*
552  * Upgrade a shared lock to exclusive.  If LK_EXCLUPGRADE then guarantee
553  * that no other exclusive requester can get in front of us and fail
554  * immediately if another upgrade is pending.  If we fail, the shared
555  * lock is released.
556  *
557  * If LK_EXCLUPGRADE is not set and we cannot upgrade because someone
558  * else is in front of us, we release the shared lock and acquire the
559  * exclusive lock normally.  If a failure occurs, the shared lock is
560  * released.
561  */
562 int
563 lockmgr_upgrade(struct lock *lkp, u_int flags)
564 {
565 	uint64_t count;
566 	uint64_t ncount;
567 	uint32_t extflags;
568 	thread_t td;
569 	int error;
570 	int pflags;
571 	int timo;
572 
573 	_lockmgr_assert(lkp, flags);
574 	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
575 	td = curthread;
576 	error = 0;
577 	count = lkp->lk_count;
578 	cpu_ccfence();
579 
580 	/*
581 	 * If we already hold the lock exclusively this operation
582 	 * succeeds and is a NOP.
583 	 */
584 	if (count & LKC_XMASK) {
585 		if (lkp->lk_lockholder == td)
586 			return 0;
587 		panic("lockmgr: upgrade unowned lock");
588 	}
589 	if ((count & LKC_SMASK) == 0)
590 		panic("lockmgr: upgrade unowned lock");
591 
592 	/*
593 	 * Loop to acquire LKC_UPREQ
594 	 */
595 	for (;;) {
596 		/*
597 		 * If UPREQ is already pending, release the shared lock
598 		 * and acquire an exclusive lock normally.
599 		 *
600 		 * If NOWAIT or EXCLUPGRADE the operation must be atomic,
601 		 * and this isn't, so we fail.
602 		 */
603 		if (count & LKC_UPREQ) {
604 			lockmgr_release(lkp, 0);
605 			if ((flags & LK_TYPE_MASK) == LK_EXCLUPGRADE)
606 				error = EBUSY;
607 			else if (extflags & LK_NOWAIT)
608 				error = EBUSY;
609 			else
610 				error = lockmgr_exclusive(lkp, flags);
611 			return error;
612 		}
613 
614 		/*
615 		 * Try to immediately grant the upgrade, handle NOWAIT,
616 		 * or release the shared lock and simultaneously set UPREQ.
617 		 */
618 		if ((count & LKC_SMASK) == LKC_SCOUNT) {
619 			/*
620 			 * Immediate grant
621 			 */
622 			ncount = (count - LKC_SCOUNT + 1) & ~LKC_SHARED;
623 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
624 				lkp->lk_lockholder = td;
625 				return 0;
626 			}
627 		} else if (extflags & LK_NOWAIT) {
628 			/*
629 			 * Early EBUSY if an immediate grant is impossible
630 			 */
631 			lockmgr_release(lkp, 0);
632 			return EBUSY;
633 		} else {
634 			/*
635 			 * Multiple shared locks present, request the
636 			 * upgrade and break to the next loop.
637 			 */
638 			pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
639 			tsleep_interlock(lkp, pflags);
640 			ncount = (count - LKC_SCOUNT) | LKC_UPREQ;
641 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
642 				count = ncount;
643 				break;
644 			}
645 		}
646 		/* retry */
647 	}
648 
649 	/*
650 	 * We have acquired LKC_UPREQ, wait until the upgrade is granted
651 	 * or the tsleep fails.
652 	 *
653 	 * NOWAIT and EXCLUPGRADE have already been handled.  The first
654 	 * tsleep_interlock() has already been associated.
655 	 */
656 	for (;;) {
657 		cpu_ccfence();
658 
659 		/*
660 		 * We were granted our upgrade.  No other UPREQ can be
661 		 * made pending because we are now exclusive.
662 		 */
663 		if ((count & LKC_UPREQ) == 0) {
664 			KKASSERT((count & LKC_XMASK) == 1);
665 			lkp->lk_lockholder = td;
666 			break;
667 		}
668 
669 		if (extflags & LK_CANCELABLE) {
670 			if (count & LKC_CANCEL) {
671 				if (undo_upreq(lkp) == 0) {
672 					lkp->lk_lockholder = LK_KERNTHREAD;
673 					lockmgr_release(lkp, 0);
674 				}
675 				error = ENOLCK;
676 				break;
677 			}
678 		}
679 
680 		pflags = (extflags & LK_PCATCH) ? PCATCH : 0;
681 		timo = (extflags & LK_TIMELOCK) ? lkp->lk_timo : 0;
682 
683 		error = tsleep(lkp, pflags | PINTERLOCKED, lkp->lk_wmesg, timo);
684 		if (extflags & LK_SLEEPFAIL) {
685 			if (undo_upreq(lkp) == 0) {
686 				lkp->lk_lockholder = LK_KERNTHREAD;
687 				lockmgr_release(lkp, 0);
688 			}
689 			if (error == 0)
690 				error = ENOLCK;
691 			break;
692 		}
693 		if (error) {
694 			if (undo_upreq(lkp))
695 				break;
696 			error = 0;
697 		}
698 
699 		/*
700 		 * Reload the lock, short-cut the UPGRANT code before
701 		 * taking the time to interlock and loop.
702 		 */
703 		count = lkp->lk_count;
704 		if ((count & LKC_UPREQ) == 0) {
705 			KKASSERT((count & LKC_XMASK) == 1);
706 			lkp->lk_lockholder = td;
707 			break;
708 		}
709 		tsleep_interlock(lkp, pflags);
710 		count = atomic_fetchadd_64(&lkp->lk_count, 0);
711 		/* retry */
712 	}
713 	return error;
714 }
715 
716 /*
717  * Release a held lock
718  *
719  * NOTE: When releasing to an unlocked state, we set the SHARED bit
720  *	 to optimize shared lock requests.
721  */
722 int
723 lockmgr_release(struct lock *lkp, u_int flags)
724 {
725 	uint64_t count;
726 	uint64_t ncount;
727 	uint32_t extflags;
728 	thread_t otd;
729 	thread_t td;
730 
731 	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
732 	td = curthread;
733 
734 	count = lkp->lk_count;
735 	cpu_ccfence();
736 
737 	for (;;) {
738 		/*
739 		 * Release the currently held lock, grant all requests
740 		 * possible.
741 		 *
742 		 * WARNING! lksleep() assumes that LK_RELEASE does not
743 		 *	    block.
744 		 *
745 		 * Always succeeds.
746 		 * Never blocks.
747 		 */
748 		if ((count & (LKC_SMASK | LKC_XMASK)) == 0)
749 			panic("lockmgr: LK_RELEASE: no lock held");
750 
751 		if (count & LKC_XMASK) {
752 			/*
753 			 * Release exclusively held lock
754 			 */
755 			if (lkp->lk_lockholder != LK_KERNTHREAD &&
756 			    lkp->lk_lockholder != td) {
757 				panic("lockmgr: pid %d, not exclusive "
758 				      "lock holder thr %p/%p unlocking",
759 				    (td->td_proc ? td->td_proc->p_pid : -1),
760 				    td, lkp->lk_lockholder);
761 			}
762 			if ((count & (LKC_UPREQ | LKC_EXREQ |
763 				      LKC_XMASK)) == 1) {
764 				/*
765 				 * Last exclusive count is being released
766 				 * with no UPREQ or EXREQ.  The SHARED
767 				 * bit can be set or not without messing
768 				 * anything up, so precondition it to
769 				 * SHARED (which is the most cpu-optimal).
770 				 *
771 				 * Wakeup any EXREQ2.  EXREQ cannot be
772 				 * set while an exclusive count is present
773 				 * so we have to wakeup any EXREQ2 we find.
774 				 *
775 				 * We could hint the EXREQ2 by leaving
776 				 * SHARED unset, but atm I don't see any
777 				 * usefulness.
778 				 */
779 				otd = lkp->lk_lockholder;
780 				lkp->lk_lockholder = NULL;
781 				ncount = (count - 1);
782 				ncount &= ~(LKC_CANCEL | LKC_EXREQ2);
783 				ncount |= LKC_SHARED;
784 				if (atomic_fcmpset_64(&lkp->lk_count,
785 						      &count, ncount)) {
786 					if (count & (LKC_SMASK | LKC_EXREQ2))
787 						wakeup(lkp);
788 					if (otd != LK_KERNTHREAD)
789 						COUNT(td, -1);
790 					/* count = ncount; NOT USED */
791 					break;
792 				}
793 				lkp->lk_lockholder = otd;
794 				/* retry */
795 			} else if ((count & (LKC_UPREQ | LKC_XMASK)) ==
796 				   (LKC_UPREQ | 1)) {
797 				/*
798 				 * Last exclusive count is being released but
799 				 * an upgrade request is present, automatically
800 				 * grant an exclusive state to the owner of
801 				 * the upgrade request.  Transfer count to
802 				 * grant.
803 				 *
804 				 * EXREQ cannot be set while an exclusive
805 				 * holder exists, so do not clear EXREQ2.
806 				 */
807 				otd = lkp->lk_lockholder;
808 				lkp->lk_lockholder = NULL;
809 				ncount = count & ~LKC_UPREQ;
810 				if (atomic_fcmpset_64(&lkp->lk_count,
811 						      &count, ncount)) {
812 					wakeup(lkp);
813 					if (otd != LK_KERNTHREAD)
814 						COUNT(td, -1);
815 					/* count = ncount; NOT USED */
816 					break;
817 				}
818 				lkp->lk_lockholder = otd;
819 				/* retry */
820 			} else if ((count & (LKC_EXREQ | LKC_XMASK)) ==
821 				   (LKC_EXREQ | 1)) {
822 				/*
823 				 * Last exclusive count is being released but
824 				 * an exclusive request is present.  We
825 				 * automatically grant an exclusive state to
826 				 * the owner of the exclusive request,
827 				 * transfering our count.
828 				 *
829 				 * This case virtually never occurs because
830 				 * EXREQ is not set while exclusive holders
831 				 * exist.  However, it might be set if a
832 				 * an exclusive request is pending and a
833 				 * shared holder upgrades.
834 				 *
835 				 * Don't bother clearing EXREQ2.  A thread
836 				 * waiting to set EXREQ can't do it while
837 				 * an exclusive lock is present.
838 				 */
839 				otd = lkp->lk_lockholder;
840 				lkp->lk_lockholder = NULL;
841 				ncount = count & ~LKC_EXREQ;
842 				if (atomic_fcmpset_64(&lkp->lk_count,
843 						      &count, ncount)) {
844 					wakeup(lkp);
845 					if (otd != LK_KERNTHREAD)
846 						COUNT(td, -1);
847 					/* count = ncount; NOT USED */
848 					break;
849 				}
850 				lkp->lk_lockholder = otd;
851 				/* retry */
852 			} else {
853 				/*
854 				 * Multiple exclusive counts, drop by 1.
855 				 * Since we are the holder and there is more
856 				 * than one count, we can just decrement it.
857 				 */
858 				count =
859 				    atomic_fetchadd_long(&lkp->lk_count, -1);
860 				/* count = count - 1  NOT NEEDED */
861 				if (lkp->lk_lockholder != LK_KERNTHREAD)
862 					COUNT(td, -1);
863 				break;
864 			}
865 			/* retry */
866 		} else {
867 			/*
868 			 * Release shared lock
869 			 */
870 			KKASSERT((count & LKC_SHARED) && (count & LKC_SMASK));
871 			if ((count & (LKC_EXREQ | LKC_UPREQ | LKC_SMASK)) ==
872 			    LKC_SCOUNT) {
873 				/*
874 				 * Last shared count is being released,
875 				 * no exclusive or upgrade request present.
876 				 * Generally leave the shared bit set.
877 				 * Clear the CANCEL bit.
878 				 */
879 				ncount = (count - LKC_SCOUNT) & ~LKC_CANCEL;
880 				if (atomic_fcmpset_64(&lkp->lk_count,
881 						      &count, ncount)) {
882 					COUNT(td, -1);
883 					/* count = ncount; NOT USED */
884 					break;
885 				}
886 				/* retry */
887 			} else if ((count & (LKC_UPREQ | LKC_SMASK)) ==
888 				   (LKC_UPREQ | LKC_SCOUNT)) {
889 				/*
890 				 * Last shared count is being released but
891 				 * an upgrade request is present, automatically
892 				 * grant an exclusive state to the owner of
893 				 * the upgrade request and transfer the count.
894 				 */
895 				ncount = (count - LKC_SCOUNT + 1) &
896 					 ~(LKC_UPREQ | LKC_CANCEL | LKC_SHARED);
897 				if (atomic_fcmpset_64(&lkp->lk_count,
898 						      &count, ncount)) {
899 					wakeup(lkp);
900 					COUNT(td, -1);
901 					/* count = ncount; NOT USED */
902 					break;
903 				}
904 				/* retry */
905 			} else if ((count & (LKC_EXREQ | LKC_SMASK)) ==
906 				   (LKC_EXREQ | LKC_SCOUNT)) {
907 				/*
908 				 * Last shared count is being released but
909 				 * an exclusive request is present, we
910 				 * automatically grant an exclusive state to
911 				 * the owner of the request and transfer
912 				 * the count.
913 				 */
914 				ncount = (count - LKC_SCOUNT + 1) &
915 					 ~(LKC_EXREQ | LKC_EXREQ2 |
916 					   LKC_CANCEL | LKC_SHARED);
917 				if (atomic_fcmpset_64(&lkp->lk_count,
918 						      &count, ncount)) {
919 					wakeup(lkp);
920 					COUNT(td, -1);
921 					/* count = ncount; NOT USED */
922 					break;
923 				}
924 				/* retry */
925 			} else {
926 				/*
927 				 * Shared count is greater than 1.  We can
928 				 * just use undo_shreq() to clean things up.
929 				 * undo_shreq() will also handle races to 0
930 				 * after the fact.
931 				 */
932 				undo_shreq(lkp);
933 				COUNT(td, -1);
934 				break;
935 			}
936 			/* retry */
937 		}
938 		/* retry */
939 	}
940 	return 0;
941 }
942 
943 /*
944  * Start canceling blocked requesters or later requestors.
945  * Only blocked requesters using CANCELABLE can be canceled.
946  *
947  * This is intended to then allow other requesters (usually the
948  * caller) to obtain a non-cancelable lock.
949  *
950  * Don't waste time issuing a wakeup if nobody is pending.
951  */
952 int
953 lockmgr_cancel_beg(struct lock *lkp, u_int flags)
954 {
955 	uint64_t count;
956 
957 	count = lkp->lk_count;
958 	for (;;) {
959 		cpu_ccfence();
960 
961 		KKASSERT((count & LKC_CANCEL) == 0);	/* disallowed case */
962 
963 		/* issue w/lock held */
964 		KKASSERT((count & (LKC_XMASK | LKC_SMASK)) != 0);
965 
966 		if (!atomic_fcmpset_64(&lkp->lk_count,
967 				       &count, count | LKC_CANCEL)) {
968 			continue;
969 		}
970 		/* count |= LKC_CANCEL; NOT USED */
971 
972 		/*
973 		 * Wakeup any waiters.
974 		 *
975 		 * NOTE: EXREQ2 only matters when EXREQ is set, so don't
976 		 *	 bother checking EXREQ2.
977 		 */
978 		if (count & (LKC_EXREQ | LKC_SMASK | LKC_UPREQ)) {
979 			wakeup(lkp);
980 		}
981 		break;
982 	}
983 	return 0;
984 }
985 
986 /*
987  * End our cancel request (typically after we have acquired
988  * the lock ourselves).
989  */
990 int
991 lockmgr_cancel_end(struct lock *lkp, u_int flags)
992 {
993 	atomic_clear_long(&lkp->lk_count, LKC_CANCEL);
994 
995 	return 0;
996 }
997 
998 /*
999  * Backout SCOUNT from a failed shared lock attempt and handle any race
1000  * to 0.  This function is also used by the release code for the less
1001  * optimal race to 0 case.
1002  *
1003  * WARNING! Since we are unconditionally decrementing LKC_SCOUNT, it is
1004  *	    possible for the lock to get into a LKC_SHARED + ZERO SCOUNT
1005  *	    situation.  A shared request can block with a ZERO SCOUNT if
1006  *	    EXREQ or UPREQ is pending in this situation.  Be sure to always
1007  *	    issue a wakeup() in this situation if we are unable to
1008  *	    transition to an exclusive lock, to handle the race.
1009  *
1010  * Always succeeds
1011  * Must not block
1012  */
1013 static void
1014 undo_shreq(struct lock *lkp)
1015 {
1016 	uint64_t count;
1017 	uint64_t ncount;
1018 
1019 	count = atomic_fetchadd_64(&lkp->lk_count, -LKC_SCOUNT) - LKC_SCOUNT;
1020 	while ((count & (LKC_EXREQ | LKC_UPREQ | LKC_CANCEL)) &&
1021 	       (count & (LKC_SMASK | LKC_XMASK)) == 0) {
1022 		/*
1023 		 * Note that UPREQ must have priority over EXREQ, and EXREQ
1024 		 * over CANCEL, so if the atomic op fails we have to loop up.
1025 		 */
1026 		if (count & LKC_UPREQ) {
1027 			ncount = (count + 1) & ~(LKC_UPREQ | LKC_CANCEL |
1028 						 LKC_SHARED);
1029 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1030 				wakeup(lkp);
1031 				/* count = ncount; NOT USED */
1032 				break;
1033 			}
1034 			wakeup(lkp);
1035 			continue;
1036 		}
1037 		if (count & LKC_EXREQ) {
1038 			ncount = (count + 1) & ~(LKC_EXREQ | LKC_EXREQ2 |
1039 						 LKC_CANCEL | LKC_SHARED);
1040 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1041 				wakeup(lkp);
1042 				/* count = ncount; NOT USED */
1043 				break;
1044 			}
1045 			wakeup(lkp);
1046 			continue;
1047 		}
1048 		if (count & LKC_CANCEL) {
1049 			ncount = count & ~LKC_CANCEL;
1050 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1051 				wakeup(lkp);
1052 				/* count = ncount; NOT USED */
1053 				break;
1054 			}
1055 		}
1056 		/* retry */
1057 	}
1058 }
1059 
1060 /*
1061  * Undo an exclusive request.  Returns EBUSY if we were able to undo the
1062  * request, and 0 if the request was granted before we could undo it.
1063  * When 0 is returned, the lock state has not been modified.  The caller
1064  * is responsible for setting the lockholder to curthread.
1065  */
1066 static
1067 int
1068 undo_exreq(struct lock *lkp)
1069 {
1070 	uint64_t count;
1071 	uint64_t ncount;
1072 	int error;
1073 
1074 	count = lkp->lk_count;
1075 	error = 0;
1076 
1077 	for (;;) {
1078 		cpu_ccfence();
1079 
1080 		if ((count & LKC_EXREQ) == 0) {
1081 			/*
1082 			 * EXREQ was granted.  We own the exclusive lock.
1083 			 */
1084 			break;
1085 		}
1086 		if (count & LKC_XMASK) {
1087 			/*
1088 			 * Clear the EXREQ we still own.  Only wakeup on
1089 			 * EXREQ2 if no UPREQ.  There are still exclusive
1090 			 * holders so do not wake up any shared locks or
1091 			 * any UPREQ.
1092 			 *
1093 			 * If there is an UPREQ it will issue a wakeup()
1094 			 * for any EXREQ wait looops, so we can clear EXREQ2
1095 			 * now.
1096 			 */
1097 			ncount = count & ~(LKC_EXREQ | LKC_EXREQ2);
1098 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1099 				if ((count & (LKC_EXREQ2 | LKC_UPREQ)) ==
1100 				    LKC_EXREQ2) {
1101 					wakeup(lkp);
1102 				}
1103 				error = EBUSY;
1104 				/* count = ncount; NOT USED */
1105 				break;
1106 			}
1107 			/* retry */
1108 		} else if (count & LKC_UPREQ) {
1109 			/*
1110 			 * Clear the EXREQ we still own.  We cannot wakeup any
1111 			 * shared or exclusive waiters because there is an
1112 			 * uprequest pending (that we do not handle here).
1113 			 *
1114 			 * If there is an UPREQ it will issue a wakeup()
1115 			 * for any EXREQ wait looops, so we can clear EXREQ2
1116 			 * now.
1117 			 */
1118 			ncount = count & ~(LKC_EXREQ | LKC_EXREQ2);
1119 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1120 				error = EBUSY;
1121 				break;
1122 			}
1123 			/* retry */
1124 		} else if ((count & LKC_SHARED) && (count & LKC_SMASK)) {
1125 			/*
1126 			 * No UPREQ, lock not held exclusively, but the lock
1127 			 * is held shared.  Clear EXREQ, wakeup anyone trying
1128 			 * to get the EXREQ bit (they have to set it
1129 			 * themselves, EXREQ2 is an aggregation).
1130 			 *
1131 			 * We must also wakeup any shared locks blocked
1132 			 * by the EXREQ, so just issue the wakeup
1133 			 * unconditionally.  See lockmgr_shared() + 76 lines
1134 			 * or so.
1135 			 */
1136 			ncount = count & ~(LKC_EXREQ | LKC_EXREQ2);
1137 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1138 				wakeup(lkp);
1139 				error = EBUSY;
1140 				/* count = ncount; NOT USED */
1141 				break;
1142 			}
1143 			/* retry */
1144 		} else {
1145 			/*
1146 			 * No UPREQ, lock not held exclusively or shared.
1147 			 * Grant the EXREQ and wakeup anyone waiting on
1148 			 * EXREQ2.
1149 			 *
1150 			 * We must also issue a wakeup if SHARED is set,
1151 			 * even without an SCOUNT, due to pre-shared blocking
1152 			 * that can occur on EXREQ in lockmgr_shared().
1153 			 */
1154 			ncount = (count + 1) & ~(LKC_EXREQ | LKC_EXREQ2);
1155 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1156 				if (count & (LKC_EXREQ2 | LKC_SHARED))
1157 					wakeup(lkp);
1158 				/* count = ncount; NOT USED */
1159 				/* we are granting, error == 0 */
1160 				break;
1161 			}
1162 			/* retry */
1163 		}
1164 		/* retry */
1165 	}
1166 	return error;
1167 }
1168 
1169 /*
1170  * Undo an upgrade request.  Returns EBUSY if we were able to undo the
1171  * request, and 0 if the request was granted before we could undo it.
1172  * When 0 is returned, the lock state has not been modified.  The caller
1173  * is responsible for setting the lockholder to curthread.
1174  */
1175 static
1176 int
1177 undo_upreq(struct lock *lkp)
1178 {
1179 	uint64_t count;
1180 	uint64_t ncount;
1181 	int error;
1182 
1183 	count = lkp->lk_count;
1184 	error = 0;
1185 
1186 	for (;;) {
1187 		cpu_ccfence();
1188 
1189 		if ((count & LKC_UPREQ) == 0) {
1190 			/*
1191 			 * UPREQ was granted
1192 			 */
1193 			break;
1194 		}
1195 		if (count & LKC_XMASK) {
1196 			/*
1197 			 * Clear the UPREQ we still own.  Nobody to wakeup
1198 			 * here because there is an existing exclusive
1199 			 * holder.
1200 			 */
1201 			if (atomic_fcmpset_64(&lkp->lk_count, &count,
1202 					      count & ~LKC_UPREQ)) {
1203 				error = EBUSY;
1204 				/* count &= ~LKC_UPREQ; NOT USED */
1205 				break;
1206 			}
1207 		} else if (count & LKC_EXREQ) {
1208 			/*
1209 			 * Clear the UPREQ we still own.  Grant the exclusive
1210 			 * request and wake it up.
1211 			 */
1212 			ncount = (count + 1);
1213 			ncount &= ~(LKC_EXREQ | LKC_EXREQ2 | LKC_UPREQ);
1214 
1215 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1216 				wakeup(lkp);
1217 				error = EBUSY;
1218 				/* count = ncount; NOT USED */
1219 				break;
1220 			}
1221 		} else {
1222 			/*
1223 			 * Clear the UPREQ we still own.  Wakeup any shared
1224 			 * waiters.
1225 			 *
1226 			 * We must also issue a wakeup if SHARED was set
1227 			 * even if no shared waiters due to pre-shared blocking
1228 			 * that can occur on UPREQ.
1229 			 */
1230 			ncount = count & ~LKC_UPREQ;
1231 			if (count & LKC_SMASK)
1232 				ncount |= LKC_SHARED;
1233 
1234 			if (atomic_fcmpset_64(&lkp->lk_count, &count, ncount)) {
1235 				if ((count & LKC_SHARED) ||
1236 				    (ncount & LKC_SHARED)) {
1237 					wakeup(lkp);
1238 				}
1239 				error = EBUSY;
1240 				/* count = ncount; NOT USED */
1241 				break;
1242 			}
1243 		}
1244 		/* retry */
1245 	}
1246 	return error;
1247 }
1248 
1249 void
1250 lockmgr_kernproc(struct lock *lp)
1251 {
1252 	struct thread *td __debugvar = curthread;
1253 
1254 	if (lp->lk_lockholder != LK_KERNTHREAD) {
1255 		KASSERT(lp->lk_lockholder == td,
1256 		    ("lockmgr_kernproc: lock not owned by curthread %p: %p",
1257 		    td, lp->lk_lockholder));
1258 		lp->lk_lockholder = LK_KERNTHREAD;
1259 		COUNT(td, -1);
1260 	}
1261 }
1262 
1263 /*
1264  * Initialize a lock; required before use.
1265  */
1266 void
1267 lockinit(struct lock *lkp, const char *wmesg, int timo, int flags)
1268 {
1269 	lkp->lk_flags = (flags & LK_EXTFLG_MASK);
1270 	lkp->lk_count = 0;
1271 	lkp->lk_wmesg = wmesg;
1272 	lkp->lk_timo = timo;
1273 	lkp->lk_lockholder = NULL;
1274 }
1275 
1276 /*
1277  * Reinitialize a lock that is being reused for a different purpose, but
1278  * which may have pending (blocked) threads sitting on it.  The caller
1279  * must already hold the interlock.
1280  */
1281 void
1282 lockreinit(struct lock *lkp, const char *wmesg, int timo, int flags)
1283 {
1284 	lkp->lk_wmesg = wmesg;
1285 	lkp->lk_timo = timo;
1286 }
1287 
1288 /*
1289  * De-initialize a lock.  The structure must no longer be used by anyone.
1290  */
1291 void
1292 lockuninit(struct lock *lkp)
1293 {
1294 	uint64_t count __unused;
1295 
1296 	count = lkp->lk_count;
1297 	cpu_ccfence();
1298 	KKASSERT((count & (LKC_EXREQ | LKC_UPREQ)) == 0 &&
1299 		 ((count & LKC_SHARED) || (count & LKC_SMASK) == 0));
1300 }
1301 
1302 /*
1303  * Determine the status of a lock.
1304  */
1305 int
1306 lockstatus(struct lock *lkp, struct thread *td)
1307 {
1308 	int lock_type = 0;
1309 	uint64_t count;
1310 
1311 	count = lkp->lk_count;
1312 	cpu_ccfence();
1313 
1314 	if (count & (LKC_XMASK | LKC_SMASK | LKC_EXREQ | LKC_UPREQ)) {
1315 		if (count & LKC_XMASK) {
1316 			if (td == NULL || lkp->lk_lockholder == td)
1317 				lock_type = LK_EXCLUSIVE;
1318 			else
1319 				lock_type = LK_EXCLOTHER;
1320 		} else if ((count & LKC_SMASK) && (count & LKC_SHARED)) {
1321 			lock_type = LK_SHARED;
1322 		}
1323 	}
1324 	return (lock_type);
1325 }
1326 
1327 /*
1328  * Return non-zero if the caller owns the lock shared or exclusive.
1329  * We can only guess re: shared locks.
1330  */
1331 int
1332 lockowned(struct lock *lkp)
1333 {
1334 	thread_t td = curthread;
1335 	uint64_t count;
1336 
1337 	count = lkp->lk_count;
1338 	cpu_ccfence();
1339 
1340 	if (count & LKC_XMASK)
1341 		return(lkp->lk_lockholder == td);
1342 	else
1343 		return((count & LKC_SMASK) != 0);
1344 }
1345 
1346 #if 0
1347 /*
1348  * Determine the number of holders of a lock.
1349  *
1350  * REMOVED - Cannot be used due to our use of atomic_fetchadd_64()
1351  *	     for shared locks.  Caller can only test if the lock has
1352  *	     a count or not using lockinuse(lk) (sys/lock.h)
1353  */
1354 int
1355 lockcount(struct lock *lkp)
1356 {
1357 	panic("lockcount cannot be used");
1358 }
1359 
1360 int
1361 lockcountnb(struct lock *lkp)
1362 {
1363 	panic("lockcount cannot be used");
1364 }
1365 #endif
1366 
1367 /*
1368  * Print out information about state of a lock. Used by VOP_PRINT
1369  * routines to display status about contained locks.
1370  */
1371 void
1372 lockmgr_printinfo(struct lock *lkp)
1373 {
1374 	struct thread *td = lkp->lk_lockholder;
1375 	struct proc *p;
1376 	uint64_t count;
1377 
1378 	count = lkp->lk_count;
1379 	cpu_ccfence();
1380 
1381 	if (td && td != LK_KERNTHREAD)
1382 		p = td->td_proc;
1383 	else
1384 		p = NULL;
1385 
1386 	if (count & LKC_XMASK) {
1387 		kprintf(" lock type %s: EXCLUS (count %016jx) by td %p pid %d",
1388 		    lkp->lk_wmesg, (intmax_t)count, td,
1389 		    p ? p->p_pid : -99);
1390 	} else if ((count & LKC_SMASK) && (count & LKC_SHARED)) {
1391 		kprintf(" lock type %s: SHARED (count %016jx)",
1392 		    lkp->lk_wmesg, (intmax_t)count);
1393 	} else {
1394 		kprintf(" lock type %s: NOTHELD", lkp->lk_wmesg);
1395 	}
1396 	if ((count & (LKC_EXREQ | LKC_UPREQ)) ||
1397 	    ((count & LKC_XMASK) && (count & LKC_SMASK)))
1398 		kprintf(" with waiters\n");
1399 	else
1400 		kprintf("\n");
1401 }
1402 
1403 void
1404 lock_sysinit(struct lock_args *arg)
1405 {
1406 	lockinit(arg->la_lock, arg->la_desc, 0, arg->la_flags);
1407 }
1408 
1409 #ifdef DEBUG_CANCEL_LOCKS
1410 
1411 static
1412 int
1413 sysctl_cancel_lock(SYSCTL_HANDLER_ARGS)
1414 {
1415 	int error;
1416 
1417 	if (req->newptr) {
1418 		SYSCTL_XUNLOCK();
1419 		lockmgr(&cancel_lk, LK_EXCLUSIVE);
1420 		error = tsleep(&error, PCATCH, "canmas", hz * 5);
1421 		lockmgr(&cancel_lk, LK_CANCEL_BEG);
1422 		error = tsleep(&error, PCATCH, "canmas", hz * 5);
1423 		lockmgr(&cancel_lk, LK_RELEASE);
1424 		SYSCTL_XLOCK();
1425 		SYSCTL_OUT(req, &error, sizeof(error));
1426 	}
1427 	error = 0;
1428 
1429 	return error;
1430 }
1431 
1432 static
1433 int
1434 sysctl_cancel_test(SYSCTL_HANDLER_ARGS)
1435 {
1436 	int error;
1437 
1438 	if (req->newptr) {
1439 		error = lockmgr(&cancel_lk, LK_EXCLUSIVE|LK_CANCELABLE);
1440 		if (error == 0)
1441 			lockmgr(&cancel_lk, LK_RELEASE);
1442 		SYSCTL_OUT(req, &error, sizeof(error));
1443 		kprintf("test %d\n", error);
1444 	}
1445 
1446 	return 0;
1447 }
1448 
1449 #endif
1450