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_object.h> 57 #include <vm/swap_pager.h> 58 #include <vm/vnode_pager.h> 59 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <string.h> 63 #include <fcntl.h> 64 #include <kvm.h> 65 #include <nlist.h> 66 #include <getopt.h> 67 68 struct nlist Nl[] = { 69 #if 0 70 { "_vm_page_buckets" }, 71 { "_vm_page_hash_mask" }, 72 #endif 73 { "_vm_page_queues" }, 74 { NULL } 75 }; 76 77 int debugopt; 78 int verboseopt; 79 80 static void kkread_vmpage(kvm_t *kd, u_long addr, vm_page_t m); 81 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes); 82 static int kkread_err(kvm_t *kd, u_long addr, void *buf, size_t nbytes); 83 84 int 85 main(int ac, char **av) 86 { 87 const char *corefile = NULL; 88 const char *sysfile = NULL; 89 kvm_t *kd; 90 int ch; 91 int i; 92 int q = PQ_FREE; 93 struct vpgqueues queues[PQ_COUNT]; 94 95 while ((ch = getopt(ac, av, "M:N:dviacf")) != -1) { 96 switch(ch) { 97 case 'i': 98 q = PQ_INACTIVE; 99 break; 100 case 'a': 101 q = PQ_ACTIVE; 102 break; 103 case 'c': 104 q = PQ_CACHE; 105 break; 106 case 'f': 107 q = PQ_FREE; 108 break; 109 case 'd': 110 ++debugopt; 111 break; 112 case 'v': 113 ++verboseopt; 114 break; 115 case 'M': 116 corefile = optarg; 117 break; 118 case 'N': 119 sysfile = optarg; 120 break; 121 default: 122 fprintf(stderr, "%s [-M core] [-N system]\n", av[0]); 123 exit(1); 124 } 125 } 126 ac -= optind; 127 av += optind; 128 129 if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) { 130 perror("kvm_open"); 131 exit(1); 132 } 133 if (kvm_nlist(kd, Nl) != 0) { 134 perror("kvm_nlist"); 135 exit(1); 136 } 137 138 for (;;) { 139 kkread(kd, Nl[0].n_value, queues, sizeof(queues)); 140 for (i = 0; i < PQ_L2_SIZE; ++i) { 141 struct vpgqueues *vpq = &queues[q+i]; 142 if ((i & 7) == 0) 143 printf("%3d ", i); 144 printf("\t%6d", vpq->lcnt); 145 if ((i & 7) == 7) 146 printf("\n"); 147 if ((i & 63) == 63) 148 printf("\n"); 149 } 150 printf("\n"); 151 sleep(1); 152 } 153 return(0); 154 } 155 156 static void 157 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes) 158 { 159 if (kvm_read(kd, addr, buf, nbytes) != nbytes) { 160 perror("kvm_read"); 161 exit(1); 162 } 163 } 164 165 static int 166 kkread_err(kvm_t *kd, u_long addr, void *buf, size_t nbytes) 167 { 168 if (kvm_read(kd, addr, buf, nbytes) != nbytes) { 169 return 1; 170 } 171 return 0; 172 } 173