aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2017-09-22 20:01:12 +0000
committerConrad Meyer <cem@FreeBSD.org>2017-09-22 20:01:12 +0000
commit6fec2d2cce07c1db709678a662204508d4647108 (patch)
tree976dec9ccd05e9f37c171b578c181687b7fd1b57 /sys
parent64f73a4c67cce02ae4debfd513da6998cb804301 (diff)
downloadsrc-6fec2d2cce07c1db709678a662204508d4647108.tar.gz
src-6fec2d2cce07c1db709678a662204508d4647108.zip
ddb(4): Add 'show badstacks' command to show witness badstacks
Add a DDB command that mirrors sysctl debug.witness.badstacks. Reported by: rstone Reviewed by: rstone Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D12468
Notes
Notes: svn path=/head/; revision=323935
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_witness.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index be3ca31df356..dffbb3afbae6 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -2539,31 +2539,18 @@ DB_SHOW_COMMAND(witness, db_witness_display)
}
#endif
-static int
-sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS)
+static void
+sbuf_print_witness_badstacks(struct sbuf *sb)
{
struct witness_lock_order_data *data1, *data2, *tmp_data1, *tmp_data2;
struct witness *tmp_w1, *tmp_w2, *w1, *w2;
- struct sbuf *sb;
u_int w_rmatrix1, w_rmatrix2;
- int error, generation, i, j;
+ int generation, i, j;
tmp_data1 = NULL;
tmp_data2 = NULL;
tmp_w1 = 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. */
tmp_w1 = malloc(sizeof(struct witness), M_TEMP, M_WAITOK | M_ZERO);
@@ -2683,6 +2670,28 @@ restart:
free(tmp_data2, M_TEMP);
free(tmp_w1, 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);
sbuf_finish(sb);
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
@@ -2691,6 +2700,26 @@ restart:
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];
+
+ sbuf_new(&sb, buffer, sizeof(buffer), SBUF_FIXEDLEN);
+ sbuf_set_drain(&sb, sbuf_db_printf_drain, NULL);
+ sbuf_print_witness_badstacks(&sb);
+ sbuf_finish(&sb);
+}
+#endif
+
static int
sysctl_debug_witness_channel(SYSCTL_HANDLER_ARGS)
{