xref: /dragonfly/test/debug/schedmon.c (revision ec21d9fb)
1 /*
2  * SCHEDMON.C
3  *
4  * cc -I/usr/src/sys schedmon.c -o ~/bin/schedmon -lkvm
5  *
6  * Monitor the user scheduler
7  *
8  * Copyright (c) 2020 The DragonFly Project.  All rights reserved.
9  *
10  * This code is derived from software contributed to The DragonFly Project
11  * by Matthew Dillon <dillon@backplane.com>
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in
21  *    the documentation and/or other materials provided with the
22  *    distribution.
23  * 3. Neither the name of The DragonFly Project nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific, prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
31  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
35  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  * $DragonFly: src/test/debug/ncptrace.c,v 1.7 2007/05/06 20:45:01 dillon Exp $
41  */
42 
43 #define _KERNEL_STRUCTURES
44 #include <sys/param.h>
45 #include <sys/user.h>
46 #include <sys/malloc.h>
47 #include <sys/signalvar.h>
48 #include <sys/vnode.h>
49 #include <sys/namecache.h>
50 #include <sys/mount.h>
51 #include <sys/cpu_topology.h>
52 
53 #include <vm/vm.h>
54 #include <vm/vm_page.h>
55 #include <vm/vm_kern.h>
56 #include <vm/swap_pager.h>
57 #include <vm/vnode_pager.h>
58 
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <fcntl.h>
63 #include <kvm.h>
64 #include <nlist.h>
65 #include <getopt.h>
66 
67 #include <sys/usched_dfly.h>
68 
69 struct nlist Nl[] = {
70     { "_ncpus" },
71     { "_dfly_pcpu" },
72     { NULL }
73 };
74 
75 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
76 
77 int
78 main(int ac, char **av)
79 {
80     struct usched_dfly_pcpu *pcpu;
81     struct usched_dfly_pcpu *scan;
82     const char *corefile = NULL;
83     const char *sysfile = NULL;
84     const char *path;
85     kvm_t *kd;
86     int ncpus;
87     int ch;
88     int i;
89 
90     while ((ch = getopt(ac, av, "M:N:")) != -1) {
91 	switch(ch) {
92 	case 'M':
93 	    corefile = optarg;
94 	    break;
95 	case 'N':
96 	    sysfile = optarg;
97 	    break;
98 	default:
99 	    fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
100 	    exit(1);
101 	}
102     }
103     ac -= optind;
104     av += optind;
105 
106     if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
107 	perror("kvm_open");
108 	exit(1);
109     }
110     if (kvm_nlist(kd, Nl) != 0) {
111 	perror("kvm_nlist");
112 	exit(1);
113     }
114     usleep(100000);
115     kkread(kd, Nl[0].n_value, &ncpus, sizeof(ncpus));
116     pcpu = malloc(ncpus * sizeof(*pcpu));
117     kkread(kd, Nl[1].n_value, pcpu, ncpus * sizeof(*pcpu));
118 
119     printf("%p %d\n", pcpu, ncpus);
120     for (i = 0; i < ncpus; ++i) {
121 	scan = &pcpu[i];
122 
123 	printf("%3d ", i);
124 	if (scan->ucount == 0 && scan->uload == 0 && scan->uschedcp == NULL) {
125 		printf("IDLE                                               "
126 			"                    ");
127 	} else {
128 		printf("runq=%-3d ucount=%-3d uload=%-5d ",
129 			scan->runqcount, scan->ucount, scan->uload);
130 		if (scan->uschedcp)
131 			printf("uschedcp=%p ", scan->uschedcp);
132 		else
133 			printf("uschedcp=------------------ ");
134 		if (scan->queuebits)
135 			printf("qs=%08x", scan->queuebits);
136 		else
137 			printf("qs=EMPTY   ");
138 	}
139 	if (i & 1)
140 		printf("\n");
141 	else
142 		printf("\t");
143     }
144 }
145 
146 static void
147 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
148 {
149     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
150         perror("kvm_read");
151         exit(1);
152     }
153 }
154