Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_witness.c
Show First 20 Lines • Show All 1,798 Lines • ▼ Show 20 Lines | witness_line(struct lock_object *lock) | ||||
w = lock->lo_witness; | w = lock->lo_witness; | ||||
return (w->w_line); | return (w->w_line); | ||||
} | } | ||||
static struct witness * | static struct witness * | ||||
enroll(const char *description, struct lock_class *lock_class) | enroll(const char *description, struct lock_class *lock_class) | ||||
{ | { | ||||
struct witness *w; | struct witness *w; | ||||
struct witness_list *typelist; | |||||
MPASS(description != NULL); | MPASS(description != NULL); | ||||
if (witness_watch == -1 || panicstr != NULL) | if (witness_watch == -1 || panicstr != NULL) | ||||
return (NULL); | return (NULL); | ||||
if ((lock_class->lc_flags & LC_SPINLOCK)) { | if ((lock_class->lc_flags & LC_SPINLOCK)) { | ||||
if (witness_skipspin) | if (witness_skipspin) | ||||
return (NULL); | return (NULL); | ||||
else | } else if ((lock_class->lc_flags & LC_SLEEPLOCK) == 0) { | ||||
typelist = &w_spin; | |||||
} else if ((lock_class->lc_flags & LC_SLEEPLOCK)) { | |||||
typelist = &w_sleep; | |||||
} else { | |||||
kassert_panic("lock class %s is not sleep or spin", | kassert_panic("lock class %s is not sleep or spin", | ||||
lock_class->lc_name); | lock_class->lc_name); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
mtx_lock_spin(&w_mtx); | mtx_lock_spin(&w_mtx); | ||||
w = witness_hash_get(description); | w = witness_hash_get(description); | ||||
if (w) | if (w) | ||||
Show All 27 Lines | kassert_panic( | ||||
description, lock_class->lc_name, | description, lock_class->lc_name, | ||||
w->w_class->lc_name); | w->w_class->lc_name); | ||||
return (w); | return (w); | ||||
} | } | ||||
static void | static void | ||||
depart(struct witness *w) | depart(struct witness *w) | ||||
{ | { | ||||
struct witness_list *list; | |||||
MPASS(w->w_refcount == 0); | MPASS(w->w_refcount == 0); | ||||
if (w->w_class->lc_flags & LC_SLEEPLOCK) { | if (w->w_class->lc_flags & LC_SLEEPLOCK) { | ||||
list = &w_sleep; | |||||
w_sleep_cnt--; | w_sleep_cnt--; | ||||
} else { | } else { | ||||
list = &w_spin; | |||||
w_spin_cnt--; | w_spin_cnt--; | ||||
} | } | ||||
/* | /* | ||||
* Set file to NULL as it may point into a loadable module. | * Set file to NULL as it may point into a loadable module. | ||||
*/ | */ | ||||
w->w_file = NULL; | w->w_file = NULL; | ||||
w->w_line = 0; | w->w_line = 0; | ||||
witness_increment_graph_generation(); | witness_increment_graph_generation(); | ||||
▲ Show 20 Lines • Show All 658 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
static int | static int | ||||
sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) | sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct witness_lock_order_data *data1, *data2, *tmp_data1, *tmp_data2; | struct witness_lock_order_data *data1, *data2, *tmp_data1, *tmp_data2; | ||||
struct witness *tmp_w1, *tmp_w2, *w1, *w2; | struct witness *tmp_w1, *tmp_w2, *w1, *w2; | ||||
struct sbuf *sb; | struct sbuf *sb; | ||||
u_int w_rmatrix1, w_rmatrix2; | |||||
int error, generation, i, j; | int error, generation, i, j; | ||||
tmp_data1 = NULL; | tmp_data1 = NULL; | ||||
tmp_data2 = NULL; | tmp_data2 = NULL; | ||||
tmp_w1 = NULL; | tmp_w1 = NULL; | ||||
tmp_w2 = NULL; | tmp_w2 = NULL; | ||||
if (witness_watch < 1) { | if (witness_watch < 1) { | ||||
error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning)); | error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning)); | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | for (j = 1; j < w_max_used_index; j++) { | ||||
data1 = witness_lock_order_get(w1, w2); | data1 = witness_lock_order_get(w1, w2); | ||||
data2 = witness_lock_order_get(w2, w1); | data2 = witness_lock_order_get(w2, w1); | ||||
/* | /* | ||||
* Copy information locally so we can release the | * Copy information locally so we can release the | ||||
* spin lock. | * spin lock. | ||||
*/ | */ | ||||
*tmp_w2 = *w2; | *tmp_w2 = *w2; | ||||
w_rmatrix1 = (unsigned int)w_rmatrix[i][j]; | |||||
w_rmatrix2 = (unsigned int)w_rmatrix[j][i]; | |||||
if (data1) { | if (data1) { | ||||
stack_zero(&tmp_data1->wlod_stack); | stack_zero(&tmp_data1->wlod_stack); | ||||
stack_copy(&data1->wlod_stack, | stack_copy(&data1->wlod_stack, | ||||
&tmp_data1->wlod_stack); | &tmp_data1->wlod_stack); | ||||
} | } | ||||
if (data2 && data2 != data1) { | if (data2 && data2 != data1) { | ||||
stack_zero(&tmp_data2->wlod_stack); | stack_zero(&tmp_data2->wlod_stack); | ||||
▲ Show 20 Lines • Show All 387 Lines • Show Last 20 Lines |