firmware/br-ext-chip-allwinner/board/v83x/kernel/patches/00000-tools_vm_slabinfo.c.p...

329 lines
10 KiB
Diff

diff -drupN a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
--- a/tools/vm/slabinfo.c 2018-08-06 17:23:04.000000000 +0300
+++ b/tools/vm/slabinfo.c 2022-06-12 05:28:14.000000000 +0300
@@ -75,6 +75,9 @@ int show_inverted;
int show_single_ref;
int show_totals;
int sort_size;
+int sort_func;
+int sort_by_size;
+int sort_by_char;
int sort_active;
int set_debug;
int show_ops;
@@ -122,7 +125,9 @@ static void usage(void)
"-o|--ops Show kmem_cache_ops\n"
"-s|--shrink Shrink slabs\n"
"-r|--report Detailed report on single slabs\n"
- "-S|--Size Sort by size\n"
+ "-S|--Size Sort slab by size\n"
+ "-F|--Func Sort func by size\n"
+ "-C|--Char Sort func by first character of func\n"
"-t|--tracking Show alloc/free information\n"
"-T|--Totals Show summary information\n"
"-v|--validate Validate slabs\n"
@@ -1337,6 +1342,8 @@ struct option opts[] = {
{ "shrink", no_argument, NULL, 's' },
{ "report", no_argument, NULL, 'r' },
{ "Size", no_argument, NULL, 'S'},
+ { "Func", no_argument, NULL, 'F'},
+ { "Char", no_argument, NULL, 'C'},
{ "tracking", no_argument, NULL, 't'},
{ "Totals", no_argument, NULL, 'T'},
{ "validate", no_argument, NULL, 'v' },
@@ -1349,6 +1356,256 @@ struct option opts[] = {
{ NULL, 0, NULL, 0 }
};
+/*
+ * Output format:
+ * Total_size slab_type object_size objects slab_size alloc_calls_info
+ * */
+struct slab_func_info{
+ char slab_name[64]; //slab type
+ int slab_total_size; //total slab size alloc by func
+ int slab_object_size; //object size
+ int slab_size; //slab size
+ int slab_cnt; //objects num
+ char *slab_alloc_info; //slab alloc func info
+ struct slab_func_info *pNext;
+};
+
+static void swap_slab_func_info(struct slab_func_info *A, struct slab_func_info *B)
+{
+ char slab_name[64];
+ int slab_total_size;
+ int slab_object_size;
+ int slab_size;
+ int slab_cnt;
+ char *slab_alloc_info = NULL;
+
+ slab_total_size = (A)->slab_total_size;
+ (A)->slab_total_size = (B)->slab_total_size;
+ (B)->slab_total_size = slab_total_size;
+
+ slab_object_size = (A)->slab_object_size;
+ (A)->slab_object_size = (B)->slab_object_size;
+ (B)->slab_object_size = slab_object_size;
+
+ slab_size = (A)->slab_size;
+ (A)->slab_size = (B)->slab_size;
+ (B)->slab_size = slab_size;
+
+ slab_cnt = (A)->slab_cnt;
+ (A)->slab_cnt = (B)->slab_cnt;
+ (B)->slab_cnt = slab_cnt;
+
+ strcpy(slab_name, (A)->slab_name);
+ strcpy((A)->slab_name, (B)->slab_name);
+ strcpy((B)->slab_name, slab_name);
+
+ slab_alloc_info = (A)->slab_alloc_info;
+ (A)->slab_alloc_info = (B)->slab_alloc_info;
+ (B)->slab_alloc_info = slab_alloc_info;
+}
+
+//#define SAVE_RESULT_FILE
+
+static void sort_func_by_size(struct slab_func_info *info_head, FILE *fp)
+{
+ struct slab_func_info *info_p = NULL;
+ struct slab_func_info *tmp_p = NULL;
+ struct slab_func_info *tgt_p = NULL;
+ int total_size = 0;
+
+ info_p = info_head;
+ for (; info_p != NULL; info_p = info_p->pNext) {
+ total_size = info_p->slab_total_size;
+ tgt_p = info_p;
+ for (tmp_p = info_p->pNext; tmp_p != NULL; tmp_p = tmp_p->pNext) {
+ if (total_size < tmp_p->slab_total_size) {
+ total_size = tmp_p->slab_total_size;
+ tgt_p = tmp_p;
+ }
+ }
+
+ printf("%-12d %-24s %-9d %-7d %-10d %s\n", tgt_p->slab_total_size,
+ tgt_p->slab_name, tgt_p->slab_object_size, tgt_p->slab_cnt, tgt_p->slab_size, tgt_p->slab_alloc_info);
+#ifdef SAVE_RESULT_FILE
+ fprintf(fp, "%-12d %-24s %-10d %-7d %-10d %s\n", tgt_p->slab_total_size,
+ tgt_p->slab_name, tgt_p->slab_size, tgt_p->slab_cnt, tgt_p->slab_object_size, tgt_p->slab_alloc_info);
+#endif
+
+ swap_slab_func_info(tgt_p, info_p);
+ }
+}
+
+static void sort_func_by_char(struct slab_func_info *info_head, FILE *fp)
+{
+ int i = 0, j = 0;
+ int had_sort_num = 0;
+ char *func_char_p = NULL;
+ struct slab_func_info *info_p = NULL;
+ struct slab_func_info *had_sort_p = NULL;
+ char *func_first_char = "abcdefghijklmnopqrstuvwxyzADCDEFGHIJKLMNOPQRSTUVWXYZ_<";
+ int func_char_len = strlen(func_first_char);
+
+ for (i = 0; i < func_char_len; i++, func_first_char++) {
+ info_p = info_head;
+ for (j = 0; j < had_sort_num; j++)
+ info_p = info_p->pNext;
+ had_sort_p = info_p;
+ for (; info_p != NULL; info_p = info_p->pNext) {
+ if (!strncmp(info_p->slab_alloc_info, func_first_char, 1)) {
+ swap_slab_func_info(had_sort_p, info_p);
+
+ printf("%-12d %-24s %-9d %-7d %-10d %s\n", had_sort_p->slab_total_size, had_sort_p->slab_name,
+ had_sort_p->slab_object_size, had_sort_p->slab_cnt, had_sort_p->slab_size, had_sort_p->slab_alloc_info);
+#ifdef SAVE_RESULT_FILE
+ fprintf(fp, "%-12d %-24s %-9d %-7d %-10d %s\n", had_sort_p->slab_total_size, had_sort_p->slab_name,
+ had_sort_p->slab_object_size, had_sort_p->slab_cnt, had_sort_p->slab_size, had_sort_p->slab_alloc_info);
+#endif
+
+ had_sort_p = had_sort_p->pNext;
+ had_sort_num++;
+ }
+ }
+ }
+}
+
+static int sort_and_show_func(void)
+{
+ FILE *fp = NULL;
+ FILE *fp_output = NULL;
+ char *str_p = NULL;
+ struct slabinfo *s = NULL;
+ char slab_name[64];
+ char str_one_line[1024];
+ int slab_size = 0;
+ int object_size = 0;
+ struct slab_func_info *info_head = NULL;
+ struct slab_func_info *info_p = NULL;
+
+ info_head = (struct slab_func_info *)malloc(sizeof(struct slab_func_info));
+ info_head->pNext = NULL;
+ info_p = info_head;
+
+#ifdef SAVE_RESULT_FILE
+ system("rm /tmp/slab_func_info > /dev/null 2>&1");
+#endif
+ /* collect alloc_calls messages and save them in tempfile*/
+ fp = fopen("/tmp/tempfile", "arw+");
+ if (fp == NULL) {
+ printf("open %s file fail!\n", "/tmp/tempfile");
+ return -1;
+ }
+ for (s = slabinfo; s < slabinfo + slabs; s++) {
+ if (read_slab_obj(s, "alloc_calls")) {
+ fprintf(fp, "slabname: %s, object_size: %d, slab_size: %d\n",
+ s->name, s->object_size, s->slab_size);
+ fwrite(buffer, 1, strlen(buffer), fp);
+ }
+ }
+
+ rewind(fp);
+ while (!feof(fp)) {
+ fgets(str_one_line, 1024, fp);
+ if (strlen(str_one_line) == 0)
+ break;
+
+ if (!strncmp(str_one_line, "slabname", 8)) { /*get one slab type info*/
+ /* format: slabname: %s, object_size: %d, slab_size: %d */
+ str_p = NULL;
+ str_p = strtok(str_one_line, " ");
+ str_p = strtok(NULL, ",");
+ strcpy(slab_name, str_p); /*get slab type*/
+ str_p = strtok(NULL, " ");
+ str_p = strtok(NULL, ",");
+ object_size = atoi(str_p); /*get object size*/
+ str_p = strtok(NULL, " ");
+ str_p = strtok(NULL, " ");
+ slab_size = atoi(str_p); /*get slab size*/
+ } else if (!strncmp(str_one_line, "No data", 7)) {
+ /*some of the loss parts*/
+ continue;
+ } else if (strlen(str_one_line) < 16) { // wait for fix
+ continue;
+ } else {
+ /*one slab object one time*/
+ if (info_head->pNext == NULL) {
+ info_p = info_head;
+ info_head->pNext = (struct slab_func_info *)malloc(sizeof(struct slab_func_info));
+ } else {
+ info_p->pNext = (struct slab_func_info *)malloc(sizeof(struct slab_func_info));
+ if (info_p->pNext == NULL) {
+ printf("In %s line %d: malloc fail!\n", __func__, __LINE__);
+ fclose(fp);
+ return -1;
+ }
+ info_p = info_p->pNext;
+ }
+ strcpy(info_p->slab_name, slab_name);
+ info_p->slab_object_size = object_size;
+ info_p->slab_size = slab_size;
+ /*format: objs alloc_func_info*/
+ str_p = NULL;
+ str_p = strtok(str_one_line, " ");
+ info_p->slab_cnt = atoi(str_p); /*get objests num*/
+ info_p->slab_total_size = info_p->slab_object_size * info_p->slab_cnt;
+ str_p = strtok(NULL, " "); /*get alloc func info*/
+ info_p->slab_alloc_info = (char *)malloc(strlen(str_p) + 4);
+ //info_p->slab_alloc_info = (char *)malloc(strlen(str_p) + 1); //malloc may fail?
+ if (info_p->slab_alloc_info == NULL) {
+ printf("In %s line %d: malloc fail!\n", __func__, __LINE__);
+ fclose(fp);
+ return -1;
+ }
+ strcpy(info_p->slab_alloc_info, str_p);
+#if 0
+ printf("In %d line %d: alloc_info = %s\n", __func__, __LINE__, info_p->slab_alloc_info);
+ printf("In %d line %d: total_size= %d, slab_name %s, alloc_info %s\n", __func__, __LINE__,
+ info_p->slab_total_size, info_p->slab_name, info_p->slab_alloc_info);
+#endif
+ }
+ }
+
+#ifdef SAVE_RESULT_FILE
+ fp_output = fopen("/tmp/slab_func_info", "arw+");
+ if (fp_output == NULL) {
+ printf("open %s file fail!\n", "/data/slab_func_info");
+ fclose(fp);
+ return -1;
+ }
+ fprintf(fp_output, "Total(byte) Slab_type Obj_size Objs Slab_size Alloc_func\n");
+#endif
+
+ printf("Total(byte) Slab_type Obj_size Objs Slab_size Alloc_func\n");
+ if (sort_by_size) {
+ /*sort by size*/
+ sort_func_by_size(info_head, fp_output);
+ } else if (sort_func_by_char) {
+ /*sort by the first character of alloc func name*/
+ sort_func_by_char(info_head, fp_output);
+ }
+
+ /*free sources!*/
+ /*must free malloc buffer*/
+ info_p = info_head;
+ for (; info_p != NULL; info_p = info_p->pNext) {
+ if (info_p->slab_alloc_info != NULL) {
+ free(info_p->slab_alloc_info);
+ info_p->slab_alloc_info = NULL;
+ }
+ if (info_p != NULL) {
+ free(info_p);
+ // info_p = NULL; /*segmemtation fault!*/
+ }
+ }
+
+ fclose(fp);
+#ifdef SAVE_RESULT_FILE
+ fclose(fp_output);
+#endif
+ system("rm /tmp/tempfile > /dev/null 2>&1");
+
+ return 1;
+}
+
int main(int argc, char *argv[])
{
int c;
@@ -1357,7 +1614,7 @@ int main(int argc, char *argv[])
page_size = getpagesize();
- while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:LXB",
+ while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSFCN:LXB",
opts, NULL)) != -1)
switch (c) {
case '1':
@@ -1419,6 +1676,16 @@ int main(int argc, char *argv[])
case 'S':
sort_size = 1;
break;
+ case 'F':
+ sort_size = 1;
+ sort_func = 1;
+ sort_by_size = 1;
+ break;
+ case 'C':
+ sort_size = 1;
+ sort_func = 1;
+ sort_by_char = 1;
+ break;
case 'N':
if (optarg) {
output_lines = atoi(optarg);
@@ -1463,6 +1730,11 @@ int main(int argc, char *argv[])
xtotals();
} else if (show_totals) {
totals();
+ } else if (sort_func) {
+ link_slabs();
+ rename_slabs();
+ sort_slabs();
+ sort_and_show_func();
} else {
link_slabs();
rename_slabs();