~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/vm/page_owner_sort.c

Version: ~ [ linux-5.5-rc1 ] ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.78 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * User-space helper to sort the output of /sys/kernel/debug/page_owner
  4  *
  5  * Example use:
  6  * cat /sys/kernel/debug/page_owner > page_owner_full.txt
  7  * grep -v ^PFN page_owner_full.txt > page_owner.txt
  8  * ./sort page_owner.txt sorted_page_owner.txt
  9 */
 10 
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <sys/types.h>
 14 #include <sys/stat.h>
 15 #include <fcntl.h>
 16 #include <unistd.h>
 17 #include <string.h>
 18 
 19 struct block_list {
 20         char *txt;
 21         int len;
 22         int num;
 23 };
 24 
 25 
 26 static struct block_list *list;
 27 static int list_size;
 28 static int max_size;
 29 
 30 struct block_list *block_head;
 31 
 32 int read_block(char *buf, int buf_size, FILE *fin)
 33 {
 34         char *curr = buf, *const buf_end = buf + buf_size;
 35 
 36         while (buf_end - curr > 1 && fgets(curr, buf_end - curr, fin)) {
 37                 if (*curr == '\n') /* empty line */
 38                         return curr - buf;
 39                 curr += strlen(curr);
 40         }
 41 
 42         return -1; /* EOF or no space left in buf. */
 43 }
 44 
 45 static int compare_txt(const void *p1, const void *p2)
 46 {
 47         const struct block_list *l1 = p1, *l2 = p2;
 48 
 49         return strcmp(l1->txt, l2->txt);
 50 }
 51 
 52 static int compare_num(const void *p1, const void *p2)
 53 {
 54         const struct block_list *l1 = p1, *l2 = p2;
 55 
 56         return l2->num - l1->num;
 57 }
 58 
 59 static void add_list(char *buf, int len)
 60 {
 61         if (list_size != 0 &&
 62             len == list[list_size-1].len &&
 63             memcmp(buf, list[list_size-1].txt, len) == 0) {
 64                 list[list_size-1].num++;
 65                 return;
 66         }
 67         if (list_size == max_size) {
 68                 printf("max_size too small??\n");
 69                 exit(1);
 70         }
 71         list[list_size].txt = malloc(len+1);
 72         list[list_size].len = len;
 73         list[list_size].num = 1;
 74         memcpy(list[list_size].txt, buf, len);
 75         list[list_size].txt[len] = 0;
 76         list_size++;
 77         if (list_size % 1000 == 0) {
 78                 printf("loaded %d\r", list_size);
 79                 fflush(stdout);
 80         }
 81 }
 82 
 83 #define BUF_SIZE        (128 * 1024)
 84 
 85 int main(int argc, char **argv)
 86 {
 87         FILE *fin, *fout;
 88         char *buf;
 89         int ret, i, count;
 90         struct block_list *list2;
 91         struct stat st;
 92 
 93         if (argc < 3) {
 94                 printf("Usage: ./program <input> <output>\n");
 95                 perror("open: ");
 96                 exit(1);
 97         }
 98 
 99         fin = fopen(argv[1], "r");
100         fout = fopen(argv[2], "w");
101         if (!fin || !fout) {
102                 printf("Usage: ./program <input> <output>\n");
103                 perror("open: ");
104                 exit(1);
105         }
106 
107         fstat(fileno(fin), &st);
108         max_size = st.st_size / 100; /* hack ... */
109 
110         list = malloc(max_size * sizeof(*list));
111         buf = malloc(BUF_SIZE);
112         if (!list || !buf) {
113                 printf("Out of memory\n");
114                 exit(1);
115         }
116 
117         for ( ; ; ) {
118                 ret = read_block(buf, BUF_SIZE, fin);
119                 if (ret < 0)
120                         break;
121 
122                 add_list(buf, ret);
123         }
124 
125         printf("loaded %d\n", list_size);
126 
127         printf("sorting ....\n");
128 
129         qsort(list, list_size, sizeof(list[0]), compare_txt);
130 
131         list2 = malloc(sizeof(*list) * list_size);
132 
133         printf("culling\n");
134 
135         for (i = count = 0; i < list_size; i++) {
136                 if (count == 0 ||
137                     strcmp(list2[count-1].txt, list[i].txt) != 0) {
138                         list2[count++] = list[i];
139                 } else {
140                         list2[count-1].num += list[i].num;
141                 }
142         }
143 
144         qsort(list2, count, sizeof(list[0]), compare_num);
145 
146         for (i = 0; i < count; i++)
147                 fprintf(fout, "%d times:\n%s\n", list2[i].num, list2[i].txt);
148 
149         return 0;
150 }
151 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp