- Fix a couple of inverted panic messages for shared/exclusive mismatches
of a lock within a single thread. - Fix handling of interlocks in WITNESS by properly requiring the interlock to be held exactly once if it is specified.
This commit is contained in:
parent
03e1315345
commit
24150d37d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251326
@ -511,7 +511,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
|
|||||||
case LK_SHARED:
|
case LK_SHARED:
|
||||||
if (LK_CAN_WITNESS(flags))
|
if (LK_CAN_WITNESS(flags))
|
||||||
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER,
|
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER,
|
||||||
file, line, ilk);
|
file, line, flags & LK_INTERLOCK ? ilk : NULL);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
x = lk->lk_lock;
|
x = lk->lk_lock;
|
||||||
|
|
||||||
@ -723,7 +723,8 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
|
|||||||
case LK_EXCLUSIVE:
|
case LK_EXCLUSIVE:
|
||||||
if (LK_CAN_WITNESS(flags))
|
if (LK_CAN_WITNESS(flags))
|
||||||
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
|
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
|
||||||
LOP_EXCLUSIVE, file, line, ilk);
|
LOP_EXCLUSIVE, file, line, flags & LK_INTERLOCK ?
|
||||||
|
ilk : NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If curthread already holds the lock and this one is
|
* If curthread already holds the lock and this one is
|
||||||
@ -1072,7 +1073,8 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
|
|||||||
case LK_DRAIN:
|
case LK_DRAIN:
|
||||||
if (LK_CAN_WITNESS(flags))
|
if (LK_CAN_WITNESS(flags))
|
||||||
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
|
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
|
||||||
LOP_EXCLUSIVE, file, line, ilk);
|
LOP_EXCLUSIVE, file, line, flags & LK_INTERLOCK ?
|
||||||
|
ilk : NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trying to drain a lock we already own will result in a
|
* Trying to drain a lock we already own will result in a
|
||||||
|
@ -1053,7 +1053,7 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
{
|
{
|
||||||
struct lock_list_entry *lock_list, *lle;
|
struct lock_list_entry *lock_list, *lle;
|
||||||
struct lock_instance *lock1, *lock2, *plock;
|
struct lock_instance *lock1, *lock2, *plock;
|
||||||
struct lock_class *class;
|
struct lock_class *class, *iclass;
|
||||||
struct witness *w, *w1;
|
struct witness *w, *w1;
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -1119,7 +1119,7 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
fixup_filename(file), line);
|
fixup_filename(file), line);
|
||||||
printf("while exclusively locked from %s:%d\n",
|
printf("while exclusively locked from %s:%d\n",
|
||||||
fixup_filename(lock1->li_file), lock1->li_line);
|
fixup_filename(lock1->li_file), lock1->li_line);
|
||||||
kassert_panic("share->excl");
|
kassert_panic("excl->share");
|
||||||
}
|
}
|
||||||
if ((lock1->li_flags & LI_EXCLUSIVE) == 0 &&
|
if ((lock1->li_flags & LI_EXCLUSIVE) == 0 &&
|
||||||
(flags & LOP_EXCLUSIVE) != 0) {
|
(flags & LOP_EXCLUSIVE) != 0) {
|
||||||
@ -1128,11 +1128,27 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
fixup_filename(file), line);
|
fixup_filename(file), line);
|
||||||
printf("while share locked from %s:%d\n",
|
printf("while share locked from %s:%d\n",
|
||||||
fixup_filename(lock1->li_file), lock1->li_line);
|
fixup_filename(lock1->li_file), lock1->li_line);
|
||||||
kassert_panic("excl->share");
|
kassert_panic("share->excl");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Warn if the interlock is not locked exactly once. */
|
||||||
|
if (interlock != NULL) {
|
||||||
|
iclass = LOCK_CLASS(interlock);
|
||||||
|
lock1 = find_instance(lock_list, interlock);
|
||||||
|
if (lock1 == NULL)
|
||||||
|
kassert_panic("interlock (%s) %s not locked @ %s:%d",
|
||||||
|
iclass->lc_name, interlock->lo_name,
|
||||||
|
flags & LOP_EXCLUSIVE ? "exclusive" : "shared",
|
||||||
|
fixup_filename(file), line);
|
||||||
|
else if ((lock1->li_flags & LI_RECURSEMASK) != 0)
|
||||||
|
kassert_panic("interlock (%s) %s recursed @ %s:%d",
|
||||||
|
iclass->lc_name, interlock->lo_name,
|
||||||
|
flags & LOP_EXCLUSIVE ? "exclusive" : "shared",
|
||||||
|
fixup_filename(file), line);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the previously acquired lock, but ignore interlocks.
|
* Find the previously acquired lock, but ignore interlocks.
|
||||||
*/
|
*/
|
||||||
@ -1205,12 +1221,10 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
|||||||
lock1 = &lle->ll_children[i];
|
lock1 = &lle->ll_children[i];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore the interlock the first time we see it.
|
* Ignore the interlock.
|
||||||
*/
|
*/
|
||||||
if (interlock != NULL && interlock == lock1->li_lock) {
|
if (interlock == lock1->li_lock)
|
||||||
interlock = NULL;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this lock doesn't undergo witness checking,
|
* If this lock doesn't undergo witness checking,
|
||||||
|
Loading…
Reference in New Issue
Block a user