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