kern_lock.c revision 65932
1214571Sdim/*
2214571Sdim * Copyright (c) 1995
3214571Sdim *	The Regents of the University of California.  All rights reserved.
4214571Sdim *
5214571Sdim * Copyright (C) 1997
6214571Sdim *	John S. Dyson.  All rights reserved.
7214571Sdim *
8214571Sdim * This code contains ideas from software contributed to Berkeley by
9214571Sdim * Avadis Tevanian, Jr., Michael Wayne Young, and the Mach Operating
10214571Sdim * System project at Carnegie-Mellon University.
11214571Sdim *
12214571Sdim * Redistribution and use in source and binary forms, with or without
13214571Sdim * modification, are permitted provided that the following conditions
14214571Sdim * are met:
15214571Sdim * 1. Redistributions of source code must retain the above copyright
16214571Sdim *    notice, this list of conditions and the following disclaimer.
17214571Sdim * 2. Redistributions in binary form must reproduce the above copyright
18214571Sdim *    notice, this list of conditions and the following disclaimer in the
19214571Sdim *    documentation and/or other materials provided with the distribution.
20214571Sdim * 3. All advertising materials mentioning features or use of this software
21214571Sdim *    must display the following acknowledgement:
22214571Sdim *	This product includes software developed by the University of
23214571Sdim *	California, Berkeley and its contributors.
24214571Sdim * 4. Neither the name of the University nor the names of its contributors
25214571Sdim *    may be used to endorse or promote products derived from this software
26214571Sdim *    without specific prior written permission.
27214571Sdim *
28214571Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29214571Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30214571Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31214571Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32214571Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33214571Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34214571Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35214571Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36214571Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37214571Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38214571Sdim * SUCH DAMAGE.
39214571Sdim *
40214571Sdim *	@(#)kern_lock.c	8.18 (Berkeley) 5/21/95
41214571Sdim * $FreeBSD: head/sys/kern/kern_lock.c 65932 2000-09-16 18:55:05Z phk $
42214571Sdim */
43214571Sdim
44214571Sdim#include <sys/param.h>
45214571Sdim#include <sys/proc.h>
46214571Sdim#include <sys/lock.h>
47214571Sdim#include <sys/systm.h>
48214571Sdim
49214571Sdim/*
50214571Sdim * Locking primitives implementation.
51214571Sdim * Locks provide shared/exclusive sychronization.
52214571Sdim */
53214571Sdim
54214571Sdim#ifdef SIMPLELOCK_DEBUG
55214571Sdim#define COUNT(p, x) if (p) (p)->p_locks += (x)
56214571Sdim#else
57214571Sdim#define COUNT(p, x)
58214571Sdim#endif
59214571Sdim
60214571Sdim#define LOCK_WAIT_TIME 100
61214571Sdim#define LOCK_SAMPLE_WAIT 7
62214571Sdim
63214571Sdim#if defined(DIAGNOSTIC)
64214571Sdim#define LOCK_INLINE
65214571Sdim#else
66214571Sdim#define LOCK_INLINE __inline
67214571Sdim#endif
68214571Sdim
69214571Sdim#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
70214571Sdim	LK_SHARE_NONZERO | LK_WAIT_NONZERO)
71214571Sdim
72214571Sdimstatic int acquire(struct lock *lkp, int extflags, int wanted);
73214571Sdimstatic int apause(struct lock *lkp, int flags);
74static int acquiredrain(struct lock *lkp, int extflags) ;
75
76static LOCK_INLINE void
77sharelock(struct lock *lkp, int incr) {
78	lkp->lk_flags |= LK_SHARE_NONZERO;
79	lkp->lk_sharecount += incr;
80}
81
82static LOCK_INLINE void
83shareunlock(struct lock *lkp, int decr) {
84
85	KASSERT(lkp->lk_sharecount >= decr, ("shareunlock: count < decr"));
86
87	if (lkp->lk_sharecount == decr) {
88		lkp->lk_flags &= ~LK_SHARE_NONZERO;
89		if (lkp->lk_flags & (LK_WANT_UPGRADE | LK_WANT_EXCL)) {
90			wakeup(lkp);
91		}
92		lkp->lk_sharecount = 0;
93	} else {
94		lkp->lk_sharecount -= decr;
95	}
96}
97
98/*
99 * This is the waitloop optimization, and note for this to work
100 * simple_lock and simple_unlock should be subroutines to avoid
101 * optimization troubles.
102 */
103static int
104apause(struct lock *lkp, int flags)
105{
106#ifdef SMP
107	int i, lock_wait;
108#endif
109
110	if ((lkp->lk_flags & flags) == 0)
111		return 0;
112#ifdef SMP
113	for (lock_wait = LOCK_WAIT_TIME; lock_wait > 0; lock_wait--) {
114		simple_unlock(&lkp->lk_interlock);
115		for (i = LOCK_SAMPLE_WAIT; i > 0; i--)
116			if ((lkp->lk_flags & flags) == 0)
117				break;
118		simple_lock(&lkp->lk_interlock);
119		if ((lkp->lk_flags & flags) == 0)
120			return 0;
121	}
122#endif
123	return 1;
124}
125
126static int
127acquire(struct lock *lkp, int extflags, int wanted) {
128	int s, error;
129
130	if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted)) {
131		return EBUSY;
132	}
133
134	if (((lkp->lk_flags | extflags) & LK_NOPAUSE) == 0) {
135		error = apause(lkp, wanted);
136		if (error == 0)
137			return 0;
138	}
139
140	s = splhigh();
141	while ((lkp->lk_flags & wanted) != 0) {
142		lkp->lk_flags |= LK_WAIT_NONZERO;
143		lkp->lk_waitcount++;
144		simple_unlock(&lkp->lk_interlock);
145		error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo);
146		simple_lock(&lkp->lk_interlock);
147		if (lkp->lk_waitcount == 1) {
148			lkp->lk_flags &= ~LK_WAIT_NONZERO;
149			lkp->lk_waitcount = 0;
150		} else {
151			lkp->lk_waitcount--;
152		}
153		if (error) {
154			splx(s);
155			return error;
156		}
157		if (extflags & LK_SLEEPFAIL) {
158			splx(s);
159			return ENOLCK;
160		}
161	}
162	splx(s);
163	return 0;
164}
165
166/*
167 * Set, change, or release a lock.
168 *
169 * Shared requests increment the shared count. Exclusive requests set the
170 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already
171 * accepted shared locks and shared-to-exclusive upgrades to go away.
172 */
173int
174#ifndef	DEBUG_LOCKS
175lockmgr(lkp, flags, interlkp, p)
176#else
177debuglockmgr(lkp, flags, interlkp, p, name, file, line)
178#endif
179	struct lock *lkp;
180	u_int flags;
181	struct simplelock *interlkp;
182	struct proc *p;
183#ifdef	DEBUG_LOCKS
184	const char *name;	/* Name of lock function */
185	const char *file;	/* Name of file call is from */
186	int line;		/* Line number in file */
187#endif
188{
189	int error;
190	pid_t pid;
191	int extflags;
192
193	error = 0;
194	if (p == NULL)
195		pid = LK_KERNPROC;
196	else
197		pid = p->p_pid;
198
199	simple_lock(&lkp->lk_interlock);
200	if (flags & LK_INTERLOCK)
201		simple_unlock(interlkp);
202
203	extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
204
205	switch (flags & LK_TYPE_MASK) {
206
207	case LK_SHARED:
208		/*
209		 * If we are not the exclusive lock holder, we have to block
210		 * while there is an exclusive lock holder or while an
211		 * exclusive lock request or upgrade request is in progress.
212		 *
213		 * However, if P_DEADLKTREAT is set, we override exclusive
214		 * lock requests or upgrade requests ( but not the exclusive
215		 * lock itself ).
216		 */
217		if (lkp->lk_lockholder != pid) {
218			if (p && (p->p_flag & P_DEADLKTREAT)) {
219				error = acquire(
220					    lkp,
221					    extflags,
222					    LK_HAVE_EXCL
223					);
224			} else {
225				error = acquire(
226					    lkp,
227					    extflags,
228					    LK_HAVE_EXCL | LK_WANT_EXCL |
229					     LK_WANT_UPGRADE
230					);
231			}
232			if (error)
233				break;
234			sharelock(lkp, 1);
235			COUNT(p, 1);
236			break;
237		}
238		/*
239		 * We hold an exclusive lock, so downgrade it to shared.
240		 * An alternative would be to fail with EDEADLK.
241		 */
242		sharelock(lkp, 1);
243		COUNT(p, 1);
244		/* fall into downgrade */
245
246	case LK_DOWNGRADE:
247		if (lkp->lk_lockholder != pid || lkp->lk_exclusivecount == 0)
248			panic("lockmgr: not holding exclusive lock");
249		sharelock(lkp, lkp->lk_exclusivecount);
250		lkp->lk_exclusivecount = 0;
251		lkp->lk_flags &= ~LK_HAVE_EXCL;
252		lkp->lk_lockholder = LK_NOPROC;
253		if (lkp->lk_waitcount)
254			wakeup((void *)lkp);
255		break;
256
257	case LK_EXCLUPGRADE:
258		/*
259		 * If another process is ahead of us to get an upgrade,
260		 * then we want to fail rather than have an intervening
261		 * exclusive access.
262		 */
263		if (lkp->lk_flags & LK_WANT_UPGRADE) {
264			shareunlock(lkp, 1);
265			COUNT(p, -1);
266			error = EBUSY;
267			break;
268		}
269		/* fall into normal upgrade */
270
271	case LK_UPGRADE:
272		/*
273		 * Upgrade a shared lock to an exclusive one. If another
274		 * shared lock has already requested an upgrade to an
275		 * exclusive lock, our shared lock is released and an
276		 * exclusive lock is requested (which will be granted
277		 * after the upgrade). If we return an error, the file
278		 * will always be unlocked.
279		 */
280		if ((lkp->lk_lockholder == pid) || (lkp->lk_sharecount <= 0))
281			panic("lockmgr: upgrade exclusive lock");
282		shareunlock(lkp, 1);
283		COUNT(p, -1);
284		/*
285		 * If we are just polling, check to see if we will block.
286		 */
287		if ((extflags & LK_NOWAIT) &&
288		    ((lkp->lk_flags & LK_WANT_UPGRADE) ||
289		     lkp->lk_sharecount > 1)) {
290			error = EBUSY;
291			break;
292		}
293		if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) {
294			/*
295			 * We are first shared lock to request an upgrade, so
296			 * request upgrade and wait for the shared count to
297			 * drop to zero, then take exclusive lock.
298			 */
299			lkp->lk_flags |= LK_WANT_UPGRADE;
300			error = acquire(lkp, extflags, LK_SHARE_NONZERO);
301			lkp->lk_flags &= ~LK_WANT_UPGRADE;
302
303			if (error)
304				break;
305			lkp->lk_flags |= LK_HAVE_EXCL;
306			lkp->lk_lockholder = pid;
307			if (lkp->lk_exclusivecount != 0)
308				panic("lockmgr: non-zero exclusive count");
309			lkp->lk_exclusivecount = 1;
310#if defined(DEBUG_LOCKS)
311			lkp->lk_filename = file;
312			lkp->lk_lineno = line;
313			lkp->lk_lockername = name;
314#endif
315			COUNT(p, 1);
316			break;
317		}
318		/*
319		 * Someone else has requested upgrade. Release our shared
320		 * lock, awaken upgrade requestor if we are the last shared
321		 * lock, then request an exclusive lock.
322		 */
323		if ( (lkp->lk_flags & (LK_SHARE_NONZERO|LK_WAIT_NONZERO)) ==
324			LK_WAIT_NONZERO)
325			wakeup((void *)lkp);
326		/* fall into exclusive request */
327
328	case LK_EXCLUSIVE:
329		if (lkp->lk_lockholder == pid && pid != LK_KERNPROC) {
330			/*
331			 *	Recursive lock.
332			 */
333			if ((extflags & (LK_NOWAIT | LK_CANRECURSE)) == 0)
334				panic("lockmgr: locking against myself");
335			if ((extflags & LK_CANRECURSE) != 0) {
336				lkp->lk_exclusivecount++;
337				COUNT(p, 1);
338				break;
339			}
340		}
341		/*
342		 * If we are just polling, check to see if we will sleep.
343		 */
344		if ((extflags & LK_NOWAIT) &&
345		    (lkp->lk_flags & (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO))) {
346			error = EBUSY;
347			break;
348		}
349		/*
350		 * Try to acquire the want_exclusive flag.
351		 */
352		error = acquire(lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL));
353		if (error)
354			break;
355		lkp->lk_flags |= LK_WANT_EXCL;
356		/*
357		 * Wait for shared locks and upgrades to finish.
358		 */
359		error = acquire(lkp, extflags, LK_WANT_UPGRADE | LK_SHARE_NONZERO);
360		lkp->lk_flags &= ~LK_WANT_EXCL;
361		if (error)
362			break;
363		lkp->lk_flags |= LK_HAVE_EXCL;
364		lkp->lk_lockholder = pid;
365		if (lkp->lk_exclusivecount != 0)
366			panic("lockmgr: non-zero exclusive count");
367		lkp->lk_exclusivecount = 1;
368#if defined(DEBUG_LOCKS)
369			lkp->lk_filename = file;
370			lkp->lk_lineno = line;
371			lkp->lk_lockername = name;
372#endif
373		COUNT(p, 1);
374		break;
375
376	case LK_RELEASE:
377		if (lkp->lk_exclusivecount != 0) {
378			if (lkp->lk_lockholder != pid &&
379			    lkp->lk_lockholder != LK_KERNPROC) {
380				panic("lockmgr: pid %d, not %s %d unlocking",
381				    pid, "exclusive lock holder",
382				    lkp->lk_lockholder);
383			}
384			if (lkp->lk_lockholder != LK_KERNPROC) {
385				COUNT(p, -1);
386			}
387			if (lkp->lk_exclusivecount == 1) {
388				lkp->lk_flags &= ~LK_HAVE_EXCL;
389				lkp->lk_lockholder = LK_NOPROC;
390				lkp->lk_exclusivecount = 0;
391			} else {
392				lkp->lk_exclusivecount--;
393			}
394		} else if (lkp->lk_flags & LK_SHARE_NONZERO) {
395			shareunlock(lkp, 1);
396			COUNT(p, -1);
397		}
398		if (lkp->lk_flags & LK_WAIT_NONZERO)
399			wakeup((void *)lkp);
400		break;
401
402	case LK_DRAIN:
403		/*
404		 * Check that we do not already hold the lock, as it can
405		 * never drain if we do. Unfortunately, we have no way to
406		 * check for holding a shared lock, but at least we can
407		 * check for an exclusive one.
408		 */
409		if (lkp->lk_lockholder == pid)
410			panic("lockmgr: draining against myself");
411
412		error = acquiredrain(lkp, extflags);
413		if (error)
414			break;
415		lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL;
416		lkp->lk_lockholder = pid;
417		lkp->lk_exclusivecount = 1;
418#if defined(DEBUG_LOCKS)
419			lkp->lk_filename = file;
420			lkp->lk_lineno = line;
421			lkp->lk_lockername = name;
422#endif
423		COUNT(p, 1);
424		break;
425
426	default:
427		simple_unlock(&lkp->lk_interlock);
428		panic("lockmgr: unknown locktype request %d",
429		    flags & LK_TYPE_MASK);
430		/* NOTREACHED */
431	}
432	if ((lkp->lk_flags & LK_WAITDRAIN) &&
433	    (lkp->lk_flags & (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
434		LK_SHARE_NONZERO | LK_WAIT_NONZERO)) == 0) {
435		lkp->lk_flags &= ~LK_WAITDRAIN;
436		wakeup((void *)&lkp->lk_flags);
437	}
438	simple_unlock(&lkp->lk_interlock);
439	return (error);
440}
441
442static int
443acquiredrain(struct lock *lkp, int extflags) {
444	int error;
445
446	if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) {
447		return EBUSY;
448	}
449
450	error = apause(lkp, LK_ALL);
451	if (error == 0)
452		return 0;
453
454	while (lkp->lk_flags & LK_ALL) {
455		lkp->lk_flags |= LK_WAITDRAIN;
456		simple_unlock(&lkp->lk_interlock);
457		error = tsleep(&lkp->lk_flags, lkp->lk_prio,
458			lkp->lk_wmesg, lkp->lk_timo);
459		simple_lock(&lkp->lk_interlock);
460		if (error)
461			return error;
462		if (extflags & LK_SLEEPFAIL) {
463			return ENOLCK;
464		}
465	}
466	return 0;
467}
468
469/*
470 * Initialize a lock; required before use.
471 */
472void
473lockinit(lkp, prio, wmesg, timo, flags)
474	struct lock *lkp;
475	int prio;
476	char *wmesg;
477	int timo;
478	int flags;
479{
480
481	simple_lock_init(&lkp->lk_interlock);
482	lkp->lk_flags = (flags & LK_EXTFLG_MASK);
483	lkp->lk_sharecount = 0;
484	lkp->lk_waitcount = 0;
485	lkp->lk_exclusivecount = 0;
486	lkp->lk_prio = prio;
487	lkp->lk_wmesg = wmesg;
488	lkp->lk_timo = timo;
489	lkp->lk_lockholder = LK_NOPROC;
490}
491
492/*
493 * Determine the status of a lock.
494 */
495int
496lockstatus(lkp, p)
497	struct lock *lkp;
498	struct proc *p;
499{
500	int lock_type = 0;
501
502	simple_lock(&lkp->lk_interlock);
503	if (lkp->lk_exclusivecount != 0) {
504		if (p == NULL || lkp->lk_lockholder == p->p_pid)
505			lock_type = LK_EXCLUSIVE;
506		else
507			lock_type = LK_EXCLOTHER;
508	} else if (lkp->lk_sharecount != 0)
509		lock_type = LK_SHARED;
510	simple_unlock(&lkp->lk_interlock);
511	return (lock_type);
512}
513
514/*
515 * Determine the number of holders of a lock.
516 */
517int
518lockcount(lkp)
519	struct lock *lkp;
520{
521	int count;
522
523	simple_lock(&lkp->lk_interlock);
524	count = lkp->lk_exclusivecount + lkp->lk_sharecount;
525	simple_unlock(&lkp->lk_interlock);
526	return (count);
527}
528
529/*
530 * Print out information about state of a lock. Used by VOP_PRINT
531 * routines to display status about contained locks.
532 */
533void
534lockmgr_printinfo(lkp)
535	struct lock *lkp;
536{
537
538	if (lkp->lk_sharecount)
539		printf(" lock type %s: SHARED (count %d)", lkp->lk_wmesg,
540		    lkp->lk_sharecount);
541	else if (lkp->lk_flags & LK_HAVE_EXCL)
542		printf(" lock type %s: EXCL (count %d) by pid %d",
543		    lkp->lk_wmesg, lkp->lk_exclusivecount, lkp->lk_lockholder);
544	if (lkp->lk_waitcount > 0)
545		printf(" with %d pending", lkp->lk_waitcount);
546}
547
548#if defined(SIMPLELOCK_DEBUG) && (NCPUS == 1 || defined(COMPILING_LINT))
549#include <sys/kernel.h>
550#include <sys/sysctl.h>
551
552static int lockpausetime = 0;
553SYSCTL_INT(_debug, OID_AUTO, lockpausetime, CTLFLAG_RW, &lockpausetime, 0, "");
554
555static int simplelockrecurse;
556
557/*
558 * Simple lock functions so that the debugger can see from whence
559 * they are being called.
560 */
561void
562simple_lock_init(alp)
563	struct simplelock *alp;
564{
565
566	alp->lock_data = 0;
567}
568
569void
570_simple_lock(alp, id, l)
571	struct simplelock *alp;
572	const char *id;
573	int l;
574{
575
576	if (simplelockrecurse)
577		return;
578	if (alp->lock_data == 1) {
579		if (lockpausetime == -1)
580			panic("%s:%d: simple_lock: lock held", id, l);
581		printf("%s:%d: simple_lock: lock held\n", id, l);
582		if (lockpausetime == 1) {
583			Debugger("simple_lock");
584			/*BACKTRACE(curproc); */
585		} else if (lockpausetime > 1) {
586			printf("%s:%d: simple_lock: lock held...", id, l);
587			tsleep(&lockpausetime, PCATCH | PPAUSE, "slock",
588			    lockpausetime * hz);
589			printf(" continuing\n");
590		}
591	}
592	alp->lock_data = 1;
593	if (curproc)
594		curproc->p_simple_locks++;
595}
596
597int
598_simple_lock_try(alp, id, l)
599	struct simplelock *alp;
600	const char *id;
601	int l;
602{
603
604	if (alp->lock_data)
605		return (0);
606	if (simplelockrecurse)
607		return (1);
608	alp->lock_data = 1;
609	if (curproc)
610		curproc->p_simple_locks++;
611	return (1);
612}
613
614void
615_simple_unlock(alp, id, l)
616	struct simplelock *alp;
617	const char *id;
618	int l;
619{
620
621	if (simplelockrecurse)
622		return;
623	if (alp->lock_data == 0) {
624		if (lockpausetime == -1)
625			panic("%s:%d: simple_unlock: lock not held", id, l);
626		printf("%s:%d: simple_unlock: lock not held\n", id, l);
627		if (lockpausetime == 1) {
628			Debugger("simple_unlock");
629			/* BACKTRACE(curproc); */
630		} else if (lockpausetime > 1) {
631			printf("%s:%d: simple_unlock: lock not held...", id, l);
632			tsleep(&lockpausetime, PCATCH | PPAUSE, "sunlock",
633			    lockpausetime * hz);
634			printf(" continuing\n");
635		}
636	}
637	alp->lock_data = 0;
638	if (curproc)
639		curproc->p_simple_locks--;
640}
641#elif defined(SIMPLELOCK_DEBUG)
642#error "SIMPLELOCK_DEBUG is not compatible with SMP!"
643#endif /* SIMPLELOCK_DEBUG && NCPUS == 1 */
644