ddb(4): Add 'show badstacks' command to show witness badstacks
Add a DDB command that mirrors sysctl debug.witness.badstacks. Reapply r323935 after fixing trivial deficiency. I forgot to compile with WITNESS enabled. Thanks emaste@ for fixing the build while I was asleep. Reported by: rstone Reviewed by: rstone (previous version) Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D12468
This commit is contained in:
parent
59059cda6a
commit
f41b85a63c
@ -2539,31 +2539,18 @@ DB_SHOW_COMMAND(witness, db_witness_display)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static void
|
||||||
sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS)
|
sbuf_print_witness_badstacks(struct sbuf *sb, size_t *oldidx)
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
u_int w_rmatrix1, w_rmatrix2;
|
u_int w_rmatrix1, w_rmatrix2;
|
||||||
int error, generation, i, j;
|
int 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) {
|
|
||||||
error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning));
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
if (witness_cold) {
|
|
||||||
error = SYSCTL_OUT(req, w_stillcold, sizeof(w_stillcold));
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
error = 0;
|
|
||||||
sb = sbuf_new(NULL, NULL, badstack_sbuf_size, SBUF_AUTOEXTEND);
|
|
||||||
if (sb == NULL)
|
|
||||||
return (ENOMEM);
|
|
||||||
|
|
||||||
/* Allocate and init temporary storage space. */
|
/* Allocate and init temporary storage space. */
|
||||||
tmp_w1 = malloc(sizeof(struct witness), M_TEMP, M_WAITOK | M_ZERO);
|
tmp_w1 = malloc(sizeof(struct witness), M_TEMP, M_WAITOK | M_ZERO);
|
||||||
@ -2587,7 +2574,7 @@ restart:
|
|||||||
mtx_unlock_spin(&w_mtx);
|
mtx_unlock_spin(&w_mtx);
|
||||||
|
|
||||||
/* The graph has changed, try again. */
|
/* The graph has changed, try again. */
|
||||||
req->oldidx = 0;
|
*oldidx = 0;
|
||||||
sbuf_clear(sb);
|
sbuf_clear(sb);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
@ -2613,7 +2600,7 @@ restart:
|
|||||||
mtx_unlock_spin(&w_mtx);
|
mtx_unlock_spin(&w_mtx);
|
||||||
|
|
||||||
/* The graph has changed, try again. */
|
/* The graph has changed, try again. */
|
||||||
req->oldidx = 0;
|
*oldidx = 0;
|
||||||
sbuf_clear(sb);
|
sbuf_clear(sb);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
@ -2672,7 +2659,7 @@ restart:
|
|||||||
* The graph changed while we were printing stack data,
|
* The graph changed while we were printing stack data,
|
||||||
* try again.
|
* try again.
|
||||||
*/
|
*/
|
||||||
req->oldidx = 0;
|
*oldidx = 0;
|
||||||
sbuf_clear(sb);
|
sbuf_clear(sb);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
@ -2683,6 +2670,28 @@ restart:
|
|||||||
free(tmp_data2, M_TEMP);
|
free(tmp_data2, M_TEMP);
|
||||||
free(tmp_w1, M_TEMP);
|
free(tmp_w1, M_TEMP);
|
||||||
free(tmp_w2, M_TEMP);
|
free(tmp_w2, M_TEMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
struct sbuf *sb;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (witness_watch < 1) {
|
||||||
|
error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning));
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
if (witness_cold) {
|
||||||
|
error = SYSCTL_OUT(req, w_stillcold, sizeof(w_stillcold));
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
error = 0;
|
||||||
|
sb = sbuf_new(NULL, NULL, badstack_sbuf_size, SBUF_AUTOEXTEND);
|
||||||
|
if (sb == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
sbuf_print_witness_badstacks(sb, &req->oldidx);
|
||||||
|
|
||||||
sbuf_finish(sb);
|
sbuf_finish(sb);
|
||||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||||
@ -2691,6 +2700,27 @@ restart:
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DDB
|
||||||
|
static int
|
||||||
|
sbuf_db_printf_drain(void *arg __unused, const char *data, int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (db_printf("%.*s", len, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
DB_SHOW_COMMAND(badstacks, db_witness_badstacks)
|
||||||
|
{
|
||||||
|
struct sbuf sb;
|
||||||
|
char buffer[128];
|
||||||
|
size_t dummy;
|
||||||
|
|
||||||
|
sbuf_new(&sb, buffer, sizeof(buffer), SBUF_FIXEDLEN);
|
||||||
|
sbuf_set_drain(&sb, sbuf_db_printf_drain, NULL);
|
||||||
|
sbuf_print_witness_badstacks(&sb, &dummy);
|
||||||
|
sbuf_finish(&sb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sysctl_debug_witness_channel(SYSCTL_HANDLER_ARGS)
|
sysctl_debug_witness_channel(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user