Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 02 Sep 2005 14:01:04 -0400
From:      Ben Thomas <bthomas@virtualiron.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/85658: [patch] add DDB command, show runq, to sched_ule.c
Message-ID:  <43189360.6010304@virtualiron.com>
Resent-Message-ID: <200509021810.j82IACwt059891@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         85658
>Category:       kern
>Synopsis:       [patch] add DDB command, show runq, to sched_ule.c
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 02 18:10:12 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Ben Thomas
>Release:        FreeBSD 5.4-RELEASE i386
>Organization:
Virtual Iron Software
>Environment:
System: FreeBSD bthomas4.katana-technology.com 5.4-RELEASE FreeBSD 5.4-RELEASE #10: Sun Aug 28 13:48:00 EDT 2005 ben@bthomas4.katana-technology.com:/usr/obj/usr/home/ben/BSD/RELENG_5_4_0_RELEASE/src/sys/BEN i386


>Description:

I've found a need to look at the run queues for debugging purposes.  After
a while, you get tired of running through data structures, and want something
a little simpler.  This patch adds a "show runq" DDB command that dumps the
current run queues.  Note that this is for sched_ule.c, which is all we run.
I assume that with a little work, it would apply to sched_4bsd.

This patch is against the 5_4_0_RELEASE source


>How-To-Repeat:
>Fix:

--- /usr/src.original/sys/kern/sched_ule.c      Fri Feb  4 15:13:21 2005
+++ /usr/src/sys/kern/sched_ule.c       Fri Aug  5 15:15:38 2005
@@ -51,6 +51,10 @@
 #include <sys/uio.h>
 #include <sys/ktrace.h>
 #endif
+#include "opt_ddb.h"
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif

 #include <machine/cpu.h>
 #include <machine/smp.h>
@@ -1922,3 +1926,104 @@
 }
 #define KERN_SWITCH_INCLUDE 1
 #include "kern/kern_switch.c"
+
+/* DDB command to dump run queues */
+
+#ifdef DDB
+
+static void print_runq(struct runq *rq, char *string1, char *string2)
+{
+       struct rqbits *rqb;
+       int             w;
+       int             b;
+       int           set;
+       int           empty;
+       struct kse    *kse;
+       int           qIndex;
+       char            sep;
+
+       /* Check input arguments */
+
+       if ( (rq == NULL) || (string1 == NULL) || (string2 == NULL) )
+               return;
+
+       db_printf("  Run Queue '%s%s' (%p):\n", string1, string2, rq);
+
+       rqb = &rq->rq_status;
+       for (w=0; w < RQB_LEN; w++) {
+               for (b = 0; b < RQB_BPW; b++) {
+                       qIndex = (w * RQB_BPW) + b;
+                       set = rqb->rqb_bits[w] & (1 << b);
+                       empty = TAILQ_EMPTY(&rq->rq_queues[qIndex]);
+                       if (empty) {
+                               if (set)
+                                 db_printf("      Pri %3d-%3d: [bit set, but queue is empty]\n",
+                                           (qIndex*RQ_PPQ), ((qIndex*RQ_PPQ) + (RQ_PPQ-1)));
+                               continue;
+                       }
+                       db_printf("      Pri %3d-%3d: ",
+                                 (qIndex*RQ_PPQ), ((qIndex*RQ_PPQ) + (RQ_PPQ-1)));
+                       if (!set)
+                         db_printf("[queue not empty, but bit NOT set]: ");
+
+                       sep = ' ';
+                       TAILQ_FOREACH(kse, &rq->rq_queues[qIndex], ke_procq) {
+                               db_printf("%c %s[%p]", sep, kse->ke_proc->p_comm, kse->ke_thread);
+                               sep= ',';
+                       }
+                       db_printf("\n");
+               }
+       }
+}
+
+DB_SHOW_COMMAND(runq, runq)
+{
+       int             i;
+       struct kseq     *kseq;
+       struct pcpu     *pcpu;
+       struct thread   *td;
+
+       /* Dump the run queues for each CPU */
+
+       for (i = 0; i < mp_ncpus; i++) {
+               kseq = &kseq_cpu[i];
+               if (kseq == NULL) {
+                       db_printf("? CPU %d has no kseq structure\n", i);
+                       continue;
+               }
+
+         /* Output basic information */
+
+               db_printf("CPU %d: Load %d, Load_TimeShare %d",
+                         i, kseq->ksq_load, kseq->ksq_load_timeshare);
+#ifdef SMP
+               db_printf(", Load_Transferrable %d\n", kseq->ksq_transferable);
+#else
+               db_printf(", Load Average %d\n", kseq->ksq_sysload);
+#endif
+               db_printf("\n");
+
+         /* Print current thread info */
+
+               pcpu = pcpu_find(i);
+               if (pcpu != NULL) {
+                       td = pcpu->pc_curthread;
+                       if ( (td != NULL) && (td->td_proc != NULL) ) {
+                               db_printf("  Current thread: %s[%p] Prio: %d\n", td->td_proc->p_comm, td, td->td_priority);
+                       }
+               }
+
+         /* Now, dump each of the queues */
+
+             print_runq(&kseq->ksq_idle, "Idle", "");
+
+               print_runq(&kseq->ksq_timeshare[0], "Timeshare[0]",
+                          ((kseq->ksq_curr == &kseq->ksq_timeshare[0]) ? " [Curr]" : " [Next]"));
+
+               print_runq(&kseq->ksq_timeshare[1], "Timeshare[1]",
+                          ((kseq->ksq_curr == &kseq->ksq_timeshare[1]) ? " [Curr]" : " [Next]"));
+               db_printf("\n");
+       }
+
+}
+#endif
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?43189360.6010304>