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