kern_lock.c revision 1.110.2.15 1 /* $NetBSD: kern_lock.c,v 1.110.2.15 2007/10/11 11:08:17 ad Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and by Andrew Doran.
10 *
11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Ross Harvey.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by the NetBSD
25 * Foundation, Inc. and its contributors.
26 * 4. Neither the name of The NetBSD Foundation nor the names of its
27 * contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42
43 /*
44 * Copyright (c) 1995
45 * The Regents of the University of California. All rights reserved.
46 *
47 * This code contains ideas from software contributed to Berkeley by
48 * Avadis Tevanian, Jr., Michael Wayne Young, and the Mach Operating
49 * System project at Carnegie-Mellon University.
50 *
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
53 * are met:
54 * 1. Redistributions of source code must retain the above copyright
55 * notice, this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright
57 * notice, this list of conditions and the following disclaimer in the
58 * documentation and/or other materials provided with the distribution.
59 * 3. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 *
75 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
76 */
77
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.110.2.15 2007/10/11 11:08:17 ad Exp $");
80
81 #include "opt_multiprocessor.h"
82
83 #include <sys/param.h>
84 #include <sys/proc.h>
85 #include <sys/lock.h>
86 #include <sys/systm.h>
87 #include <sys/lockdebug.h>
88 #include <sys/cpu.h>
89 #include <sys/syslog.h>
90
91 #include <machine/stdarg.h>
92
93 #include <dev/lockstat.h>
94
95 /*
96 * note that stdarg.h and the ansi style va_start macro is used for both
97 * ansi and traditional c compiles.
98 * XXX: this requires that stdarg.h define: va_alist and va_dcl
99 */
100 void lock_printf(const char *fmt, ...)
101 __attribute__((__format__(__printf__,1,2)));
102
103 static int acquire(volatile struct lock **, int *, int, int, int, uintptr_t);
104
105 int lock_debug_syslog = 0; /* defaults to printf, but can be patched */
106 int kernel_lock_id;
107 __cpu_simple_lock_t kernel_lock;
108
109 #if defined(LOCKDEBUG) || defined(DIAGNOSTIC) /* { */
110 #define COUNT(lkp, l, cpu_id, x) (l)->l_locks += (x)
111 #else
112 #define COUNT(lkp, p, cpu_id, x)
113 #endif /* LOCKDEBUG || DIAGNOSTIC */ /* } */
114
115 #define RETURN_ADDRESS ((uintptr_t)__builtin_return_address(0))
116
117 /*
118 * Acquire a resource.
119 */
120 static int
121 acquire(volatile struct lock **lkpp, int *s, int extflags,
122 int drain, int wanted, uintptr_t ra)
123 {
124 int error;
125 volatile struct lock *lkp = *lkpp;
126 LOCKSTAT_TIMER(slptime);
127 LOCKSTAT_FLAG(lsflag);
128
129 KASSERT(drain || (wanted & LK_WAIT_NONZERO) == 0);
130
131 LOCKSTAT_ENTER(lsflag);
132
133 for (error = 0; (lkp->lk_flags & wanted) != 0; ) {
134 if (drain)
135 lkp->lk_flags |= LK_WAITDRAIN;
136 else {
137 lkp->lk_waitcount++;
138 lkp->lk_flags |= LK_WAIT_NONZERO;
139 }
140 /* XXX Cast away volatile. */
141 LOCKSTAT_START_TIMER(lsflag, slptime);
142 error = mtsleep(drain ?
143 (volatile const void *)&lkp->lk_flags :
144 (volatile const void *)lkp, lkp->lk_prio,
145 lkp->lk_wmesg, lkp->lk_timo,
146 __UNVOLATILE(&lkp->lk_interlock));
147 LOCKSTAT_STOP_TIMER(lsflag, slptime);
148 LOCKSTAT_EVENT_RA(lsflag, (void *)(uintptr_t)lkp,
149 LB_LOCKMGR | LB_SLEEP1, 1, slptime, ra);
150 if (!drain) {
151 lkp->lk_waitcount--;
152 if (lkp->lk_waitcount == 0)
153 lkp->lk_flags &= ~LK_WAIT_NONZERO;
154 }
155 if (error)
156 break;
157 if (extflags & LK_SLEEPFAIL) {
158 error = ENOLCK;
159 break;
160 }
161 }
162
163 LOCKSTAT_EXIT(lsflag);
164
165 return error;
166 }
167
168 #define SETHOLDER(lkp, pid, lid, cpu_id) \
169 do { \
170 (lkp)->lk_lockholder = pid; \
171 (lkp)->lk_locklwp = lid; \
172 } while (/*CONSTCOND*/0)
173
174 #define WEHOLDIT(lkp, pid, lid, cpu_id) \
175 ((lkp)->lk_lockholder == (pid) && (lkp)->lk_locklwp == (lid))
176
177 #define WAKEUP_WAITER(lkp) \
178 do { \
179 if (((lkp)->lk_flags & LK_WAIT_NONZERO) != 0) { \
180 wakeup((lkp)); \
181 } \
182 } while (/*CONSTCOND*/0)
183
184 #if defined(LOCKDEBUG)
185 /*
186 * Lock debug printing routine; can be configured to print to console
187 * or log to syslog.
188 */
189 void
190 lock_printf(const char *fmt, ...)
191 {
192 char b[150];
193 va_list ap;
194
195 va_start(ap, fmt);
196 if (lock_debug_syslog)
197 vlog(LOG_DEBUG, fmt, ap);
198 else {
199 vsnprintf(b, sizeof(b), fmt, ap);
200 printf_nolog("%s", b);
201 }
202 va_end(ap);
203 }
204 #endif /* LOCKDEBUG */
205
206 static void
207 lockpanic(volatile struct lock *lkp, const char *fmt, ...)
208 {
209 char s[150], b[150];
210 static const char *locktype[] = {
211 "*0*", "shared", "exclusive", "upgrade", "exclupgrade",
212 "downgrade", "release", "drain", "exclother", "*9*",
213 "*10*", "*11*", "*12*", "*13*", "*14*", "*15*"
214 };
215 va_list ap;
216 va_start(ap, fmt);
217 vsnprintf(s, sizeof(s), fmt, ap);
218 va_end(ap);
219 bitmask_snprintf(lkp->lk_flags, __LK_FLAG_BITS, b, sizeof(b));
220 panic("%s ("
221 "type %s flags %s, sharecount %d, exclusivecount %d, "
222 "recurselevel %d, waitcount %d, wmesg %s"
223 ", lock_addr %p, unlock_addr %p"
224 ")\n",
225 s, locktype[lkp->lk_flags & LK_TYPE_MASK],
226 b, lkp->lk_sharecount, lkp->lk_exclusivecount,
227 lkp->lk_recurselevel, lkp->lk_waitcount, lkp->lk_wmesg,
228 (void *)lkp->lk_lock_addr, (void *)lkp->lk_unlock_addr
229 );
230 }
231
232 /*
233 * Initialize a lock; required before use.
234 */
235 void
236 lockinit(struct lock *lkp, pri_t prio, const char *wmesg, int timo, int flags)
237 {
238
239 memset(lkp, 0, sizeof(struct lock));
240 lkp->lk_flags = flags & LK_EXTFLG_MASK;
241 mutex_init(&lkp->lk_interlock, MUTEX_DEFAULT, IPL_NONE);
242 lkp->lk_lockholder = LK_NOPROC;
243 lkp->lk_prio = prio;
244 lkp->lk_timo = timo;
245 lkp->lk_wmesg = wmesg;
246 lkp->lk_lock_addr = 0;
247 lkp->lk_unlock_addr = 0;
248 }
249
250 void
251 lockdestroy(struct lock *lkp)
252 {
253
254 mutex_destroy(&lkp->lk_interlock);
255 }
256
257 /*
258 * Determine the status of a lock.
259 */
260 int
261 lockstatus(struct lock *lkp)
262 {
263 int lock_type = 0;
264 struct lwp *l = curlwp; /* XXX */
265 pid_t pid;
266 lwpid_t lid;
267 cpuid_t cpu_num;
268
269 if (l == NULL) {
270 cpu_num = cpu_number();
271 pid = LK_KERNPROC;
272 lid = 0;
273 } else {
274 cpu_num = LK_NOCPU;
275 pid = l->l_proc->p_pid;
276 lid = l->l_lid;
277 }
278
279 mutex_enter(&lkp->lk_interlock);
280 if (lkp->lk_exclusivecount != 0) {
281 if (WEHOLDIT(lkp, pid, lid, cpu_num))
282 lock_type = LK_EXCLUSIVE;
283 else
284 lock_type = LK_EXCLOTHER;
285 } else if (lkp->lk_sharecount != 0)
286 lock_type = LK_SHARED;
287 else if (lkp->lk_flags & (LK_WANT_EXCL | LK_WANT_UPGRADE))
288 lock_type = LK_EXCLOTHER;
289 mutex_exit(__UNVOLATILE(&lkp->lk_interlock));
290 return (lock_type);
291 }
292
293 /*
294 * XXX XXX kludge around another kludge..
295 *
296 * vfs_shutdown() may be called from interrupt context, either as a result
297 * of a panic, or from the debugger. It proceeds to call
298 * sys_sync(&proc0, ...), pretending its running on behalf of proc0
299 *
300 * We would like to make an attempt to sync the filesystems in this case, so
301 * if this happens, we treat attempts to acquire locks specially.
302 * All locks are acquired on behalf of proc0.
303 *
304 * If we've already paniced, we don't block waiting for locks, but
305 * just barge right ahead since we're already going down in flames.
306 */
307
308 /*
309 * Set, change, or release a lock.
310 *
311 * Shared requests increment the shared count. Exclusive requests set the
312 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already
313 * accepted shared locks and shared-to-exclusive upgrades to go away.
314 */
315 int
316 lockmgr(volatile struct lock *lkp, u_int flags, kmutex_t *interlkp)
317 {
318 int error;
319 pid_t pid;
320 lwpid_t lid;
321 int extflags;
322 cpuid_t cpu_num;
323 struct lwp *l = curlwp;
324 int lock_shutdown_noblock = 0;
325 kmutex_t *mutex;
326 int s = 0;
327
328 error = 0;
329 mutex = __UNVOLATILE(&lkp->lk_interlock);
330
331 /* LK_RETRY is for vn_lock, not for lockmgr. */
332 KASSERT((flags & LK_RETRY) == 0);
333 KASSERT((l->l_flag & LW_INTR) == 0 || panicstr != NULL);
334
335 mutex_enter(mutex);
336 if (flags & LK_INTERLOCK)
337 mutex_exit(__UNVOLATILE(interlkp));
338 extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
339
340 if (l == NULL) {
341 if (!doing_shutdown) {
342 panic("lockmgr: no context");
343 } else {
344 l = &lwp0;
345 if (panicstr && (!(flags & LK_NOWAIT))) {
346 flags |= LK_NOWAIT;
347 lock_shutdown_noblock = 1;
348 }
349 }
350 }
351 lid = l->l_lid;
352 pid = l->l_proc->p_pid;
353 cpu_num = cpu_number();
354
355 /*
356 * Once a lock has drained, the LK_DRAINING flag is set and an
357 * exclusive lock is returned. The only valid operation thereafter
358 * is a single release of that exclusive lock. This final release
359 * clears the LK_DRAINING flag and sets the LK_DRAINED flag. Any
360 * further requests of any sort will result in a panic. The bits
361 * selected for these two flags are chosen so that they will be set
362 * in memory that is freed (freed memory is filled with 0xdeadbeef).
363 * The final release is permitted to give a new lease on life to
364 * the lock by specifying LK_REENABLE.
365 */
366 if (lkp->lk_flags & (LK_DRAINING|LK_DRAINED)) {
367 #ifdef DIAGNOSTIC /* { */
368 if (lkp->lk_flags & LK_DRAINED)
369 lockpanic(lkp, "lockmgr: using decommissioned lock");
370 if ((flags & LK_TYPE_MASK) != LK_RELEASE ||
371 WEHOLDIT(lkp, pid, lid, cpu_num) == 0)
372 lockpanic(lkp, "lockmgr: non-release on draining lock: %d",
373 flags & LK_TYPE_MASK);
374 #endif /* DIAGNOSTIC */ /* } */
375 lkp->lk_flags &= ~LK_DRAINING;
376 if ((flags & LK_REENABLE) == 0)
377 lkp->lk_flags |= LK_DRAINED;
378 }
379
380 switch (flags & LK_TYPE_MASK) {
381
382 case LK_SHARED:
383 if (WEHOLDIT(lkp, pid, lid, cpu_num) == 0) {
384 /*
385 * If just polling, check to see if we will block.
386 */
387 if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
388 (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE))) {
389 error = EBUSY;
390 break;
391 }
392 /*
393 * Wait for exclusive locks and upgrades to clear.
394 */
395 error = acquire(&lkp, &s, extflags, 0,
396 LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE,
397 RETURN_ADDRESS);
398 if (error)
399 break;
400 lkp->lk_sharecount++;
401 lkp->lk_flags |= LK_SHARE_NONZERO;
402 COUNT(lkp, l, cpu_num, 1);
403 break;
404 }
405 /*
406 * We hold an exclusive lock, so downgrade it to shared.
407 * An alternative would be to fail with EDEADLK.
408 */
409 lkp->lk_sharecount++;
410 lkp->lk_flags |= LK_SHARE_NONZERO;
411 COUNT(lkp, l, cpu_num, 1);
412 /* fall into downgrade */
413
414 case LK_DOWNGRADE:
415 if (WEHOLDIT(lkp, pid, lid, cpu_num) == 0 ||
416 lkp->lk_exclusivecount == 0)
417 lockpanic(lkp, "lockmgr: not holding exclusive lock");
418 lkp->lk_sharecount += lkp->lk_exclusivecount;
419 lkp->lk_flags |= LK_SHARE_NONZERO;
420 lkp->lk_exclusivecount = 0;
421 lkp->lk_recurselevel = 0;
422 lkp->lk_flags &= ~LK_HAVE_EXCL;
423 SETHOLDER(lkp, LK_NOPROC, 0, LK_NOCPU);
424 #if defined(LOCKDEBUG)
425 lkp->lk_unlock_addr = RETURN_ADDRESS;
426 #endif
427 WAKEUP_WAITER(lkp);
428 break;
429
430 case LK_EXCLUPGRADE:
431 /*
432 * If another process is ahead of us to get an upgrade,
433 * then we want to fail rather than have an intervening
434 * exclusive access.
435 */
436 if (lkp->lk_flags & LK_WANT_UPGRADE) {
437 lkp->lk_sharecount--;
438 if (lkp->lk_sharecount == 0)
439 lkp->lk_flags &= ~LK_SHARE_NONZERO;
440 COUNT(lkp, l, cpu_num, -1);
441 error = EBUSY;
442 break;
443 }
444 /* fall into normal upgrade */
445
446 case LK_UPGRADE:
447 /*
448 * Upgrade a shared lock to an exclusive one. If another
449 * shared lock has already requested an upgrade to an
450 * exclusive lock, our shared lock is released and an
451 * exclusive lock is requested (which will be granted
452 * after the upgrade). If we return an error, the file
453 * will always be unlocked.
454 */
455 if (WEHOLDIT(lkp, pid, lid, cpu_num) || lkp->lk_sharecount <= 0)
456 lockpanic(lkp, "lockmgr: upgrade exclusive lock");
457 lkp->lk_sharecount--;
458 if (lkp->lk_sharecount == 0)
459 lkp->lk_flags &= ~LK_SHARE_NONZERO;
460 COUNT(lkp, l, cpu_num, -1);
461 /*
462 * If we are just polling, check to see if we will block.
463 */
464 if ((extflags & LK_NOWAIT) &&
465 ((lkp->lk_flags & LK_WANT_UPGRADE) ||
466 lkp->lk_sharecount > 1)) {
467 error = EBUSY;
468 break;
469 }
470 if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) {
471 /*
472 * We are first shared lock to request an upgrade, so
473 * request upgrade and wait for the shared count to
474 * drop to zero, then take exclusive lock.
475 */
476 lkp->lk_flags |= LK_WANT_UPGRADE;
477 error = acquire(&lkp, &s, extflags, 0, LK_SHARE_NONZERO,
478 RETURN_ADDRESS);
479 lkp->lk_flags &= ~LK_WANT_UPGRADE;
480 if (error) {
481 WAKEUP_WAITER(lkp);
482 break;
483 }
484 lkp->lk_flags |= LK_HAVE_EXCL;
485 SETHOLDER(lkp, pid, lid, cpu_num);
486 #if defined(LOCKDEBUG)
487 lkp->lk_lock_addr = RETURN_ADDRESS;
488 #endif
489 if (lkp->lk_exclusivecount != 0)
490 lockpanic(lkp, "lockmgr: non-zero exclusive count");
491 lkp->lk_exclusivecount = 1;
492 if (extflags & LK_SETRECURSE)
493 lkp->lk_recurselevel = 1;
494 COUNT(lkp, l, cpu_num, 1);
495 break;
496 }
497 /*
498 * Someone else has requested upgrade. Release our shared
499 * lock, awaken upgrade requestor if we are the last shared
500 * lock, then request an exclusive lock.
501 */
502 if (lkp->lk_sharecount == 0)
503 WAKEUP_WAITER(lkp);
504 /* fall into exclusive request */
505
506 case LK_EXCLUSIVE:
507 if (WEHOLDIT(lkp, pid, lid, cpu_num)) {
508 /*
509 * Recursive lock.
510 */
511 if ((extflags & LK_CANRECURSE) == 0 &&
512 lkp->lk_recurselevel == 0) {
513 if (extflags & LK_RECURSEFAIL) {
514 error = EDEADLK;
515 break;
516 } else
517 lockpanic(lkp, "lockmgr: locking against myself");
518 }
519 lkp->lk_exclusivecount++;
520 if (extflags & LK_SETRECURSE &&
521 lkp->lk_recurselevel == 0)
522 lkp->lk_recurselevel = lkp->lk_exclusivecount;
523 COUNT(lkp, l, cpu_num, 1);
524 break;
525 }
526 /*
527 * If we are just polling, check to see if we will sleep.
528 */
529 if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
530 (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
531 LK_SHARE_NONZERO))) {
532 error = EBUSY;
533 break;
534 }
535 /*
536 * Try to acquire the want_exclusive flag.
537 */
538 error = acquire(&lkp, &s, extflags, 0,
539 LK_HAVE_EXCL | LK_WANT_EXCL, RETURN_ADDRESS);
540 if (error)
541 break;
542 lkp->lk_flags |= LK_WANT_EXCL;
543 /*
544 * Wait for shared locks and upgrades to finish.
545 */
546 error = acquire(&lkp, &s, extflags, 0,
547 LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO,
548 RETURN_ADDRESS);
549 lkp->lk_flags &= ~LK_WANT_EXCL;
550 if (error) {
551 WAKEUP_WAITER(lkp);
552 break;
553 }
554 lkp->lk_flags |= LK_HAVE_EXCL;
555 SETHOLDER(lkp, pid, lid, cpu_num);
556 #if defined(LOCKDEBUG)
557 lkp->lk_lock_addr = RETURN_ADDRESS;
558 #endif
559 if (lkp->lk_exclusivecount != 0)
560 lockpanic(lkp, "lockmgr: non-zero exclusive count");
561 lkp->lk_exclusivecount = 1;
562 if (extflags & LK_SETRECURSE)
563 lkp->lk_recurselevel = 1;
564 COUNT(lkp, l, cpu_num, 1);
565 break;
566
567 case LK_RELEASE:
568 if (lkp->lk_exclusivecount != 0) {
569 if (WEHOLDIT(lkp, pid, lid, cpu_num) == 0) {
570 lockpanic(lkp, "lockmgr: pid %d.%d, not "
571 "exclusive lock holder %d.%d "
572 "unlocking", pid, lid,
573 lkp->lk_lockholder,
574 lkp->lk_locklwp);
575 }
576 if (lkp->lk_exclusivecount == lkp->lk_recurselevel)
577 lkp->lk_recurselevel = 0;
578 lkp->lk_exclusivecount--;
579 COUNT(lkp, l, cpu_num, -1);
580 if (lkp->lk_exclusivecount == 0) {
581 lkp->lk_flags &= ~LK_HAVE_EXCL;
582 SETHOLDER(lkp, LK_NOPROC, 0, LK_NOCPU);
583 #if defined(LOCKDEBUG)
584 lkp->lk_unlock_addr = RETURN_ADDRESS;
585 #endif
586 }
587 } else if (lkp->lk_sharecount != 0) {
588 lkp->lk_sharecount--;
589 if (lkp->lk_sharecount == 0)
590 lkp->lk_flags &= ~LK_SHARE_NONZERO;
591 COUNT(lkp, l, cpu_num, -1);
592 }
593 #ifdef DIAGNOSTIC
594 else
595 lockpanic(lkp, "lockmgr: release of unlocked lock!");
596 #endif
597 WAKEUP_WAITER(lkp);
598 break;
599
600 case LK_DRAIN:
601 /*
602 * Check that we do not already hold the lock, as it can
603 * never drain if we do. Unfortunately, we have no way to
604 * check for holding a shared lock, but at least we can
605 * check for an exclusive one.
606 */
607 if (WEHOLDIT(lkp, pid, lid, cpu_num))
608 lockpanic(lkp, "lockmgr: draining against myself");
609 /*
610 * If we are just polling, check to see if we will sleep.
611 */
612 if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
613 (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
614 LK_SHARE_NONZERO | LK_WAIT_NONZERO))) {
615 error = EBUSY;
616 break;
617 }
618 error = acquire(&lkp, &s, extflags, 1,
619 LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
620 LK_SHARE_NONZERO | LK_WAIT_NONZERO,
621 RETURN_ADDRESS);
622 if (error)
623 break;
624 lkp->lk_flags |= LK_HAVE_EXCL;
625 if ((extflags & LK_RESURRECT) == 0)
626 lkp->lk_flags |= LK_DRAINING;
627 SETHOLDER(lkp, pid, lid, cpu_num);
628 #if defined(LOCKDEBUG)
629 lkp->lk_lock_addr = RETURN_ADDRESS;
630 #endif
631 lkp->lk_exclusivecount = 1;
632 /* XXX unlikely that we'd want this */
633 if (extflags & LK_SETRECURSE)
634 lkp->lk_recurselevel = 1;
635 COUNT(lkp, l, cpu_num, 1);
636 break;
637
638 default:
639 mutex_exit(mutex);
640 lockpanic(lkp, "lockmgr: unknown locktype request %d",
641 flags & LK_TYPE_MASK);
642 /* NOTREACHED */
643 }
644 if ((lkp->lk_flags & LK_WAITDRAIN) != 0 &&
645 ((lkp->lk_flags &
646 (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
647 LK_SHARE_NONZERO | LK_WAIT_NONZERO)) == 0)) {
648 lkp->lk_flags &= ~LK_WAITDRAIN;
649 wakeup(&lkp->lk_flags);
650 }
651 /*
652 * Note that this panic will be a recursive panic, since
653 * we only set lock_shutdown_noblock above if panicstr != NULL.
654 */
655 if (error && lock_shutdown_noblock)
656 lockpanic(lkp, "lockmgr: deadlock (see previous panic)");
657
658 mutex_exit(mutex);
659 return (error);
660 }
661
662 /*
663 * Print out information about state of a lock. Used by VOP_PRINT
664 * routines to display ststus about contained locks.
665 */
666 void
667 lockmgr_printinfo(volatile struct lock *lkp)
668 {
669
670 if (lkp->lk_sharecount)
671 printf(" lock type %s: SHARED (count %d)", lkp->lk_wmesg,
672 lkp->lk_sharecount);
673 else if (lkp->lk_flags & LK_HAVE_EXCL) {
674 printf(" lock type %s: EXCL (count %d) by ",
675 lkp->lk_wmesg, lkp->lk_exclusivecount);
676 printf("pid %d.%d", lkp->lk_lockholder,
677 lkp->lk_locklwp);
678 } else
679 printf(" not locked");
680 if (lkp->lk_waitcount > 0)
681 printf(" with %d pending", lkp->lk_waitcount);
682 }
683
684 #if defined(LOCKDEBUG)
685 void
686 assert_sleepable(struct simplelock *interlock, const char *msg)
687 {
688
689 if (panicstr != NULL)
690 return;
691 LOCKDEBUG_BARRIER(&kernel_lock, 1);
692 if (CURCPU_IDLE_P()) {
693 panic("assert_sleepable: idle");
694 }
695 }
696 #endif
697
698 /*
699 * Functions for manipulating the kernel_lock. We put them here
700 * so that they show up in profiles.
701 */
702
703 #define _KERNEL_LOCK_ABORT(msg) \
704 LOCKDEBUG_ABORT(kernel_lock_id, &kernel_lock, &_kernel_lock_ops, \
705 __func__, msg)
706
707 #ifdef LOCKDEBUG
708 #define _KERNEL_LOCK_ASSERT(cond) \
709 do { \
710 if (!(cond)) \
711 _KERNEL_LOCK_ABORT("assertion failed: " #cond); \
712 } while (/* CONSTCOND */ 0)
713 #else
714 #define _KERNEL_LOCK_ASSERT(cond) /* nothing */
715 #endif
716
717 void _kernel_lock_dump(volatile void *);
718
719 lockops_t _kernel_lock_ops = {
720 "Kernel lock",
721 0,
722 _kernel_lock_dump
723 };
724
725 /*
726 * Initialize the kernel lock.
727 */
728 void
729 kernel_lock_init(void)
730 {
731
732 __cpu_simple_lock_init(&kernel_lock);
733 kernel_lock_id = LOCKDEBUG_ALLOC(&kernel_lock, &_kernel_lock_ops,
734 RETURN_ADDRESS);
735 }
736
737 /*
738 * Print debugging information about the kernel lock.
739 */
740 void
741 _kernel_lock_dump(volatile void *junk)
742 {
743 struct cpu_info *ci = curcpu();
744
745 (void)junk;
746
747 printf_nolog("curcpu holds : %18d wanted by: %#018lx\n",
748 ci->ci_biglock_count, (long)ci->ci_biglock_wanted);
749 }
750
751 /*
752 * Acquire 'nlocks' holds on the kernel lock. If 'l' is non-null, the
753 * acquisition is from process context.
754 */
755 void
756 _kernel_lock(int nlocks, struct lwp *l)
757 {
758 struct cpu_info *ci = curcpu();
759 LOCKSTAT_TIMER(spintime);
760 LOCKSTAT_FLAG(lsflag);
761 struct lwp *owant;
762 #ifdef LOCKDEBUG
763 u_int spins;
764 #endif
765 int s;
766
767 if (nlocks == 0)
768 return;
769 _KERNEL_LOCK_ASSERT(nlocks > 0);
770
771 l = curlwp;
772
773 if (ci->ci_biglock_count != 0) {
774 _KERNEL_LOCK_ASSERT(__SIMPLELOCK_LOCKED_P(&kernel_lock));
775 ci->ci_biglock_count += nlocks;
776 l->l_blcnt += nlocks;
777 return;
778 }
779
780 _KERNEL_LOCK_ASSERT(l->l_blcnt == 0);
781 LOCKDEBUG_WANTLOCK(kernel_lock_id, RETURN_ADDRESS, 0);
782
783 s = splvm();
784 if (__cpu_simple_lock_try(&kernel_lock)) {
785 ci->ci_biglock_count = nlocks;
786 l->l_blcnt = nlocks;
787 LOCKDEBUG_LOCKED(kernel_lock_id, RETURN_ADDRESS, 0);
788 splx(s);
789 return;
790 }
791
792 LOCKSTAT_ENTER(lsflag);
793 LOCKSTAT_START_TIMER(lsflag, spintime);
794
795 /*
796 * Before setting ci_biglock_wanted we must post a store
797 * fence (see kern_mutex.c). This is accomplished by the
798 * __cpu_simple_lock_try() above.
799 */
800 owant = ci->ci_biglock_wanted;
801 ci->ci_biglock_wanted = curlwp; /* XXXAD */
802
803 #ifdef LOCKDEBUG
804 spins = 0;
805 #endif
806
807 do {
808 splx(s);
809 while (kernel_lock == __SIMPLELOCK_LOCKED) {
810 #ifdef LOCKDEBUG
811 if (SPINLOCK_SPINOUT(spins))
812 _KERNEL_LOCK_ABORT("spinout");
813 #endif
814 SPINLOCK_BACKOFF_HOOK;
815 SPINLOCK_SPIN_HOOK;
816 }
817 (void)splvm();
818 } while (!__cpu_simple_lock_try(&kernel_lock));
819
820 ci->ci_biglock_wanted = owant;
821 ci->ci_biglock_count = nlocks;
822 l->l_blcnt = nlocks;
823 LOCKSTAT_STOP_TIMER(lsflag, spintime);
824 LOCKDEBUG_LOCKED(kernel_lock_id, RETURN_ADDRESS, 0);
825 splx(s);
826
827 /*
828 * Again, another store fence is required (see kern_mutex.c).
829 */
830 mb_write();
831 if (owant == NULL) {
832 LOCKSTAT_EVENT(lsflag, &kernel_lock, LB_KERNEL_LOCK | LB_SPIN,
833 1, spintime);
834 }
835 LOCKSTAT_EXIT(lsflag);
836 }
837
838 /*
839 * Release 'nlocks' holds on the kernel lock. If 'nlocks' is zero, release
840 * all holds. If 'l' is non-null, the release is from process context.
841 */
842 void
843 _kernel_unlock(int nlocks, struct lwp *l, int *countp)
844 {
845 struct cpu_info *ci = curcpu();
846 u_int olocks;
847 int s;
848
849 l = curlwp;
850
851 _KERNEL_LOCK_ASSERT(nlocks < 2);
852
853 olocks = l->l_blcnt;
854
855 if (olocks == 0) {
856 _KERNEL_LOCK_ASSERT(nlocks <= 0);
857 if (countp != NULL)
858 *countp = 0;
859 return;
860 }
861
862 _KERNEL_LOCK_ASSERT(__SIMPLELOCK_LOCKED_P(&kernel_lock));
863
864 if (nlocks == 0)
865 nlocks = olocks;
866 else if (nlocks == -1) {
867 nlocks = 1;
868 _KERNEL_LOCK_ASSERT(olocks == 1);
869 }
870
871 _KERNEL_LOCK_ASSERT(ci->ci_biglock_count >= l->l_blcnt);
872
873 l->l_blcnt -= nlocks;
874 if (ci->ci_biglock_count == nlocks) {
875 s = splvm();
876 LOCKDEBUG_UNLOCKED(kernel_lock_id, RETURN_ADDRESS, 0);
877 ci->ci_biglock_count = 0;
878 __cpu_simple_unlock(&kernel_lock);
879 splx(s);
880 } else
881 ci->ci_biglock_count -= nlocks;
882
883 if (countp != NULL)
884 *countp = olocks;
885 }
886
887 #if defined(DEBUG)
888 /*
889 * Assert that the kernel lock is held.
890 */
891 void
892 _kernel_lock_assert_locked(void)
893 {
894
895 if (!__SIMPLELOCK_LOCKED_P(&kernel_lock) ||
896 curcpu()->ci_biglock_count == 0)
897 _KERNEL_LOCK_ABORT("not locked");
898 }
899
900 void
901 _kernel_lock_assert_unlocked()
902 {
903
904 if (curcpu()->ci_biglock_count != 0)
905 _KERNEL_LOCK_ABORT("locked");
906 }
907 #endif
908