Deleted Added
full compact
kern_lock.c (164246) kern_lock.c (167012)
1/*-
2 * Copyright (c) 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Copyright (C) 1997
6 * John S. Dyson. All rights reserved.
7 *
8 * This code contains ideas from software contributed to Berkeley by

--- 27 unchanged lines hidden (view full) ---

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 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
41 */
42
43#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Copyright (C) 1997
6 * John S. Dyson. All rights reserved.
7 *
8 * This code contains ideas from software contributed to Berkeley by

--- 27 unchanged lines hidden (view full) ---

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 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
41 */
42
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: head/sys/kern/kern_lock.c 164246 2006-11-13 05:41:46Z kmacy $");
44__FBSDID("$FreeBSD: head/sys/kern/kern_lock.c 167012 2007-02-26 08:26:44Z kmacy $");
45
46#include "opt_ddb.h"
47#include "opt_global.h"
48
49#include <sys/param.h>
50#include <sys/kdb.h>
51#include <sys/kernel.h>
52#include <sys/ktr.h>

--- 26 unchanged lines hidden (view full) ---

79 * Locking primitives implementation.
80 * Locks provide shared/exclusive sychronization.
81 */
82
83#define COUNT(td, x) if ((td)) (td)->td_locks += (x)
84#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
85 LK_SHARE_NONZERO | LK_WAIT_NONZERO)
86
45
46#include "opt_ddb.h"
47#include "opt_global.h"
48
49#include <sys/param.h>
50#include <sys/kdb.h>
51#include <sys/kernel.h>
52#include <sys/ktr.h>

--- 26 unchanged lines hidden (view full) ---

79 * Locking primitives implementation.
80 * Locks provide shared/exclusive sychronization.
81 */
82
83#define COUNT(td, x) if ((td)) (td)->td_locks += (x)
84#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
85 LK_SHARE_NONZERO | LK_WAIT_NONZERO)
86
87static int acquire(struct lock **lkpp, int extflags, int wanted);
87static int acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *waittime);
88static int acquiredrain(struct lock *lkp, int extflags) ;
89
90static __inline void
91sharelock(struct thread *td, struct lock *lkp, int incr) {
92 lkp->lk_flags |= LK_SHARE_NONZERO;
93 lkp->lk_sharecount += incr;
94 COUNT(td, incr);
95}

--- 11 unchanged lines hidden (view full) ---

107 }
108 lkp->lk_sharecount = 0;
109 } else {
110 lkp->lk_sharecount -= decr;
111 }
112}
113
114static int
88static int acquiredrain(struct lock *lkp, int extflags) ;
89
90static __inline void
91sharelock(struct thread *td, struct lock *lkp, int incr) {
92 lkp->lk_flags |= LK_SHARE_NONZERO;
93 lkp->lk_sharecount += incr;
94 COUNT(td, incr);
95}

--- 11 unchanged lines hidden (view full) ---

107 }
108 lkp->lk_sharecount = 0;
109 } else {
110 lkp->lk_sharecount -= decr;
111 }
112}
113
114static int
115acquire(struct lock **lkpp, int extflags, int wanted)
115acquire(struct lock **lkpp, int extflags, int wanted, int *contested, uint64_t *waittime)
116{
117 struct lock *lkp = *lkpp;
118 int error;
119 CTR3(KTR_LOCK,
120 "acquire(): lkp == %p, extflags == 0x%x, wanted == 0x%x",
121 lkp, extflags, wanted);
122
123 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted))
124 return EBUSY;
125 error = 0;
116{
117 struct lock *lkp = *lkpp;
118 int error;
119 CTR3(KTR_LOCK,
120 "acquire(): lkp == %p, extflags == 0x%x, wanted == 0x%x",
121 lkp, extflags, wanted);
122
123 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted))
124 return EBUSY;
125 error = 0;
126 if ((lkp->lk_flags & wanted) != 0)
127 lock_profile_obtain_lock_failed(&lkp->lk_object, contested, waittime);
128
126 while ((lkp->lk_flags & wanted) != 0) {
127 CTR2(KTR_LOCK,
128 "acquire(): lkp == %p, lk_flags == 0x%x sleeping",
129 lkp, lkp->lk_flags);
130 lkp->lk_flags |= LK_WAIT_NONZERO;
131 lkp->lk_waitcount++;
132 error = msleep(lkp, lkp->lk_interlock, lkp->lk_prio,
133 lkp->lk_wmesg,

--- 29 unchanged lines hidden (view full) ---

163int
164_lockmgr(struct lock *lkp, int flags, struct mtx *interlkp,
165 struct thread *td, char *file, int line)
166
167{
168 int error;
169 struct thread *thr;
170 int extflags, lockflags;
129 while ((lkp->lk_flags & wanted) != 0) {
130 CTR2(KTR_LOCK,
131 "acquire(): lkp == %p, lk_flags == 0x%x sleeping",
132 lkp, lkp->lk_flags);
133 lkp->lk_flags |= LK_WAIT_NONZERO;
134 lkp->lk_waitcount++;
135 error = msleep(lkp, lkp->lk_interlock, lkp->lk_prio,
136 lkp->lk_wmesg,

--- 29 unchanged lines hidden (view full) ---

166int
167_lockmgr(struct lock *lkp, int flags, struct mtx *interlkp,
168 struct thread *td, char *file, int line)
169
170{
171 int error;
172 struct thread *thr;
173 int extflags, lockflags;
171 uint64_t waitstart;
172
174 int contested = 0;
175 uint64_t waitstart = 0;
176
173 error = 0;
174 if (td == NULL)
175 thr = LK_KERNPROC;
176 else
177 thr = td;
178
177 error = 0;
178 if (td == NULL)
179 thr = LK_KERNPROC;
180 else
181 thr = td;
182
179 lock_profile_waitstart(&waitstart);
180 if ((flags & LK_INTERNAL) == 0)
181 mtx_lock(lkp->lk_interlock);
182 CTR6(KTR_LOCK,
183 "lockmgr(): lkp == %p (lk_wmesg == \"%s\"), owner == %p, exclusivecount == %d, flags == 0x%x, "
184 "td == %p", lkp, lkp->lk_wmesg, lkp->lk_lockholder,
185 lkp->lk_exclusivecount, flags, td);
186#ifdef DEBUG_LOCKS
187 {

--- 35 unchanged lines hidden (view full) ---

223 * However, if TDP_DEADLKTREAT is set, we override exclusive
224 * lock requests or upgrade requests ( but not the exclusive
225 * lock itself ).
226 */
227 if (lkp->lk_lockholder != thr) {
228 lockflags = LK_HAVE_EXCL;
229 if (td != NULL && !(td->td_pflags & TDP_DEADLKTREAT))
230 lockflags |= LK_WANT_EXCL | LK_WANT_UPGRADE;
183 if ((flags & LK_INTERNAL) == 0)
184 mtx_lock(lkp->lk_interlock);
185 CTR6(KTR_LOCK,
186 "lockmgr(): lkp == %p (lk_wmesg == \"%s\"), owner == %p, exclusivecount == %d, flags == 0x%x, "
187 "td == %p", lkp, lkp->lk_wmesg, lkp->lk_lockholder,
188 lkp->lk_exclusivecount, flags, td);
189#ifdef DEBUG_LOCKS
190 {

--- 35 unchanged lines hidden (view full) ---

226 * However, if TDP_DEADLKTREAT is set, we override exclusive
227 * lock requests or upgrade requests ( but not the exclusive
228 * lock itself ).
229 */
230 if (lkp->lk_lockholder != thr) {
231 lockflags = LK_HAVE_EXCL;
232 if (td != NULL && !(td->td_pflags & TDP_DEADLKTREAT))
233 lockflags |= LK_WANT_EXCL | LK_WANT_UPGRADE;
231 error = acquire(&lkp, extflags, lockflags);
234 error = acquire(&lkp, extflags, lockflags, &contested, &waitstart);
232 if (error)
233 break;
234 sharelock(td, lkp, 1);
235 if (lkp->lk_sharecount == 1)
235 if (error)
236 break;
237 sharelock(td, lkp, 1);
238 if (lkp->lk_sharecount == 1)
236 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line);
239 lock_profile_obtain_lock_success(&lkp->lk_object, contested, waitstart, file, line);
237
238#if defined(DEBUG_LOCKS)
239 stack_save(&lkp->lk_stack);
240#endif
241 break;
242 }
243 /*
244 * We hold an exclusive lock, so downgrade it to shared.
245 * An alternative would be to fail with EDEADLK.
246 */
247 sharelock(td, lkp, 1);
248 if (lkp->lk_sharecount == 1)
240
241#if defined(DEBUG_LOCKS)
242 stack_save(&lkp->lk_stack);
243#endif
244 break;
245 }
246 /*
247 * We hold an exclusive lock, so downgrade it to shared.
248 * An alternative would be to fail with EDEADLK.
249 */
250 sharelock(td, lkp, 1);
251 if (lkp->lk_sharecount == 1)
249 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line);
252 lock_profile_obtain_lock_success(&lkp->lk_object, contested, waitstart, file, line);
250 /* FALLTHROUGH downgrade */
251
252 case LK_DOWNGRADE:
253 KASSERT(lkp->lk_lockholder == thr && lkp->lk_exclusivecount != 0,
254 ("lockmgr: not holding exclusive lock "
255 "(owner thread (%p) != thread (%p), exlcnt (%d) != 0",
256 lkp->lk_lockholder, thr, lkp->lk_exclusivecount));
257 sharelock(td, lkp, lkp->lk_exclusivecount);

--- 45 unchanged lines hidden (view full) ---

303 }
304 if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) {
305 /*
306 * We are first shared lock to request an upgrade, so
307 * request upgrade and wait for the shared count to
308 * drop to zero, then take exclusive lock.
309 */
310 lkp->lk_flags |= LK_WANT_UPGRADE;
253 /* FALLTHROUGH downgrade */
254
255 case LK_DOWNGRADE:
256 KASSERT(lkp->lk_lockholder == thr && lkp->lk_exclusivecount != 0,
257 ("lockmgr: not holding exclusive lock "
258 "(owner thread (%p) != thread (%p), exlcnt (%d) != 0",
259 lkp->lk_lockholder, thr, lkp->lk_exclusivecount));
260 sharelock(td, lkp, lkp->lk_exclusivecount);

--- 45 unchanged lines hidden (view full) ---

306 }
307 if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) {
308 /*
309 * We are first shared lock to request an upgrade, so
310 * request upgrade and wait for the shared count to
311 * drop to zero, then take exclusive lock.
312 */
313 lkp->lk_flags |= LK_WANT_UPGRADE;
311 error = acquire(&lkp, extflags, LK_SHARE_NONZERO);
314 error = acquire(&lkp, extflags, LK_SHARE_NONZERO, &contested, &waitstart);
312 lkp->lk_flags &= ~LK_WANT_UPGRADE;
313
314 if (error) {
315 if ((lkp->lk_flags & ( LK_WANT_EXCL | LK_WAIT_NONZERO)) == (LK_WANT_EXCL | LK_WAIT_NONZERO))
316 wakeup((void *)lkp);
317 break;
318 }
319 if (lkp->lk_exclusivecount != 0)
320 panic("lockmgr: non-zero exclusive count");
321 lkp->lk_flags |= LK_HAVE_EXCL;
322 lkp->lk_lockholder = thr;
323 lkp->lk_exclusivecount = 1;
324 COUNT(td, 1);
315 lkp->lk_flags &= ~LK_WANT_UPGRADE;
316
317 if (error) {
318 if ((lkp->lk_flags & ( LK_WANT_EXCL | LK_WAIT_NONZERO)) == (LK_WANT_EXCL | LK_WAIT_NONZERO))
319 wakeup((void *)lkp);
320 break;
321 }
322 if (lkp->lk_exclusivecount != 0)
323 panic("lockmgr: non-zero exclusive count");
324 lkp->lk_flags |= LK_HAVE_EXCL;
325 lkp->lk_lockholder = thr;
326 lkp->lk_exclusivecount = 1;
327 COUNT(td, 1);
325 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line);
328 lock_profile_obtain_lock_success(&lkp->lk_object, contested, waitstart, file, line);
326#if defined(DEBUG_LOCKS)
327 stack_save(&lkp->lk_stack);
328#endif
329 break;
330 }
331 /*
332 * Someone else has requested upgrade. Release our shared
333 * lock, awaken upgrade requestor if we are the last shared

--- 23 unchanged lines hidden (view full) ---

357 if ((extflags & LK_NOWAIT) &&
358 (lkp->lk_flags & (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO))) {
359 error = EBUSY;
360 break;
361 }
362 /*
363 * Try to acquire the want_exclusive flag.
364 */
329#if defined(DEBUG_LOCKS)
330 stack_save(&lkp->lk_stack);
331#endif
332 break;
333 }
334 /*
335 * Someone else has requested upgrade. Release our shared
336 * lock, awaken upgrade requestor if we are the last shared

--- 23 unchanged lines hidden (view full) ---

360 if ((extflags & LK_NOWAIT) &&
361 (lkp->lk_flags & (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO))) {
362 error = EBUSY;
363 break;
364 }
365 /*
366 * Try to acquire the want_exclusive flag.
367 */
365 error = acquire(&lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL));
368 error = acquire(&lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL), &contested, &waitstart);
366 if (error)
367 break;
368 lkp->lk_flags |= LK_WANT_EXCL;
369 /*
370 * Wait for shared locks and upgrades to finish.
371 */
369 if (error)
370 break;
371 lkp->lk_flags |= LK_WANT_EXCL;
372 /*
373 * Wait for shared locks and upgrades to finish.
374 */
372 error = acquire(&lkp, extflags, LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO);
375 error = acquire(&lkp, extflags, LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO, &contested, &waitstart);
373 lkp->lk_flags &= ~LK_WANT_EXCL;
374 if (error) {
375 if (lkp->lk_flags & LK_WAIT_NONZERO)
376 wakeup((void *)lkp);
377 break;
378 }
379 lkp->lk_flags |= LK_HAVE_EXCL;
380 lkp->lk_lockholder = thr;
381 if (lkp->lk_exclusivecount != 0)
382 panic("lockmgr: non-zero exclusive count");
383 lkp->lk_exclusivecount = 1;
384 COUNT(td, 1);
376 lkp->lk_flags &= ~LK_WANT_EXCL;
377 if (error) {
378 if (lkp->lk_flags & LK_WAIT_NONZERO)
379 wakeup((void *)lkp);
380 break;
381 }
382 lkp->lk_flags |= LK_HAVE_EXCL;
383 lkp->lk_lockholder = thr;
384 if (lkp->lk_exclusivecount != 0)
385 panic("lockmgr: non-zero exclusive count");
386 lkp->lk_exclusivecount = 1;
387 COUNT(td, 1);
385 lock_profile_obtain_lock_success(&lkp->lk_object, waitstart, file, line);
388 lock_profile_obtain_lock_success(&lkp->lk_object, contested, waitstart, file, line);
386#if defined(DEBUG_LOCKS)
387 stack_save(&lkp->lk_stack);
388#endif
389 break;
390
391 case LK_RELEASE:
392 if (lkp->lk_exclusivecount != 0) {
393 if (lkp->lk_lockholder != thr &&

--- 289 unchanged lines hidden ---
389#if defined(DEBUG_LOCKS)
390 stack_save(&lkp->lk_stack);
391#endif
392 break;
393
394 case LK_RELEASE:
395 if (lkp->lk_exclusivecount != 0) {
396 if (lkp->lk_lockholder != thr &&

--- 289 unchanged lines hidden ---