Author: cem
Date: Sat Sep 23 17:48:49 2017
New Revision: 323956
URL: https://svnweb.freebsd.org/changeset/base/323956

Log:
  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

Modified:
  head/sys/kern/subr_witness.c

Modified: head/sys/kern/subr_witness.c
==============================================================================
--- head/sys/kern/subr_witness.c        Sat Sep 23 16:59:37 2017        
(r323955)
+++ head/sys/kern/subr_witness.c        Sat Sep 23 17:48:49 2017        
(r323956)
@@ -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, size_t *oldidx)
 {
        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);
@@ -2587,7 +2574,7 @@ restart:
                        mtx_unlock_spin(&w_mtx);
 
                        /* The graph has changed, try again. */
-                       req->oldidx = 0;
+                       *oldidx = 0;
                        sbuf_clear(sb);
                        goto restart;
                }
@@ -2613,7 +2600,7 @@ restart:
                                mtx_unlock_spin(&w_mtx);
 
                                /* The graph has changed, try again. */
-                               req->oldidx = 0;
+                               *oldidx = 0;
                                sbuf_clear(sb);
                                goto restart;
                        }
@@ -2672,7 +2659,7 @@ restart:
                 * The graph changed while we were printing stack data,
                 * try again.
                 */
-               req->oldidx = 0;
+               *oldidx = 0;
                sbuf_clear(sb);
                goto restart;
        }
@@ -2683,13 +2670,56 @@ 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, &req->oldidx);
+
        sbuf_finish(sb);
        error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
        sbuf_delete(sb);
 
        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
 sysctl_debug_witness_channel(SYSCTL_HANDLER_ARGS)
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to