18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Slabinfo: Tool to get reports about slabs 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) 2007 sgi, Christoph Lameter 68c2ecf20Sopenharmony_ci * (C) 2011 Linux Foundation, Christoph Lameter 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Compile with: 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * gcc -o slabinfo slabinfo.c 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci#include <stdio.h> 138c2ecf20Sopenharmony_ci#include <stdlib.h> 148c2ecf20Sopenharmony_ci#include <sys/types.h> 158c2ecf20Sopenharmony_ci#include <dirent.h> 168c2ecf20Sopenharmony_ci#include <strings.h> 178c2ecf20Sopenharmony_ci#include <string.h> 188c2ecf20Sopenharmony_ci#include <unistd.h> 198c2ecf20Sopenharmony_ci#include <stdarg.h> 208c2ecf20Sopenharmony_ci#include <getopt.h> 218c2ecf20Sopenharmony_ci#include <regex.h> 228c2ecf20Sopenharmony_ci#include <errno.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define MAX_SLABS 500 258c2ecf20Sopenharmony_ci#define MAX_ALIASES 500 268c2ecf20Sopenharmony_ci#define MAX_NODES 1024 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistruct slabinfo { 298c2ecf20Sopenharmony_ci char *name; 308c2ecf20Sopenharmony_ci int alias; 318c2ecf20Sopenharmony_ci int refs; 328c2ecf20Sopenharmony_ci int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu; 338c2ecf20Sopenharmony_ci unsigned int hwcache_align, object_size, objs_per_slab; 348c2ecf20Sopenharmony_ci unsigned int sanity_checks, slab_size, store_user, trace; 358c2ecf20Sopenharmony_ci int order, poison, reclaim_account, red_zone; 368c2ecf20Sopenharmony_ci unsigned long partial, objects, slabs, objects_partial, objects_total; 378c2ecf20Sopenharmony_ci unsigned long alloc_fastpath, alloc_slowpath; 388c2ecf20Sopenharmony_ci unsigned long free_fastpath, free_slowpath; 398c2ecf20Sopenharmony_ci unsigned long free_frozen, free_add_partial, free_remove_partial; 408c2ecf20Sopenharmony_ci unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill; 418c2ecf20Sopenharmony_ci unsigned long cpuslab_flush, deactivate_full, deactivate_empty; 428c2ecf20Sopenharmony_ci unsigned long deactivate_to_head, deactivate_to_tail; 438c2ecf20Sopenharmony_ci unsigned long deactivate_remote_frees, order_fallback; 448c2ecf20Sopenharmony_ci unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail; 458c2ecf20Sopenharmony_ci unsigned long alloc_node_mismatch, deactivate_bypass; 468c2ecf20Sopenharmony_ci unsigned long cpu_partial_alloc, cpu_partial_free; 478c2ecf20Sopenharmony_ci int numa[MAX_NODES]; 488c2ecf20Sopenharmony_ci int numa_partial[MAX_NODES]; 498c2ecf20Sopenharmony_ci} slabinfo[MAX_SLABS]; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistruct aliasinfo { 528c2ecf20Sopenharmony_ci char *name; 538c2ecf20Sopenharmony_ci char *ref; 548c2ecf20Sopenharmony_ci struct slabinfo *slab; 558c2ecf20Sopenharmony_ci} aliasinfo[MAX_ALIASES]; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciint slabs; 588c2ecf20Sopenharmony_ciint actual_slabs; 598c2ecf20Sopenharmony_ciint aliases; 608c2ecf20Sopenharmony_ciint alias_targets; 618c2ecf20Sopenharmony_ciint highest_node; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cichar buffer[4096]; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciint show_empty; 668c2ecf20Sopenharmony_ciint show_report; 678c2ecf20Sopenharmony_ciint show_alias; 688c2ecf20Sopenharmony_ciint show_slab; 698c2ecf20Sopenharmony_ciint skip_zero = 1; 708c2ecf20Sopenharmony_ciint show_numa; 718c2ecf20Sopenharmony_ciint show_track; 728c2ecf20Sopenharmony_ciint show_first_alias; 738c2ecf20Sopenharmony_ciint validate; 748c2ecf20Sopenharmony_ciint shrink; 758c2ecf20Sopenharmony_ciint show_inverted; 768c2ecf20Sopenharmony_ciint show_single_ref; 778c2ecf20Sopenharmony_ciint show_totals; 788c2ecf20Sopenharmony_ciint sort_size; 798c2ecf20Sopenharmony_ciint sort_active; 808c2ecf20Sopenharmony_ciint set_debug; 818c2ecf20Sopenharmony_ciint show_ops; 828c2ecf20Sopenharmony_ciint sort_partial; 838c2ecf20Sopenharmony_ciint show_activity; 848c2ecf20Sopenharmony_ciint output_lines = -1; 858c2ecf20Sopenharmony_ciint sort_loss; 868c2ecf20Sopenharmony_ciint extended_totals; 878c2ecf20Sopenharmony_ciint show_bytes; 888c2ecf20Sopenharmony_ciint unreclaim_only; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* Debug options */ 918c2ecf20Sopenharmony_ciint sanity; 928c2ecf20Sopenharmony_ciint redzone; 938c2ecf20Sopenharmony_ciint poison; 948c2ecf20Sopenharmony_ciint tracking; 958c2ecf20Sopenharmony_ciint tracing; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciint page_size; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciregex_t pattern; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic void fatal(const char *x, ...) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci va_list ap; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci va_start(ap, x); 1068c2ecf20Sopenharmony_ci vfprintf(stderr, x, ap); 1078c2ecf20Sopenharmony_ci va_end(ap); 1088c2ecf20Sopenharmony_ci exit(EXIT_FAILURE); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic void usage(void) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.\n\n" 1148c2ecf20Sopenharmony_ci "slabinfo [-aABDefhilLnoPrsStTUvXz1] [N=K] [-dafzput] [slab-regexp]\n" 1158c2ecf20Sopenharmony_ci "-a|--aliases Show aliases\n" 1168c2ecf20Sopenharmony_ci "-A|--activity Most active slabs first\n" 1178c2ecf20Sopenharmony_ci "-B|--Bytes Show size in bytes\n" 1188c2ecf20Sopenharmony_ci "-D|--display-active Switch line format to activity\n" 1198c2ecf20Sopenharmony_ci "-e|--empty Show empty slabs\n" 1208c2ecf20Sopenharmony_ci "-f|--first-alias Show first alias\n" 1218c2ecf20Sopenharmony_ci "-h|--help Show usage information\n" 1228c2ecf20Sopenharmony_ci "-i|--inverted Inverted list\n" 1238c2ecf20Sopenharmony_ci "-l|--slabs Show slabs\n" 1248c2ecf20Sopenharmony_ci "-L|--Loss Sort by loss\n" 1258c2ecf20Sopenharmony_ci "-n|--numa Show NUMA information\n" 1268c2ecf20Sopenharmony_ci "-N|--lines=K Show the first K slabs\n" 1278c2ecf20Sopenharmony_ci "-o|--ops Show kmem_cache_ops\n" 1288c2ecf20Sopenharmony_ci "-P|--partial Sort by number of partial slabs\n" 1298c2ecf20Sopenharmony_ci "-r|--report Detailed report on single slabs\n" 1308c2ecf20Sopenharmony_ci "-s|--shrink Shrink slabs\n" 1318c2ecf20Sopenharmony_ci "-S|--Size Sort by size\n" 1328c2ecf20Sopenharmony_ci "-t|--tracking Show alloc/free information\n" 1338c2ecf20Sopenharmony_ci "-T|--Totals Show summary information\n" 1348c2ecf20Sopenharmony_ci "-U|--Unreclaim Show unreclaimable slabs only\n" 1358c2ecf20Sopenharmony_ci "-v|--validate Validate slabs\n" 1368c2ecf20Sopenharmony_ci "-X|--Xtotals Show extended summary information\n" 1378c2ecf20Sopenharmony_ci "-z|--zero Include empty slabs\n" 1388c2ecf20Sopenharmony_ci "-1|--1ref Single reference\n" 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci "\n" 1418c2ecf20Sopenharmony_ci "-d | --debug Switch off all debug options\n" 1428c2ecf20Sopenharmony_ci "-da | --debug=a Switch on all debug options (--debug=FZPU)\n" 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci "\n" 1458c2ecf20Sopenharmony_ci "-d[afzput] | --debug=[afzput]\n" 1468c2ecf20Sopenharmony_ci " f | F Sanity Checks (SLAB_CONSISTENCY_CHECKS)\n" 1478c2ecf20Sopenharmony_ci " z | Z Redzoning\n" 1488c2ecf20Sopenharmony_ci " p | P Poisoning\n" 1498c2ecf20Sopenharmony_ci " u | U Tracking\n" 1508c2ecf20Sopenharmony_ci " t | T Tracing\n" 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci "\nSorting options (--Loss, --Size, --Partial) are mutually exclusive\n" 1538c2ecf20Sopenharmony_ci ); 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic unsigned long read_obj(const char *name) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci FILE *f = fopen(name, "r"); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (!f) 1618c2ecf20Sopenharmony_ci buffer[0] = 0; 1628c2ecf20Sopenharmony_ci else { 1638c2ecf20Sopenharmony_ci if (!fgets(buffer, sizeof(buffer), f)) 1648c2ecf20Sopenharmony_ci buffer[0] = 0; 1658c2ecf20Sopenharmony_ci fclose(f); 1668c2ecf20Sopenharmony_ci if (buffer[strlen(buffer)] == '\n') 1678c2ecf20Sopenharmony_ci buffer[strlen(buffer)] = 0; 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci return strlen(buffer); 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* 1748c2ecf20Sopenharmony_ci * Get the contents of an attribute 1758c2ecf20Sopenharmony_ci */ 1768c2ecf20Sopenharmony_cistatic unsigned long get_obj(const char *name) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci if (!read_obj(name)) 1798c2ecf20Sopenharmony_ci return 0; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci return atol(buffer); 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic unsigned long get_obj_and_str(const char *name, char **x) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci unsigned long result = 0; 1878c2ecf20Sopenharmony_ci char *p; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci *x = NULL; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci if (!read_obj(name)) { 1928c2ecf20Sopenharmony_ci x = NULL; 1938c2ecf20Sopenharmony_ci return 0; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci result = strtoul(buffer, &p, 10); 1968c2ecf20Sopenharmony_ci while (*p == ' ') 1978c2ecf20Sopenharmony_ci p++; 1988c2ecf20Sopenharmony_ci if (*p) 1998c2ecf20Sopenharmony_ci *x = strdup(p); 2008c2ecf20Sopenharmony_ci return result; 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic void set_obj(struct slabinfo *s, const char *name, int n) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci char x[100]; 2068c2ecf20Sopenharmony_ci FILE *f; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci snprintf(x, 100, "%s/%s", s->name, name); 2098c2ecf20Sopenharmony_ci f = fopen(x, "w"); 2108c2ecf20Sopenharmony_ci if (!f) 2118c2ecf20Sopenharmony_ci fatal("Cannot write to %s\n", x); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci fprintf(f, "%d\n", n); 2148c2ecf20Sopenharmony_ci fclose(f); 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic unsigned long read_slab_obj(struct slabinfo *s, const char *name) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci char x[100]; 2208c2ecf20Sopenharmony_ci FILE *f; 2218c2ecf20Sopenharmony_ci size_t l; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci snprintf(x, 100, "%s/%s", s->name, name); 2248c2ecf20Sopenharmony_ci f = fopen(x, "r"); 2258c2ecf20Sopenharmony_ci if (!f) { 2268c2ecf20Sopenharmony_ci buffer[0] = 0; 2278c2ecf20Sopenharmony_ci l = 0; 2288c2ecf20Sopenharmony_ci } else { 2298c2ecf20Sopenharmony_ci l = fread(buffer, 1, sizeof(buffer), f); 2308c2ecf20Sopenharmony_ci buffer[l] = 0; 2318c2ecf20Sopenharmony_ci fclose(f); 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci return l; 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci/* 2388c2ecf20Sopenharmony_ci * Put a size string together 2398c2ecf20Sopenharmony_ci */ 2408c2ecf20Sopenharmony_cistatic int store_size(char *buffer, unsigned long value) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci unsigned long divisor = 1; 2438c2ecf20Sopenharmony_ci char trailer = 0; 2448c2ecf20Sopenharmony_ci int n; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (!show_bytes) { 2478c2ecf20Sopenharmony_ci if (value > 1000000000UL) { 2488c2ecf20Sopenharmony_ci divisor = 100000000UL; 2498c2ecf20Sopenharmony_ci trailer = 'G'; 2508c2ecf20Sopenharmony_ci } else if (value > 1000000UL) { 2518c2ecf20Sopenharmony_ci divisor = 100000UL; 2528c2ecf20Sopenharmony_ci trailer = 'M'; 2538c2ecf20Sopenharmony_ci } else if (value > 1000UL) { 2548c2ecf20Sopenharmony_ci divisor = 100; 2558c2ecf20Sopenharmony_ci trailer = 'K'; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci value /= divisor; 2608c2ecf20Sopenharmony_ci n = sprintf(buffer, "%ld",value); 2618c2ecf20Sopenharmony_ci if (trailer) { 2628c2ecf20Sopenharmony_ci buffer[n] = trailer; 2638c2ecf20Sopenharmony_ci n++; 2648c2ecf20Sopenharmony_ci buffer[n] = 0; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci if (divisor != 1) { 2678c2ecf20Sopenharmony_ci memmove(buffer + n - 2, buffer + n - 3, 4); 2688c2ecf20Sopenharmony_ci buffer[n-2] = '.'; 2698c2ecf20Sopenharmony_ci n++; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci return n; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistatic void decode_numa_list(int *numa, char *t) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci int node; 2778c2ecf20Sopenharmony_ci int nr; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci memset(numa, 0, MAX_NODES * sizeof(int)); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (!t) 2828c2ecf20Sopenharmony_ci return; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci while (*t == 'N') { 2858c2ecf20Sopenharmony_ci t++; 2868c2ecf20Sopenharmony_ci node = strtoul(t, &t, 10); 2878c2ecf20Sopenharmony_ci if (*t == '=') { 2888c2ecf20Sopenharmony_ci t++; 2898c2ecf20Sopenharmony_ci nr = strtoul(t, &t, 10); 2908c2ecf20Sopenharmony_ci numa[node] = nr; 2918c2ecf20Sopenharmony_ci if (node > highest_node) 2928c2ecf20Sopenharmony_ci highest_node = node; 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci while (*t == ' ') 2958c2ecf20Sopenharmony_ci t++; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic void slab_validate(struct slabinfo *s) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 3028c2ecf20Sopenharmony_ci return; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci set_obj(s, "validate", 1); 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistatic void slab_shrink(struct slabinfo *s) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 3108c2ecf20Sopenharmony_ci return; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci set_obj(s, "shrink", 1); 3138c2ecf20Sopenharmony_ci} 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ciint line = 0; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic void first_line(void) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci if (show_activity) 3208c2ecf20Sopenharmony_ci printf("Name Objects Alloc Free" 3218c2ecf20Sopenharmony_ci " %%Fast Fallb O CmpX UL\n"); 3228c2ecf20Sopenharmony_ci else 3238c2ecf20Sopenharmony_ci printf("Name Objects Objsize %s " 3248c2ecf20Sopenharmony_ci "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n", 3258c2ecf20Sopenharmony_ci sort_loss ? " Loss" : "Space"); 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/* 3298c2ecf20Sopenharmony_ci * Find the shortest alias of a slab 3308c2ecf20Sopenharmony_ci */ 3318c2ecf20Sopenharmony_cistatic struct aliasinfo *find_one_alias(struct slabinfo *find) 3328c2ecf20Sopenharmony_ci{ 3338c2ecf20Sopenharmony_ci struct aliasinfo *a; 3348c2ecf20Sopenharmony_ci struct aliasinfo *best = NULL; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci for(a = aliasinfo;a < aliasinfo + aliases; a++) { 3378c2ecf20Sopenharmony_ci if (a->slab == find && 3388c2ecf20Sopenharmony_ci (!best || strlen(best->name) < strlen(a->name))) { 3398c2ecf20Sopenharmony_ci best = a; 3408c2ecf20Sopenharmony_ci if (strncmp(a->name,"kmall", 5) == 0) 3418c2ecf20Sopenharmony_ci return best; 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci return best; 3458c2ecf20Sopenharmony_ci} 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic unsigned long slab_size(struct slabinfo *s) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci return s->slabs * (page_size << s->order); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic unsigned long slab_activity(struct slabinfo *s) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci return s->alloc_fastpath + s->free_fastpath + 3558c2ecf20Sopenharmony_ci s->alloc_slowpath + s->free_slowpath; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistatic unsigned long slab_waste(struct slabinfo *s) 3598c2ecf20Sopenharmony_ci{ 3608c2ecf20Sopenharmony_ci return slab_size(s) - s->objects * s->object_size; 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic void slab_numa(struct slabinfo *s, int mode) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci int node; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 3688c2ecf20Sopenharmony_ci return; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (!highest_node) { 3718c2ecf20Sopenharmony_ci printf("\n%s: No NUMA information available.\n", s->name); 3728c2ecf20Sopenharmony_ci return; 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci if (skip_zero && !s->slabs) 3768c2ecf20Sopenharmony_ci return; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci if (!line) { 3798c2ecf20Sopenharmony_ci printf("\n%-21s:", mode ? "NUMA nodes" : "Slab"); 3808c2ecf20Sopenharmony_ci for(node = 0; node <= highest_node; node++) 3818c2ecf20Sopenharmony_ci printf(" %4d", node); 3828c2ecf20Sopenharmony_ci printf("\n----------------------"); 3838c2ecf20Sopenharmony_ci for(node = 0; node <= highest_node; node++) 3848c2ecf20Sopenharmony_ci printf("-----"); 3858c2ecf20Sopenharmony_ci printf("\n"); 3868c2ecf20Sopenharmony_ci } 3878c2ecf20Sopenharmony_ci printf("%-21s ", mode ? "All slabs" : s->name); 3888c2ecf20Sopenharmony_ci for(node = 0; node <= highest_node; node++) { 3898c2ecf20Sopenharmony_ci char b[20]; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci store_size(b, s->numa[node]); 3928c2ecf20Sopenharmony_ci printf(" %4s", b); 3938c2ecf20Sopenharmony_ci } 3948c2ecf20Sopenharmony_ci printf("\n"); 3958c2ecf20Sopenharmony_ci if (mode) { 3968c2ecf20Sopenharmony_ci printf("%-21s ", "Partial slabs"); 3978c2ecf20Sopenharmony_ci for(node = 0; node <= highest_node; node++) { 3988c2ecf20Sopenharmony_ci char b[20]; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci store_size(b, s->numa_partial[node]); 4018c2ecf20Sopenharmony_ci printf(" %4s", b); 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci printf("\n"); 4048c2ecf20Sopenharmony_ci } 4058c2ecf20Sopenharmony_ci line++; 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic void show_tracking(struct slabinfo *s) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci printf("\n%s: Kernel object allocation\n", s->name); 4118c2ecf20Sopenharmony_ci printf("-----------------------------------------------------------------------\n"); 4128c2ecf20Sopenharmony_ci if (read_slab_obj(s, "alloc_calls")) 4138c2ecf20Sopenharmony_ci printf("%s", buffer); 4148c2ecf20Sopenharmony_ci else 4158c2ecf20Sopenharmony_ci printf("No Data\n"); 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci printf("\n%s: Kernel object freeing\n", s->name); 4188c2ecf20Sopenharmony_ci printf("------------------------------------------------------------------------\n"); 4198c2ecf20Sopenharmony_ci if (read_slab_obj(s, "free_calls")) 4208c2ecf20Sopenharmony_ci printf("%s", buffer); 4218c2ecf20Sopenharmony_ci else 4228c2ecf20Sopenharmony_ci printf("No Data\n"); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_cistatic void ops(struct slabinfo *s) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 4298c2ecf20Sopenharmony_ci return; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci if (read_slab_obj(s, "ops")) { 4328c2ecf20Sopenharmony_ci printf("\n%s: kmem_cache operations\n", s->name); 4338c2ecf20Sopenharmony_ci printf("--------------------------------------------\n"); 4348c2ecf20Sopenharmony_ci printf("%s", buffer); 4358c2ecf20Sopenharmony_ci } else 4368c2ecf20Sopenharmony_ci printf("\n%s has no kmem_cache operations\n", s->name); 4378c2ecf20Sopenharmony_ci} 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_cistatic const char *onoff(int x) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci if (x) 4428c2ecf20Sopenharmony_ci return "On "; 4438c2ecf20Sopenharmony_ci return "Off"; 4448c2ecf20Sopenharmony_ci} 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_cistatic void slab_stats(struct slabinfo *s) 4478c2ecf20Sopenharmony_ci{ 4488c2ecf20Sopenharmony_ci unsigned long total_alloc; 4498c2ecf20Sopenharmony_ci unsigned long total_free; 4508c2ecf20Sopenharmony_ci unsigned long total; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci if (!s->alloc_slab) 4538c2ecf20Sopenharmony_ci return; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci total_alloc = s->alloc_fastpath + s->alloc_slowpath; 4568c2ecf20Sopenharmony_ci total_free = s->free_fastpath + s->free_slowpath; 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci if (!total_alloc) 4598c2ecf20Sopenharmony_ci return; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci printf("\n"); 4628c2ecf20Sopenharmony_ci printf("Slab Perf Counter Alloc Free %%Al %%Fr\n"); 4638c2ecf20Sopenharmony_ci printf("--------------------------------------------------\n"); 4648c2ecf20Sopenharmony_ci printf("Fastpath %8lu %8lu %3lu %3lu\n", 4658c2ecf20Sopenharmony_ci s->alloc_fastpath, s->free_fastpath, 4668c2ecf20Sopenharmony_ci s->alloc_fastpath * 100 / total_alloc, 4678c2ecf20Sopenharmony_ci total_free ? s->free_fastpath * 100 / total_free : 0); 4688c2ecf20Sopenharmony_ci printf("Slowpath %8lu %8lu %3lu %3lu\n", 4698c2ecf20Sopenharmony_ci total_alloc - s->alloc_fastpath, s->free_slowpath, 4708c2ecf20Sopenharmony_ci (total_alloc - s->alloc_fastpath) * 100 / total_alloc, 4718c2ecf20Sopenharmony_ci total_free ? s->free_slowpath * 100 / total_free : 0); 4728c2ecf20Sopenharmony_ci printf("Page Alloc %8lu %8lu %3lu %3lu\n", 4738c2ecf20Sopenharmony_ci s->alloc_slab, s->free_slab, 4748c2ecf20Sopenharmony_ci s->alloc_slab * 100 / total_alloc, 4758c2ecf20Sopenharmony_ci total_free ? s->free_slab * 100 / total_free : 0); 4768c2ecf20Sopenharmony_ci printf("Add partial %8lu %8lu %3lu %3lu\n", 4778c2ecf20Sopenharmony_ci s->deactivate_to_head + s->deactivate_to_tail, 4788c2ecf20Sopenharmony_ci s->free_add_partial, 4798c2ecf20Sopenharmony_ci (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc, 4808c2ecf20Sopenharmony_ci total_free ? s->free_add_partial * 100 / total_free : 0); 4818c2ecf20Sopenharmony_ci printf("Remove partial %8lu %8lu %3lu %3lu\n", 4828c2ecf20Sopenharmony_ci s->alloc_from_partial, s->free_remove_partial, 4838c2ecf20Sopenharmony_ci s->alloc_from_partial * 100 / total_alloc, 4848c2ecf20Sopenharmony_ci total_free ? s->free_remove_partial * 100 / total_free : 0); 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci printf("Cpu partial list %8lu %8lu %3lu %3lu\n", 4878c2ecf20Sopenharmony_ci s->cpu_partial_alloc, s->cpu_partial_free, 4888c2ecf20Sopenharmony_ci s->cpu_partial_alloc * 100 / total_alloc, 4898c2ecf20Sopenharmony_ci total_free ? s->cpu_partial_free * 100 / total_free : 0); 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n", 4928c2ecf20Sopenharmony_ci s->deactivate_remote_frees, s->free_frozen, 4938c2ecf20Sopenharmony_ci s->deactivate_remote_frees * 100 / total_alloc, 4948c2ecf20Sopenharmony_ci total_free ? s->free_frozen * 100 / total_free : 0); 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci printf("Total %8lu %8lu\n\n", total_alloc, total_free); 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci if (s->cpuslab_flush) 4998c2ecf20Sopenharmony_ci printf("Flushes %8lu\n", s->cpuslab_flush); 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci total = s->deactivate_full + s->deactivate_empty + 5028c2ecf20Sopenharmony_ci s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass; 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci if (total) { 5058c2ecf20Sopenharmony_ci printf("\nSlab Deactivation Occurrences %%\n"); 5068c2ecf20Sopenharmony_ci printf("-------------------------------------------------\n"); 5078c2ecf20Sopenharmony_ci printf("Slab full %7lu %3lu%%\n", 5088c2ecf20Sopenharmony_ci s->deactivate_full, (s->deactivate_full * 100) / total); 5098c2ecf20Sopenharmony_ci printf("Slab empty %7lu %3lu%%\n", 5108c2ecf20Sopenharmony_ci s->deactivate_empty, (s->deactivate_empty * 100) / total); 5118c2ecf20Sopenharmony_ci printf("Moved to head of partial list %7lu %3lu%%\n", 5128c2ecf20Sopenharmony_ci s->deactivate_to_head, (s->deactivate_to_head * 100) / total); 5138c2ecf20Sopenharmony_ci printf("Moved to tail of partial list %7lu %3lu%%\n", 5148c2ecf20Sopenharmony_ci s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total); 5158c2ecf20Sopenharmony_ci printf("Deactivation bypass %7lu %3lu%%\n", 5168c2ecf20Sopenharmony_ci s->deactivate_bypass, (s->deactivate_bypass * 100) / total); 5178c2ecf20Sopenharmony_ci printf("Refilled from foreign frees %7lu %3lu%%\n", 5188c2ecf20Sopenharmony_ci s->alloc_refill, (s->alloc_refill * 100) / total); 5198c2ecf20Sopenharmony_ci printf("Node mismatch %7lu %3lu%%\n", 5208c2ecf20Sopenharmony_ci s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total); 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) { 5248c2ecf20Sopenharmony_ci printf("\nCmpxchg_double Looping\n------------------------\n"); 5258c2ecf20Sopenharmony_ci printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg Double redos %lu\n", 5268c2ecf20Sopenharmony_ci s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail); 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_cistatic void report(struct slabinfo *s) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 5338c2ecf20Sopenharmony_ci return; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci printf("\nSlabcache: %-15s Aliases: %2d Order : %2d Objects: %lu\n", 5368c2ecf20Sopenharmony_ci s->name, s->aliases, s->order, s->objects); 5378c2ecf20Sopenharmony_ci if (s->hwcache_align) 5388c2ecf20Sopenharmony_ci printf("** Hardware cacheline aligned\n"); 5398c2ecf20Sopenharmony_ci if (s->cache_dma) 5408c2ecf20Sopenharmony_ci printf("** Memory is allocated in a special DMA zone\n"); 5418c2ecf20Sopenharmony_ci if (s->destroy_by_rcu) 5428c2ecf20Sopenharmony_ci printf("** Slabs are destroyed via RCU\n"); 5438c2ecf20Sopenharmony_ci if (s->reclaim_account) 5448c2ecf20Sopenharmony_ci printf("** Reclaim accounting active\n"); 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci printf("\nSizes (bytes) Slabs Debug Memory\n"); 5478c2ecf20Sopenharmony_ci printf("------------------------------------------------------------------------\n"); 5488c2ecf20Sopenharmony_ci printf("Object : %7d Total : %7ld Sanity Checks : %s Total: %7ld\n", 5498c2ecf20Sopenharmony_ci s->object_size, s->slabs, onoff(s->sanity_checks), 5508c2ecf20Sopenharmony_ci s->slabs * (page_size << s->order)); 5518c2ecf20Sopenharmony_ci printf("SlabObj: %7d Full : %7ld Redzoning : %s Used : %7ld\n", 5528c2ecf20Sopenharmony_ci s->slab_size, s->slabs - s->partial - s->cpu_slabs, 5538c2ecf20Sopenharmony_ci onoff(s->red_zone), s->objects * s->object_size); 5548c2ecf20Sopenharmony_ci printf("SlabSiz: %7d Partial: %7ld Poisoning : %s Loss : %7ld\n", 5558c2ecf20Sopenharmony_ci page_size << s->order, s->partial, onoff(s->poison), 5568c2ecf20Sopenharmony_ci s->slabs * (page_size << s->order) - s->objects * s->object_size); 5578c2ecf20Sopenharmony_ci printf("Loss : %7d CpuSlab: %7d Tracking : %s Lalig: %7ld\n", 5588c2ecf20Sopenharmony_ci s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user), 5598c2ecf20Sopenharmony_ci (s->slab_size - s->object_size) * s->objects); 5608c2ecf20Sopenharmony_ci printf("Align : %7d Objects: %7d Tracing : %s Lpadd: %7ld\n", 5618c2ecf20Sopenharmony_ci s->align, s->objs_per_slab, onoff(s->trace), 5628c2ecf20Sopenharmony_ci ((page_size << s->order) - s->objs_per_slab * s->slab_size) * 5638c2ecf20Sopenharmony_ci s->slabs); 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci ops(s); 5668c2ecf20Sopenharmony_ci show_tracking(s); 5678c2ecf20Sopenharmony_ci slab_numa(s, 1); 5688c2ecf20Sopenharmony_ci slab_stats(s); 5698c2ecf20Sopenharmony_ci} 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_cistatic void slabcache(struct slabinfo *s) 5728c2ecf20Sopenharmony_ci{ 5738c2ecf20Sopenharmony_ci char size_str[20]; 5748c2ecf20Sopenharmony_ci char dist_str[40]; 5758c2ecf20Sopenharmony_ci char flags[20]; 5768c2ecf20Sopenharmony_ci char *p = flags; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 5798c2ecf20Sopenharmony_ci return; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci if (unreclaim_only && s->reclaim_account) 5828c2ecf20Sopenharmony_ci return; 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (actual_slabs == 1) { 5858c2ecf20Sopenharmony_ci report(s); 5868c2ecf20Sopenharmony_ci return; 5878c2ecf20Sopenharmony_ci } 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci if (skip_zero && !show_empty && !s->slabs) 5908c2ecf20Sopenharmony_ci return; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci if (show_empty && s->slabs) 5938c2ecf20Sopenharmony_ci return; 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci if (sort_loss == 0) 5968c2ecf20Sopenharmony_ci store_size(size_str, slab_size(s)); 5978c2ecf20Sopenharmony_ci else 5988c2ecf20Sopenharmony_ci store_size(size_str, slab_waste(s)); 5998c2ecf20Sopenharmony_ci snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs, 6008c2ecf20Sopenharmony_ci s->partial, s->cpu_slabs); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci if (!line++) 6038c2ecf20Sopenharmony_ci first_line(); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (s->aliases) 6068c2ecf20Sopenharmony_ci *p++ = '*'; 6078c2ecf20Sopenharmony_ci if (s->cache_dma) 6088c2ecf20Sopenharmony_ci *p++ = 'd'; 6098c2ecf20Sopenharmony_ci if (s->hwcache_align) 6108c2ecf20Sopenharmony_ci *p++ = 'A'; 6118c2ecf20Sopenharmony_ci if (s->poison) 6128c2ecf20Sopenharmony_ci *p++ = 'P'; 6138c2ecf20Sopenharmony_ci if (s->reclaim_account) 6148c2ecf20Sopenharmony_ci *p++ = 'a'; 6158c2ecf20Sopenharmony_ci if (s->red_zone) 6168c2ecf20Sopenharmony_ci *p++ = 'Z'; 6178c2ecf20Sopenharmony_ci if (s->sanity_checks) 6188c2ecf20Sopenharmony_ci *p++ = 'F'; 6198c2ecf20Sopenharmony_ci if (s->store_user) 6208c2ecf20Sopenharmony_ci *p++ = 'U'; 6218c2ecf20Sopenharmony_ci if (s->trace) 6228c2ecf20Sopenharmony_ci *p++ = 'T'; 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci *p = 0; 6258c2ecf20Sopenharmony_ci if (show_activity) { 6268c2ecf20Sopenharmony_ci unsigned long total_alloc; 6278c2ecf20Sopenharmony_ci unsigned long total_free; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci total_alloc = s->alloc_fastpath + s->alloc_slowpath; 6308c2ecf20Sopenharmony_ci total_free = s->free_fastpath + s->free_slowpath; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld\n", 6338c2ecf20Sopenharmony_ci s->name, s->objects, 6348c2ecf20Sopenharmony_ci total_alloc, total_free, 6358c2ecf20Sopenharmony_ci total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0, 6368c2ecf20Sopenharmony_ci total_free ? (s->free_fastpath * 100 / total_free) : 0, 6378c2ecf20Sopenharmony_ci s->order_fallback, s->order, s->cmpxchg_double_fail, 6388c2ecf20Sopenharmony_ci s->cmpxchg_double_cpu_fail); 6398c2ecf20Sopenharmony_ci } else { 6408c2ecf20Sopenharmony_ci printf("%-21s %8ld %7d %15s %14s %4d %1d %3ld %3ld %s\n", 6418c2ecf20Sopenharmony_ci s->name, s->objects, s->object_size, size_str, dist_str, 6428c2ecf20Sopenharmony_ci s->objs_per_slab, s->order, 6438c2ecf20Sopenharmony_ci s->slabs ? (s->partial * 100) / s->slabs : 100, 6448c2ecf20Sopenharmony_ci s->slabs ? (s->objects * s->object_size * 100) / 6458c2ecf20Sopenharmony_ci (s->slabs * (page_size << s->order)) : 100, 6468c2ecf20Sopenharmony_ci flags); 6478c2ecf20Sopenharmony_ci } 6488c2ecf20Sopenharmony_ci} 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci/* 6518c2ecf20Sopenharmony_ci * Analyze debug options. Return false if something is amiss. 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_cistatic int debug_opt_scan(char *opt) 6548c2ecf20Sopenharmony_ci{ 6558c2ecf20Sopenharmony_ci if (!opt || !opt[0] || strcmp(opt, "-") == 0) 6568c2ecf20Sopenharmony_ci return 1; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci if (strcasecmp(opt, "a") == 0) { 6598c2ecf20Sopenharmony_ci sanity = 1; 6608c2ecf20Sopenharmony_ci poison = 1; 6618c2ecf20Sopenharmony_ci redzone = 1; 6628c2ecf20Sopenharmony_ci tracking = 1; 6638c2ecf20Sopenharmony_ci return 1; 6648c2ecf20Sopenharmony_ci } 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci for ( ; *opt; opt++) 6678c2ecf20Sopenharmony_ci switch (*opt) { 6688c2ecf20Sopenharmony_ci case 'F' : case 'f': 6698c2ecf20Sopenharmony_ci if (sanity) 6708c2ecf20Sopenharmony_ci return 0; 6718c2ecf20Sopenharmony_ci sanity = 1; 6728c2ecf20Sopenharmony_ci break; 6738c2ecf20Sopenharmony_ci case 'P' : case 'p': 6748c2ecf20Sopenharmony_ci if (poison) 6758c2ecf20Sopenharmony_ci return 0; 6768c2ecf20Sopenharmony_ci poison = 1; 6778c2ecf20Sopenharmony_ci break; 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci case 'Z' : case 'z': 6808c2ecf20Sopenharmony_ci if (redzone) 6818c2ecf20Sopenharmony_ci return 0; 6828c2ecf20Sopenharmony_ci redzone = 1; 6838c2ecf20Sopenharmony_ci break; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci case 'U' : case 'u': 6868c2ecf20Sopenharmony_ci if (tracking) 6878c2ecf20Sopenharmony_ci return 0; 6888c2ecf20Sopenharmony_ci tracking = 1; 6898c2ecf20Sopenharmony_ci break; 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci case 'T' : case 't': 6928c2ecf20Sopenharmony_ci if (tracing) 6938c2ecf20Sopenharmony_ci return 0; 6948c2ecf20Sopenharmony_ci tracing = 1; 6958c2ecf20Sopenharmony_ci break; 6968c2ecf20Sopenharmony_ci default: 6978c2ecf20Sopenharmony_ci return 0; 6988c2ecf20Sopenharmony_ci } 6998c2ecf20Sopenharmony_ci return 1; 7008c2ecf20Sopenharmony_ci} 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_cistatic int slab_empty(struct slabinfo *s) 7038c2ecf20Sopenharmony_ci{ 7048c2ecf20Sopenharmony_ci if (s->objects > 0) 7058c2ecf20Sopenharmony_ci return 0; 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci /* 7088c2ecf20Sopenharmony_ci * We may still have slabs even if there are no objects. Shrinking will 7098c2ecf20Sopenharmony_ci * remove them. 7108c2ecf20Sopenharmony_ci */ 7118c2ecf20Sopenharmony_ci if (s->slabs != 0) 7128c2ecf20Sopenharmony_ci set_obj(s, "shrink", 1); 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci return 1; 7158c2ecf20Sopenharmony_ci} 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_cistatic void slab_debug(struct slabinfo *s) 7188c2ecf20Sopenharmony_ci{ 7198c2ecf20Sopenharmony_ci if (strcmp(s->name, "*") == 0) 7208c2ecf20Sopenharmony_ci return; 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci if (sanity && !s->sanity_checks) { 7238c2ecf20Sopenharmony_ci set_obj(s, "sanity_checks", 1); 7248c2ecf20Sopenharmony_ci } 7258c2ecf20Sopenharmony_ci if (!sanity && s->sanity_checks) { 7268c2ecf20Sopenharmony_ci if (slab_empty(s)) 7278c2ecf20Sopenharmony_ci set_obj(s, "sanity_checks", 0); 7288c2ecf20Sopenharmony_ci else 7298c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name); 7308c2ecf20Sopenharmony_ci } 7318c2ecf20Sopenharmony_ci if (redzone && !s->red_zone) { 7328c2ecf20Sopenharmony_ci if (slab_empty(s)) 7338c2ecf20Sopenharmony_ci set_obj(s, "red_zone", 1); 7348c2ecf20Sopenharmony_ci else 7358c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name); 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci if (!redzone && s->red_zone) { 7388c2ecf20Sopenharmony_ci if (slab_empty(s)) 7398c2ecf20Sopenharmony_ci set_obj(s, "red_zone", 0); 7408c2ecf20Sopenharmony_ci else 7418c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name); 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci if (poison && !s->poison) { 7448c2ecf20Sopenharmony_ci if (slab_empty(s)) 7458c2ecf20Sopenharmony_ci set_obj(s, "poison", 1); 7468c2ecf20Sopenharmony_ci else 7478c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name); 7488c2ecf20Sopenharmony_ci } 7498c2ecf20Sopenharmony_ci if (!poison && s->poison) { 7508c2ecf20Sopenharmony_ci if (slab_empty(s)) 7518c2ecf20Sopenharmony_ci set_obj(s, "poison", 0); 7528c2ecf20Sopenharmony_ci else 7538c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name); 7548c2ecf20Sopenharmony_ci } 7558c2ecf20Sopenharmony_ci if (tracking && !s->store_user) { 7568c2ecf20Sopenharmony_ci if (slab_empty(s)) 7578c2ecf20Sopenharmony_ci set_obj(s, "store_user", 1); 7588c2ecf20Sopenharmony_ci else 7598c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot enable tracking\n", s->name); 7608c2ecf20Sopenharmony_ci } 7618c2ecf20Sopenharmony_ci if (!tracking && s->store_user) { 7628c2ecf20Sopenharmony_ci if (slab_empty(s)) 7638c2ecf20Sopenharmony_ci set_obj(s, "store_user", 0); 7648c2ecf20Sopenharmony_ci else 7658c2ecf20Sopenharmony_ci fprintf(stderr, "%s not empty cannot disable tracking\n", s->name); 7668c2ecf20Sopenharmony_ci } 7678c2ecf20Sopenharmony_ci if (tracing && !s->trace) { 7688c2ecf20Sopenharmony_ci if (slabs == 1) 7698c2ecf20Sopenharmony_ci set_obj(s, "trace", 1); 7708c2ecf20Sopenharmony_ci else 7718c2ecf20Sopenharmony_ci fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name); 7728c2ecf20Sopenharmony_ci } 7738c2ecf20Sopenharmony_ci if (!tracing && s->trace) 7748c2ecf20Sopenharmony_ci set_obj(s, "trace", 1); 7758c2ecf20Sopenharmony_ci} 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_cistatic void totals(void) 7788c2ecf20Sopenharmony_ci{ 7798c2ecf20Sopenharmony_ci struct slabinfo *s; 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci int used_slabs = 0; 7828c2ecf20Sopenharmony_ci char b1[20], b2[20], b3[20], b4[20]; 7838c2ecf20Sopenharmony_ci unsigned long long max = 1ULL << 63; 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci /* Object size */ 7868c2ecf20Sopenharmony_ci unsigned long long min_objsize = max, max_objsize = 0, avg_objsize; 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci /* Number of partial slabs in a slabcache */ 7898c2ecf20Sopenharmony_ci unsigned long long min_partial = max, max_partial = 0, 7908c2ecf20Sopenharmony_ci avg_partial, total_partial = 0; 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci /* Number of slabs in a slab cache */ 7938c2ecf20Sopenharmony_ci unsigned long long min_slabs = max, max_slabs = 0, 7948c2ecf20Sopenharmony_ci avg_slabs, total_slabs = 0; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci /* Size of the whole slab */ 7978c2ecf20Sopenharmony_ci unsigned long long min_size = max, max_size = 0, 7988c2ecf20Sopenharmony_ci avg_size, total_size = 0; 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci /* Bytes used for object storage in a slab */ 8018c2ecf20Sopenharmony_ci unsigned long long min_used = max, max_used = 0, 8028c2ecf20Sopenharmony_ci avg_used, total_used = 0; 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci /* Waste: Bytes used for alignment and padding */ 8058c2ecf20Sopenharmony_ci unsigned long long min_waste = max, max_waste = 0, 8068c2ecf20Sopenharmony_ci avg_waste, total_waste = 0; 8078c2ecf20Sopenharmony_ci /* Number of objects in a slab */ 8088c2ecf20Sopenharmony_ci unsigned long long min_objects = max, max_objects = 0, 8098c2ecf20Sopenharmony_ci avg_objects, total_objects = 0; 8108c2ecf20Sopenharmony_ci /* Waste per object */ 8118c2ecf20Sopenharmony_ci unsigned long long min_objwaste = max, 8128c2ecf20Sopenharmony_ci max_objwaste = 0, avg_objwaste, 8138c2ecf20Sopenharmony_ci total_objwaste = 0; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci /* Memory per object */ 8168c2ecf20Sopenharmony_ci unsigned long long min_memobj = max, 8178c2ecf20Sopenharmony_ci max_memobj = 0, avg_memobj, 8188c2ecf20Sopenharmony_ci total_objsize = 0; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci /* Percentage of partial slabs per slab */ 8218c2ecf20Sopenharmony_ci unsigned long min_ppart = 100, max_ppart = 0, 8228c2ecf20Sopenharmony_ci avg_ppart, total_ppart = 0; 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci /* Number of objects in partial slabs */ 8258c2ecf20Sopenharmony_ci unsigned long min_partobj = max, max_partobj = 0, 8268c2ecf20Sopenharmony_ci avg_partobj, total_partobj = 0; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci /* Percentage of partial objects of all objects in a slab */ 8298c2ecf20Sopenharmony_ci unsigned long min_ppartobj = 100, max_ppartobj = 0, 8308c2ecf20Sopenharmony_ci avg_ppartobj, total_ppartobj = 0; 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci for (s = slabinfo; s < slabinfo + slabs; s++) { 8348c2ecf20Sopenharmony_ci unsigned long long size; 8358c2ecf20Sopenharmony_ci unsigned long used; 8368c2ecf20Sopenharmony_ci unsigned long long wasted; 8378c2ecf20Sopenharmony_ci unsigned long long objwaste; 8388c2ecf20Sopenharmony_ci unsigned long percentage_partial_slabs; 8398c2ecf20Sopenharmony_ci unsigned long percentage_partial_objs; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci if (!s->slabs || !s->objects) 8428c2ecf20Sopenharmony_ci continue; 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci used_slabs++; 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci size = slab_size(s); 8478c2ecf20Sopenharmony_ci used = s->objects * s->object_size; 8488c2ecf20Sopenharmony_ci wasted = size - used; 8498c2ecf20Sopenharmony_ci objwaste = s->slab_size - s->object_size; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci percentage_partial_slabs = s->partial * 100 / s->slabs; 8528c2ecf20Sopenharmony_ci if (percentage_partial_slabs > 100) 8538c2ecf20Sopenharmony_ci percentage_partial_slabs = 100; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci percentage_partial_objs = s->objects_partial * 100 8568c2ecf20Sopenharmony_ci / s->objects; 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci if (percentage_partial_objs > 100) 8598c2ecf20Sopenharmony_ci percentage_partial_objs = 100; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci if (s->object_size < min_objsize) 8628c2ecf20Sopenharmony_ci min_objsize = s->object_size; 8638c2ecf20Sopenharmony_ci if (s->partial < min_partial) 8648c2ecf20Sopenharmony_ci min_partial = s->partial; 8658c2ecf20Sopenharmony_ci if (s->slabs < min_slabs) 8668c2ecf20Sopenharmony_ci min_slabs = s->slabs; 8678c2ecf20Sopenharmony_ci if (size < min_size) 8688c2ecf20Sopenharmony_ci min_size = size; 8698c2ecf20Sopenharmony_ci if (wasted < min_waste) 8708c2ecf20Sopenharmony_ci min_waste = wasted; 8718c2ecf20Sopenharmony_ci if (objwaste < min_objwaste) 8728c2ecf20Sopenharmony_ci min_objwaste = objwaste; 8738c2ecf20Sopenharmony_ci if (s->objects < min_objects) 8748c2ecf20Sopenharmony_ci min_objects = s->objects; 8758c2ecf20Sopenharmony_ci if (used < min_used) 8768c2ecf20Sopenharmony_ci min_used = used; 8778c2ecf20Sopenharmony_ci if (s->objects_partial < min_partobj) 8788c2ecf20Sopenharmony_ci min_partobj = s->objects_partial; 8798c2ecf20Sopenharmony_ci if (percentage_partial_slabs < min_ppart) 8808c2ecf20Sopenharmony_ci min_ppart = percentage_partial_slabs; 8818c2ecf20Sopenharmony_ci if (percentage_partial_objs < min_ppartobj) 8828c2ecf20Sopenharmony_ci min_ppartobj = percentage_partial_objs; 8838c2ecf20Sopenharmony_ci if (s->slab_size < min_memobj) 8848c2ecf20Sopenharmony_ci min_memobj = s->slab_size; 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci if (s->object_size > max_objsize) 8878c2ecf20Sopenharmony_ci max_objsize = s->object_size; 8888c2ecf20Sopenharmony_ci if (s->partial > max_partial) 8898c2ecf20Sopenharmony_ci max_partial = s->partial; 8908c2ecf20Sopenharmony_ci if (s->slabs > max_slabs) 8918c2ecf20Sopenharmony_ci max_slabs = s->slabs; 8928c2ecf20Sopenharmony_ci if (size > max_size) 8938c2ecf20Sopenharmony_ci max_size = size; 8948c2ecf20Sopenharmony_ci if (wasted > max_waste) 8958c2ecf20Sopenharmony_ci max_waste = wasted; 8968c2ecf20Sopenharmony_ci if (objwaste > max_objwaste) 8978c2ecf20Sopenharmony_ci max_objwaste = objwaste; 8988c2ecf20Sopenharmony_ci if (s->objects > max_objects) 8998c2ecf20Sopenharmony_ci max_objects = s->objects; 9008c2ecf20Sopenharmony_ci if (used > max_used) 9018c2ecf20Sopenharmony_ci max_used = used; 9028c2ecf20Sopenharmony_ci if (s->objects_partial > max_partobj) 9038c2ecf20Sopenharmony_ci max_partobj = s->objects_partial; 9048c2ecf20Sopenharmony_ci if (percentage_partial_slabs > max_ppart) 9058c2ecf20Sopenharmony_ci max_ppart = percentage_partial_slabs; 9068c2ecf20Sopenharmony_ci if (percentage_partial_objs > max_ppartobj) 9078c2ecf20Sopenharmony_ci max_ppartobj = percentage_partial_objs; 9088c2ecf20Sopenharmony_ci if (s->slab_size > max_memobj) 9098c2ecf20Sopenharmony_ci max_memobj = s->slab_size; 9108c2ecf20Sopenharmony_ci 9118c2ecf20Sopenharmony_ci total_partial += s->partial; 9128c2ecf20Sopenharmony_ci total_slabs += s->slabs; 9138c2ecf20Sopenharmony_ci total_size += size; 9148c2ecf20Sopenharmony_ci total_waste += wasted; 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_ci total_objects += s->objects; 9178c2ecf20Sopenharmony_ci total_used += used; 9188c2ecf20Sopenharmony_ci total_partobj += s->objects_partial; 9198c2ecf20Sopenharmony_ci total_ppart += percentage_partial_slabs; 9208c2ecf20Sopenharmony_ci total_ppartobj += percentage_partial_objs; 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci total_objwaste += s->objects * objwaste; 9238c2ecf20Sopenharmony_ci total_objsize += s->objects * s->slab_size; 9248c2ecf20Sopenharmony_ci } 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci if (!total_objects) { 9278c2ecf20Sopenharmony_ci printf("No objects\n"); 9288c2ecf20Sopenharmony_ci return; 9298c2ecf20Sopenharmony_ci } 9308c2ecf20Sopenharmony_ci if (!used_slabs) { 9318c2ecf20Sopenharmony_ci printf("No slabs\n"); 9328c2ecf20Sopenharmony_ci return; 9338c2ecf20Sopenharmony_ci } 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci /* Per slab averages */ 9368c2ecf20Sopenharmony_ci avg_partial = total_partial / used_slabs; 9378c2ecf20Sopenharmony_ci avg_slabs = total_slabs / used_slabs; 9388c2ecf20Sopenharmony_ci avg_size = total_size / used_slabs; 9398c2ecf20Sopenharmony_ci avg_waste = total_waste / used_slabs; 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci avg_objects = total_objects / used_slabs; 9428c2ecf20Sopenharmony_ci avg_used = total_used / used_slabs; 9438c2ecf20Sopenharmony_ci avg_partobj = total_partobj / used_slabs; 9448c2ecf20Sopenharmony_ci avg_ppart = total_ppart / used_slabs; 9458c2ecf20Sopenharmony_ci avg_ppartobj = total_ppartobj / used_slabs; 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_ci /* Per object object sizes */ 9488c2ecf20Sopenharmony_ci avg_objsize = total_used / total_objects; 9498c2ecf20Sopenharmony_ci avg_objwaste = total_objwaste / total_objects; 9508c2ecf20Sopenharmony_ci avg_partobj = total_partobj * 100 / total_objects; 9518c2ecf20Sopenharmony_ci avg_memobj = total_objsize / total_objects; 9528c2ecf20Sopenharmony_ci 9538c2ecf20Sopenharmony_ci printf("Slabcache Totals\n"); 9548c2ecf20Sopenharmony_ci printf("----------------\n"); 9558c2ecf20Sopenharmony_ci printf("Slabcaches : %15d Aliases : %11d->%-3d Active: %3d\n", 9568c2ecf20Sopenharmony_ci slabs, aliases, alias_targets, used_slabs); 9578c2ecf20Sopenharmony_ci 9588c2ecf20Sopenharmony_ci store_size(b1, total_size);store_size(b2, total_waste); 9598c2ecf20Sopenharmony_ci store_size(b3, total_waste * 100 / total_used); 9608c2ecf20Sopenharmony_ci printf("Memory used: %15s # Loss : %15s MRatio:%6s%%\n", b1, b2, b3); 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci store_size(b1, total_objects);store_size(b2, total_partobj); 9638c2ecf20Sopenharmony_ci store_size(b3, total_partobj * 100 / total_objects); 9648c2ecf20Sopenharmony_ci printf("# Objects : %15s # PartObj: %15s ORatio:%6s%%\n", b1, b2, b3); 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci printf("\n"); 9678c2ecf20Sopenharmony_ci printf("Per Cache Average " 9688c2ecf20Sopenharmony_ci "Min Max Total\n"); 9698c2ecf20Sopenharmony_ci printf("---------------------------------------" 9708c2ecf20Sopenharmony_ci "-------------------------------------\n"); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci store_size(b1, avg_objects);store_size(b2, min_objects); 9738c2ecf20Sopenharmony_ci store_size(b3, max_objects);store_size(b4, total_objects); 9748c2ecf20Sopenharmony_ci printf("#Objects %15s %15s %15s %15s\n", 9758c2ecf20Sopenharmony_ci b1, b2, b3, b4); 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci store_size(b1, avg_slabs);store_size(b2, min_slabs); 9788c2ecf20Sopenharmony_ci store_size(b3, max_slabs);store_size(b4, total_slabs); 9798c2ecf20Sopenharmony_ci printf("#Slabs %15s %15s %15s %15s\n", 9808c2ecf20Sopenharmony_ci b1, b2, b3, b4); 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci store_size(b1, avg_partial);store_size(b2, min_partial); 9838c2ecf20Sopenharmony_ci store_size(b3, max_partial);store_size(b4, total_partial); 9848c2ecf20Sopenharmony_ci printf("#PartSlab %15s %15s %15s %15s\n", 9858c2ecf20Sopenharmony_ci b1, b2, b3, b4); 9868c2ecf20Sopenharmony_ci store_size(b1, avg_ppart);store_size(b2, min_ppart); 9878c2ecf20Sopenharmony_ci store_size(b3, max_ppart); 9888c2ecf20Sopenharmony_ci store_size(b4, total_partial * 100 / total_slabs); 9898c2ecf20Sopenharmony_ci printf("%%PartSlab%15s%% %15s%% %15s%% %15s%%\n", 9908c2ecf20Sopenharmony_ci b1, b2, b3, b4); 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci store_size(b1, avg_partobj);store_size(b2, min_partobj); 9938c2ecf20Sopenharmony_ci store_size(b3, max_partobj); 9948c2ecf20Sopenharmony_ci store_size(b4, total_partobj); 9958c2ecf20Sopenharmony_ci printf("PartObjs %15s %15s %15s %15s\n", 9968c2ecf20Sopenharmony_ci b1, b2, b3, b4); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj); 9998c2ecf20Sopenharmony_ci store_size(b3, max_ppartobj); 10008c2ecf20Sopenharmony_ci store_size(b4, total_partobj * 100 / total_objects); 10018c2ecf20Sopenharmony_ci printf("%% PartObj%15s%% %15s%% %15s%% %15s%%\n", 10028c2ecf20Sopenharmony_ci b1, b2, b3, b4); 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci store_size(b1, avg_size);store_size(b2, min_size); 10058c2ecf20Sopenharmony_ci store_size(b3, max_size);store_size(b4, total_size); 10068c2ecf20Sopenharmony_ci printf("Memory %15s %15s %15s %15s\n", 10078c2ecf20Sopenharmony_ci b1, b2, b3, b4); 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci store_size(b1, avg_used);store_size(b2, min_used); 10108c2ecf20Sopenharmony_ci store_size(b3, max_used);store_size(b4, total_used); 10118c2ecf20Sopenharmony_ci printf("Used %15s %15s %15s %15s\n", 10128c2ecf20Sopenharmony_ci b1, b2, b3, b4); 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci store_size(b1, avg_waste);store_size(b2, min_waste); 10158c2ecf20Sopenharmony_ci store_size(b3, max_waste);store_size(b4, total_waste); 10168c2ecf20Sopenharmony_ci printf("Loss %15s %15s %15s %15s\n", 10178c2ecf20Sopenharmony_ci b1, b2, b3, b4); 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_ci printf("\n"); 10208c2ecf20Sopenharmony_ci printf("Per Object Average " 10218c2ecf20Sopenharmony_ci "Min Max\n"); 10228c2ecf20Sopenharmony_ci printf("---------------------------------------" 10238c2ecf20Sopenharmony_ci "--------------------\n"); 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci store_size(b1, avg_memobj);store_size(b2, min_memobj); 10268c2ecf20Sopenharmony_ci store_size(b3, max_memobj); 10278c2ecf20Sopenharmony_ci printf("Memory %15s %15s %15s\n", 10288c2ecf20Sopenharmony_ci b1, b2, b3); 10298c2ecf20Sopenharmony_ci store_size(b1, avg_objsize);store_size(b2, min_objsize); 10308c2ecf20Sopenharmony_ci store_size(b3, max_objsize); 10318c2ecf20Sopenharmony_ci printf("User %15s %15s %15s\n", 10328c2ecf20Sopenharmony_ci b1, b2, b3); 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci store_size(b1, avg_objwaste);store_size(b2, min_objwaste); 10358c2ecf20Sopenharmony_ci store_size(b3, max_objwaste); 10368c2ecf20Sopenharmony_ci printf("Loss %15s %15s %15s\n", 10378c2ecf20Sopenharmony_ci b1, b2, b3); 10388c2ecf20Sopenharmony_ci} 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_cistatic void sort_slabs(void) 10418c2ecf20Sopenharmony_ci{ 10428c2ecf20Sopenharmony_ci struct slabinfo *s1,*s2; 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) { 10458c2ecf20Sopenharmony_ci for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) { 10468c2ecf20Sopenharmony_ci int result; 10478c2ecf20Sopenharmony_ci 10488c2ecf20Sopenharmony_ci if (sort_size) { 10498c2ecf20Sopenharmony_ci if (slab_size(s1) == slab_size(s2)) 10508c2ecf20Sopenharmony_ci result = strcasecmp(s1->name, s2->name); 10518c2ecf20Sopenharmony_ci else 10528c2ecf20Sopenharmony_ci result = slab_size(s1) < slab_size(s2); 10538c2ecf20Sopenharmony_ci } else if (sort_active) { 10548c2ecf20Sopenharmony_ci if (slab_activity(s1) == slab_activity(s2)) 10558c2ecf20Sopenharmony_ci result = strcasecmp(s1->name, s2->name); 10568c2ecf20Sopenharmony_ci else 10578c2ecf20Sopenharmony_ci result = slab_activity(s1) < slab_activity(s2); 10588c2ecf20Sopenharmony_ci } else if (sort_loss) { 10598c2ecf20Sopenharmony_ci if (slab_waste(s1) == slab_waste(s2)) 10608c2ecf20Sopenharmony_ci result = strcasecmp(s1->name, s2->name); 10618c2ecf20Sopenharmony_ci else 10628c2ecf20Sopenharmony_ci result = slab_waste(s1) < slab_waste(s2); 10638c2ecf20Sopenharmony_ci } else if (sort_partial) { 10648c2ecf20Sopenharmony_ci if (s1->partial == s2->partial) 10658c2ecf20Sopenharmony_ci result = strcasecmp(s1->name, s2->name); 10668c2ecf20Sopenharmony_ci else 10678c2ecf20Sopenharmony_ci result = s1->partial < s2->partial; 10688c2ecf20Sopenharmony_ci } else 10698c2ecf20Sopenharmony_ci result = strcasecmp(s1->name, s2->name); 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci if (show_inverted) 10728c2ecf20Sopenharmony_ci result = -result; 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_ci if (result > 0) { 10758c2ecf20Sopenharmony_ci struct slabinfo t; 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ci memcpy(&t, s1, sizeof(struct slabinfo)); 10788c2ecf20Sopenharmony_ci memcpy(s1, s2, sizeof(struct slabinfo)); 10798c2ecf20Sopenharmony_ci memcpy(s2, &t, sizeof(struct slabinfo)); 10808c2ecf20Sopenharmony_ci } 10818c2ecf20Sopenharmony_ci } 10828c2ecf20Sopenharmony_ci } 10838c2ecf20Sopenharmony_ci} 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_cistatic void sort_aliases(void) 10868c2ecf20Sopenharmony_ci{ 10878c2ecf20Sopenharmony_ci struct aliasinfo *a1,*a2; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) { 10908c2ecf20Sopenharmony_ci for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) { 10918c2ecf20Sopenharmony_ci char *n1, *n2; 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci n1 = a1->name; 10948c2ecf20Sopenharmony_ci n2 = a2->name; 10958c2ecf20Sopenharmony_ci if (show_alias && !show_inverted) { 10968c2ecf20Sopenharmony_ci n1 = a1->ref; 10978c2ecf20Sopenharmony_ci n2 = a2->ref; 10988c2ecf20Sopenharmony_ci } 10998c2ecf20Sopenharmony_ci if (strcasecmp(n1, n2) > 0) { 11008c2ecf20Sopenharmony_ci struct aliasinfo t; 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci memcpy(&t, a1, sizeof(struct aliasinfo)); 11038c2ecf20Sopenharmony_ci memcpy(a1, a2, sizeof(struct aliasinfo)); 11048c2ecf20Sopenharmony_ci memcpy(a2, &t, sizeof(struct aliasinfo)); 11058c2ecf20Sopenharmony_ci } 11068c2ecf20Sopenharmony_ci } 11078c2ecf20Sopenharmony_ci } 11088c2ecf20Sopenharmony_ci} 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistatic void link_slabs(void) 11118c2ecf20Sopenharmony_ci{ 11128c2ecf20Sopenharmony_ci struct aliasinfo *a; 11138c2ecf20Sopenharmony_ci struct slabinfo *s; 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_ci for (a = aliasinfo; a < aliasinfo + aliases; a++) { 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci for (s = slabinfo; s < slabinfo + slabs; s++) 11188c2ecf20Sopenharmony_ci if (strcmp(a->ref, s->name) == 0) { 11198c2ecf20Sopenharmony_ci a->slab = s; 11208c2ecf20Sopenharmony_ci s->refs++; 11218c2ecf20Sopenharmony_ci break; 11228c2ecf20Sopenharmony_ci } 11238c2ecf20Sopenharmony_ci if (s == slabinfo + slabs) 11248c2ecf20Sopenharmony_ci fatal("Unresolved alias %s\n", a->ref); 11258c2ecf20Sopenharmony_ci } 11268c2ecf20Sopenharmony_ci} 11278c2ecf20Sopenharmony_ci 11288c2ecf20Sopenharmony_cistatic void alias(void) 11298c2ecf20Sopenharmony_ci{ 11308c2ecf20Sopenharmony_ci struct aliasinfo *a; 11318c2ecf20Sopenharmony_ci char *active = NULL; 11328c2ecf20Sopenharmony_ci 11338c2ecf20Sopenharmony_ci sort_aliases(); 11348c2ecf20Sopenharmony_ci link_slabs(); 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci for(a = aliasinfo; a < aliasinfo + aliases; a++) { 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci if (!show_single_ref && a->slab->refs == 1) 11398c2ecf20Sopenharmony_ci continue; 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci if (!show_inverted) { 11428c2ecf20Sopenharmony_ci if (active) { 11438c2ecf20Sopenharmony_ci if (strcmp(a->slab->name, active) == 0) { 11448c2ecf20Sopenharmony_ci printf(" %s", a->name); 11458c2ecf20Sopenharmony_ci continue; 11468c2ecf20Sopenharmony_ci } 11478c2ecf20Sopenharmony_ci } 11488c2ecf20Sopenharmony_ci printf("\n%-12s <- %s", a->slab->name, a->name); 11498c2ecf20Sopenharmony_ci active = a->slab->name; 11508c2ecf20Sopenharmony_ci } 11518c2ecf20Sopenharmony_ci else 11528c2ecf20Sopenharmony_ci printf("%-15s -> %s\n", a->name, a->slab->name); 11538c2ecf20Sopenharmony_ci } 11548c2ecf20Sopenharmony_ci if (active) 11558c2ecf20Sopenharmony_ci printf("\n"); 11568c2ecf20Sopenharmony_ci} 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_cistatic void rename_slabs(void) 11608c2ecf20Sopenharmony_ci{ 11618c2ecf20Sopenharmony_ci struct slabinfo *s; 11628c2ecf20Sopenharmony_ci struct aliasinfo *a; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci for (s = slabinfo; s < slabinfo + slabs; s++) { 11658c2ecf20Sopenharmony_ci if (*s->name != ':') 11668c2ecf20Sopenharmony_ci continue; 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci if (s->refs > 1 && !show_first_alias) 11698c2ecf20Sopenharmony_ci continue; 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci a = find_one_alias(s); 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci if (a) 11748c2ecf20Sopenharmony_ci s->name = a->name; 11758c2ecf20Sopenharmony_ci else { 11768c2ecf20Sopenharmony_ci s->name = "*"; 11778c2ecf20Sopenharmony_ci actual_slabs--; 11788c2ecf20Sopenharmony_ci } 11798c2ecf20Sopenharmony_ci } 11808c2ecf20Sopenharmony_ci} 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_cistatic int slab_mismatch(char *slab) 11838c2ecf20Sopenharmony_ci{ 11848c2ecf20Sopenharmony_ci return regexec(&pattern, slab, 0, NULL, 0); 11858c2ecf20Sopenharmony_ci} 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_cistatic void read_slab_dir(void) 11888c2ecf20Sopenharmony_ci{ 11898c2ecf20Sopenharmony_ci DIR *dir; 11908c2ecf20Sopenharmony_ci struct dirent *de; 11918c2ecf20Sopenharmony_ci struct slabinfo *slab = slabinfo; 11928c2ecf20Sopenharmony_ci struct aliasinfo *alias = aliasinfo; 11938c2ecf20Sopenharmony_ci char *p; 11948c2ecf20Sopenharmony_ci char *t; 11958c2ecf20Sopenharmony_ci int count; 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ci if (chdir("/sys/kernel/slab") && chdir("/sys/slab")) 11988c2ecf20Sopenharmony_ci fatal("SYSFS support for SLUB not active\n"); 11998c2ecf20Sopenharmony_ci 12008c2ecf20Sopenharmony_ci dir = opendir("."); 12018c2ecf20Sopenharmony_ci while ((de = readdir(dir))) { 12028c2ecf20Sopenharmony_ci if (de->d_name[0] == '.' || 12038c2ecf20Sopenharmony_ci (de->d_name[0] != ':' && slab_mismatch(de->d_name))) 12048c2ecf20Sopenharmony_ci continue; 12058c2ecf20Sopenharmony_ci switch (de->d_type) { 12068c2ecf20Sopenharmony_ci case DT_LNK: 12078c2ecf20Sopenharmony_ci alias->name = strdup(de->d_name); 12088c2ecf20Sopenharmony_ci count = readlink(de->d_name, buffer, sizeof(buffer)-1); 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci if (count < 0) 12118c2ecf20Sopenharmony_ci fatal("Cannot read symlink %s\n", de->d_name); 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci buffer[count] = 0; 12148c2ecf20Sopenharmony_ci p = buffer + count; 12158c2ecf20Sopenharmony_ci while (p > buffer && p[-1] != '/') 12168c2ecf20Sopenharmony_ci p--; 12178c2ecf20Sopenharmony_ci alias->ref = strdup(p); 12188c2ecf20Sopenharmony_ci alias++; 12198c2ecf20Sopenharmony_ci break; 12208c2ecf20Sopenharmony_ci case DT_DIR: 12218c2ecf20Sopenharmony_ci if (chdir(de->d_name)) 12228c2ecf20Sopenharmony_ci fatal("Unable to access slab %s\n", slab->name); 12238c2ecf20Sopenharmony_ci slab->name = strdup(de->d_name); 12248c2ecf20Sopenharmony_ci slab->alias = 0; 12258c2ecf20Sopenharmony_ci slab->refs = 0; 12268c2ecf20Sopenharmony_ci slab->aliases = get_obj("aliases"); 12278c2ecf20Sopenharmony_ci slab->align = get_obj("align"); 12288c2ecf20Sopenharmony_ci slab->cache_dma = get_obj("cache_dma"); 12298c2ecf20Sopenharmony_ci slab->cpu_slabs = get_obj("cpu_slabs"); 12308c2ecf20Sopenharmony_ci slab->destroy_by_rcu = get_obj("destroy_by_rcu"); 12318c2ecf20Sopenharmony_ci slab->hwcache_align = get_obj("hwcache_align"); 12328c2ecf20Sopenharmony_ci slab->object_size = get_obj("object_size"); 12338c2ecf20Sopenharmony_ci slab->objects = get_obj("objects"); 12348c2ecf20Sopenharmony_ci slab->objects_partial = get_obj("objects_partial"); 12358c2ecf20Sopenharmony_ci slab->objects_total = get_obj("objects_total"); 12368c2ecf20Sopenharmony_ci slab->objs_per_slab = get_obj("objs_per_slab"); 12378c2ecf20Sopenharmony_ci slab->order = get_obj("order"); 12388c2ecf20Sopenharmony_ci slab->partial = get_obj("partial"); 12398c2ecf20Sopenharmony_ci slab->partial = get_obj_and_str("partial", &t); 12408c2ecf20Sopenharmony_ci decode_numa_list(slab->numa_partial, t); 12418c2ecf20Sopenharmony_ci free(t); 12428c2ecf20Sopenharmony_ci slab->poison = get_obj("poison"); 12438c2ecf20Sopenharmony_ci slab->reclaim_account = get_obj("reclaim_account"); 12448c2ecf20Sopenharmony_ci slab->red_zone = get_obj("red_zone"); 12458c2ecf20Sopenharmony_ci slab->sanity_checks = get_obj("sanity_checks"); 12468c2ecf20Sopenharmony_ci slab->slab_size = get_obj("slab_size"); 12478c2ecf20Sopenharmony_ci slab->slabs = get_obj_and_str("slabs", &t); 12488c2ecf20Sopenharmony_ci decode_numa_list(slab->numa, t); 12498c2ecf20Sopenharmony_ci free(t); 12508c2ecf20Sopenharmony_ci slab->store_user = get_obj("store_user"); 12518c2ecf20Sopenharmony_ci slab->trace = get_obj("trace"); 12528c2ecf20Sopenharmony_ci slab->alloc_fastpath = get_obj("alloc_fastpath"); 12538c2ecf20Sopenharmony_ci slab->alloc_slowpath = get_obj("alloc_slowpath"); 12548c2ecf20Sopenharmony_ci slab->free_fastpath = get_obj("free_fastpath"); 12558c2ecf20Sopenharmony_ci slab->free_slowpath = get_obj("free_slowpath"); 12568c2ecf20Sopenharmony_ci slab->free_frozen= get_obj("free_frozen"); 12578c2ecf20Sopenharmony_ci slab->free_add_partial = get_obj("free_add_partial"); 12588c2ecf20Sopenharmony_ci slab->free_remove_partial = get_obj("free_remove_partial"); 12598c2ecf20Sopenharmony_ci slab->alloc_from_partial = get_obj("alloc_from_partial"); 12608c2ecf20Sopenharmony_ci slab->alloc_slab = get_obj("alloc_slab"); 12618c2ecf20Sopenharmony_ci slab->alloc_refill = get_obj("alloc_refill"); 12628c2ecf20Sopenharmony_ci slab->free_slab = get_obj("free_slab"); 12638c2ecf20Sopenharmony_ci slab->cpuslab_flush = get_obj("cpuslab_flush"); 12648c2ecf20Sopenharmony_ci slab->deactivate_full = get_obj("deactivate_full"); 12658c2ecf20Sopenharmony_ci slab->deactivate_empty = get_obj("deactivate_empty"); 12668c2ecf20Sopenharmony_ci slab->deactivate_to_head = get_obj("deactivate_to_head"); 12678c2ecf20Sopenharmony_ci slab->deactivate_to_tail = get_obj("deactivate_to_tail"); 12688c2ecf20Sopenharmony_ci slab->deactivate_remote_frees = get_obj("deactivate_remote_frees"); 12698c2ecf20Sopenharmony_ci slab->order_fallback = get_obj("order_fallback"); 12708c2ecf20Sopenharmony_ci slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail"); 12718c2ecf20Sopenharmony_ci slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail"); 12728c2ecf20Sopenharmony_ci slab->cpu_partial_alloc = get_obj("cpu_partial_alloc"); 12738c2ecf20Sopenharmony_ci slab->cpu_partial_free = get_obj("cpu_partial_free"); 12748c2ecf20Sopenharmony_ci slab->alloc_node_mismatch = get_obj("alloc_node_mismatch"); 12758c2ecf20Sopenharmony_ci slab->deactivate_bypass = get_obj("deactivate_bypass"); 12768c2ecf20Sopenharmony_ci chdir(".."); 12778c2ecf20Sopenharmony_ci if (slab->name[0] == ':') 12788c2ecf20Sopenharmony_ci alias_targets++; 12798c2ecf20Sopenharmony_ci slab++; 12808c2ecf20Sopenharmony_ci break; 12818c2ecf20Sopenharmony_ci default : 12828c2ecf20Sopenharmony_ci fatal("Unknown file type %lx\n", de->d_type); 12838c2ecf20Sopenharmony_ci } 12848c2ecf20Sopenharmony_ci } 12858c2ecf20Sopenharmony_ci closedir(dir); 12868c2ecf20Sopenharmony_ci slabs = slab - slabinfo; 12878c2ecf20Sopenharmony_ci actual_slabs = slabs; 12888c2ecf20Sopenharmony_ci aliases = alias - aliasinfo; 12898c2ecf20Sopenharmony_ci if (slabs > MAX_SLABS) 12908c2ecf20Sopenharmony_ci fatal("Too many slabs\n"); 12918c2ecf20Sopenharmony_ci if (aliases > MAX_ALIASES) 12928c2ecf20Sopenharmony_ci fatal("Too many aliases\n"); 12938c2ecf20Sopenharmony_ci} 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_cistatic void output_slabs(void) 12968c2ecf20Sopenharmony_ci{ 12978c2ecf20Sopenharmony_ci struct slabinfo *slab; 12988c2ecf20Sopenharmony_ci int lines = output_lines; 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci for (slab = slabinfo; (slab < slabinfo + slabs) && 13018c2ecf20Sopenharmony_ci lines != 0; slab++) { 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci if (slab->alias) 13048c2ecf20Sopenharmony_ci continue; 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci if (lines != -1) 13078c2ecf20Sopenharmony_ci lines--; 13088c2ecf20Sopenharmony_ci 13098c2ecf20Sopenharmony_ci if (show_numa) 13108c2ecf20Sopenharmony_ci slab_numa(slab, 0); 13118c2ecf20Sopenharmony_ci else if (show_track) 13128c2ecf20Sopenharmony_ci show_tracking(slab); 13138c2ecf20Sopenharmony_ci else if (validate) 13148c2ecf20Sopenharmony_ci slab_validate(slab); 13158c2ecf20Sopenharmony_ci else if (shrink) 13168c2ecf20Sopenharmony_ci slab_shrink(slab); 13178c2ecf20Sopenharmony_ci else if (set_debug) 13188c2ecf20Sopenharmony_ci slab_debug(slab); 13198c2ecf20Sopenharmony_ci else if (show_ops) 13208c2ecf20Sopenharmony_ci ops(slab); 13218c2ecf20Sopenharmony_ci else if (show_slab) 13228c2ecf20Sopenharmony_ci slabcache(slab); 13238c2ecf20Sopenharmony_ci else if (show_report) 13248c2ecf20Sopenharmony_ci report(slab); 13258c2ecf20Sopenharmony_ci } 13268c2ecf20Sopenharmony_ci} 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_cistatic void _xtotals(char *heading, char *underline, 13298c2ecf20Sopenharmony_ci int loss, int size, int partial) 13308c2ecf20Sopenharmony_ci{ 13318c2ecf20Sopenharmony_ci printf("%s%s", heading, underline); 13328c2ecf20Sopenharmony_ci line = 0; 13338c2ecf20Sopenharmony_ci sort_loss = loss; 13348c2ecf20Sopenharmony_ci sort_size = size; 13358c2ecf20Sopenharmony_ci sort_partial = partial; 13368c2ecf20Sopenharmony_ci sort_slabs(); 13378c2ecf20Sopenharmony_ci output_slabs(); 13388c2ecf20Sopenharmony_ci} 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_cistatic void xtotals(void) 13418c2ecf20Sopenharmony_ci{ 13428c2ecf20Sopenharmony_ci char *heading, *underline; 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci totals(); 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci link_slabs(); 13478c2ecf20Sopenharmony_ci rename_slabs(); 13488c2ecf20Sopenharmony_ci 13498c2ecf20Sopenharmony_ci heading = "\nSlabs sorted by size\n"; 13508c2ecf20Sopenharmony_ci underline = "--------------------\n"; 13518c2ecf20Sopenharmony_ci _xtotals(heading, underline, 0, 1, 0); 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci heading = "\nSlabs sorted by loss\n"; 13548c2ecf20Sopenharmony_ci underline = "--------------------\n"; 13558c2ecf20Sopenharmony_ci _xtotals(heading, underline, 1, 0, 0); 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_ci heading = "\nSlabs sorted by number of partial slabs\n"; 13588c2ecf20Sopenharmony_ci underline = "---------------------------------------\n"; 13598c2ecf20Sopenharmony_ci _xtotals(heading, underline, 0, 0, 1); 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci printf("\n"); 13628c2ecf20Sopenharmony_ci} 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_cistruct option opts[] = { 13658c2ecf20Sopenharmony_ci { "aliases", no_argument, NULL, 'a' }, 13668c2ecf20Sopenharmony_ci { "activity", no_argument, NULL, 'A' }, 13678c2ecf20Sopenharmony_ci { "Bytes", no_argument, NULL, 'B'}, 13688c2ecf20Sopenharmony_ci { "debug", optional_argument, NULL, 'd' }, 13698c2ecf20Sopenharmony_ci { "display-activity", no_argument, NULL, 'D' }, 13708c2ecf20Sopenharmony_ci { "empty", no_argument, NULL, 'e' }, 13718c2ecf20Sopenharmony_ci { "first-alias", no_argument, NULL, 'f' }, 13728c2ecf20Sopenharmony_ci { "help", no_argument, NULL, 'h' }, 13738c2ecf20Sopenharmony_ci { "inverted", no_argument, NULL, 'i'}, 13748c2ecf20Sopenharmony_ci { "slabs", no_argument, NULL, 'l' }, 13758c2ecf20Sopenharmony_ci { "Loss", no_argument, NULL, 'L'}, 13768c2ecf20Sopenharmony_ci { "numa", no_argument, NULL, 'n' }, 13778c2ecf20Sopenharmony_ci { "lines", required_argument, NULL, 'N'}, 13788c2ecf20Sopenharmony_ci { "ops", no_argument, NULL, 'o' }, 13798c2ecf20Sopenharmony_ci { "partial", no_argument, NULL, 'p'}, 13808c2ecf20Sopenharmony_ci { "report", no_argument, NULL, 'r' }, 13818c2ecf20Sopenharmony_ci { "shrink", no_argument, NULL, 's' }, 13828c2ecf20Sopenharmony_ci { "Size", no_argument, NULL, 'S'}, 13838c2ecf20Sopenharmony_ci { "tracking", no_argument, NULL, 't'}, 13848c2ecf20Sopenharmony_ci { "Totals", no_argument, NULL, 'T'}, 13858c2ecf20Sopenharmony_ci { "Unreclaim", no_argument, NULL, 'U'}, 13868c2ecf20Sopenharmony_ci { "validate", no_argument, NULL, 'v' }, 13878c2ecf20Sopenharmony_ci { "Xtotals", no_argument, NULL, 'X'}, 13888c2ecf20Sopenharmony_ci { "zero", no_argument, NULL, 'z' }, 13898c2ecf20Sopenharmony_ci { "1ref", no_argument, NULL, '1'}, 13908c2ecf20Sopenharmony_ci { NULL, 0, NULL, 0 } 13918c2ecf20Sopenharmony_ci}; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ciint main(int argc, char *argv[]) 13948c2ecf20Sopenharmony_ci{ 13958c2ecf20Sopenharmony_ci int c; 13968c2ecf20Sopenharmony_ci int err; 13978c2ecf20Sopenharmony_ci char *pattern_source; 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci page_size = getpagesize(); 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci while ((c = getopt_long(argc, argv, "aABd::DefhilLnN:oPrsStTUvXz1", 14028c2ecf20Sopenharmony_ci opts, NULL)) != -1) 14038c2ecf20Sopenharmony_ci switch (c) { 14048c2ecf20Sopenharmony_ci case 'a': 14058c2ecf20Sopenharmony_ci show_alias = 1; 14068c2ecf20Sopenharmony_ci break; 14078c2ecf20Sopenharmony_ci case 'A': 14088c2ecf20Sopenharmony_ci sort_active = 1; 14098c2ecf20Sopenharmony_ci break; 14108c2ecf20Sopenharmony_ci case 'B': 14118c2ecf20Sopenharmony_ci show_bytes = 1; 14128c2ecf20Sopenharmony_ci break; 14138c2ecf20Sopenharmony_ci case 'd': 14148c2ecf20Sopenharmony_ci set_debug = 1; 14158c2ecf20Sopenharmony_ci if (!debug_opt_scan(optarg)) 14168c2ecf20Sopenharmony_ci fatal("Invalid debug option '%s'\n", optarg); 14178c2ecf20Sopenharmony_ci break; 14188c2ecf20Sopenharmony_ci case 'D': 14198c2ecf20Sopenharmony_ci show_activity = 1; 14208c2ecf20Sopenharmony_ci break; 14218c2ecf20Sopenharmony_ci case 'e': 14228c2ecf20Sopenharmony_ci show_empty = 1; 14238c2ecf20Sopenharmony_ci break; 14248c2ecf20Sopenharmony_ci case 'f': 14258c2ecf20Sopenharmony_ci show_first_alias = 1; 14268c2ecf20Sopenharmony_ci break; 14278c2ecf20Sopenharmony_ci case 'h': 14288c2ecf20Sopenharmony_ci usage(); 14298c2ecf20Sopenharmony_ci return 0; 14308c2ecf20Sopenharmony_ci case 'i': 14318c2ecf20Sopenharmony_ci show_inverted = 1; 14328c2ecf20Sopenharmony_ci break; 14338c2ecf20Sopenharmony_ci case 'l': 14348c2ecf20Sopenharmony_ci show_slab = 1; 14358c2ecf20Sopenharmony_ci break; 14368c2ecf20Sopenharmony_ci case 'L': 14378c2ecf20Sopenharmony_ci sort_loss = 1; 14388c2ecf20Sopenharmony_ci break; 14398c2ecf20Sopenharmony_ci case 'n': 14408c2ecf20Sopenharmony_ci show_numa = 1; 14418c2ecf20Sopenharmony_ci break; 14428c2ecf20Sopenharmony_ci case 'N': 14438c2ecf20Sopenharmony_ci if (optarg) { 14448c2ecf20Sopenharmony_ci output_lines = atoi(optarg); 14458c2ecf20Sopenharmony_ci if (output_lines < 1) 14468c2ecf20Sopenharmony_ci output_lines = 1; 14478c2ecf20Sopenharmony_ci } 14488c2ecf20Sopenharmony_ci break; 14498c2ecf20Sopenharmony_ci case 'o': 14508c2ecf20Sopenharmony_ci show_ops = 1; 14518c2ecf20Sopenharmony_ci break; 14528c2ecf20Sopenharmony_ci case 'r': 14538c2ecf20Sopenharmony_ci show_report = 1; 14548c2ecf20Sopenharmony_ci break; 14558c2ecf20Sopenharmony_ci case 'P': 14568c2ecf20Sopenharmony_ci sort_partial = 1; 14578c2ecf20Sopenharmony_ci break; 14588c2ecf20Sopenharmony_ci case 's': 14598c2ecf20Sopenharmony_ci shrink = 1; 14608c2ecf20Sopenharmony_ci break; 14618c2ecf20Sopenharmony_ci case 'S': 14628c2ecf20Sopenharmony_ci sort_size = 1; 14638c2ecf20Sopenharmony_ci break; 14648c2ecf20Sopenharmony_ci case 't': 14658c2ecf20Sopenharmony_ci show_track = 1; 14668c2ecf20Sopenharmony_ci break; 14678c2ecf20Sopenharmony_ci case 'T': 14688c2ecf20Sopenharmony_ci show_totals = 1; 14698c2ecf20Sopenharmony_ci break; 14708c2ecf20Sopenharmony_ci case 'U': 14718c2ecf20Sopenharmony_ci unreclaim_only = 1; 14728c2ecf20Sopenharmony_ci break; 14738c2ecf20Sopenharmony_ci case 'v': 14748c2ecf20Sopenharmony_ci validate = 1; 14758c2ecf20Sopenharmony_ci break; 14768c2ecf20Sopenharmony_ci case 'X': 14778c2ecf20Sopenharmony_ci if (output_lines == -1) 14788c2ecf20Sopenharmony_ci output_lines = 1; 14798c2ecf20Sopenharmony_ci extended_totals = 1; 14808c2ecf20Sopenharmony_ci show_bytes = 1; 14818c2ecf20Sopenharmony_ci break; 14828c2ecf20Sopenharmony_ci case 'z': 14838c2ecf20Sopenharmony_ci skip_zero = 0; 14848c2ecf20Sopenharmony_ci break; 14858c2ecf20Sopenharmony_ci case '1': 14868c2ecf20Sopenharmony_ci show_single_ref = 1; 14878c2ecf20Sopenharmony_ci break; 14888c2ecf20Sopenharmony_ci default: 14898c2ecf20Sopenharmony_ci fatal("%s: Invalid option '%c'\n", argv[0], optopt); 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci } 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci if (!show_slab && !show_alias && !show_track && !show_report 14948c2ecf20Sopenharmony_ci && !validate && !shrink && !set_debug && !show_ops) 14958c2ecf20Sopenharmony_ci show_slab = 1; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci if (argc > optind) 14988c2ecf20Sopenharmony_ci pattern_source = argv[optind]; 14998c2ecf20Sopenharmony_ci else 15008c2ecf20Sopenharmony_ci pattern_source = ".*"; 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB); 15038c2ecf20Sopenharmony_ci if (err) 15048c2ecf20Sopenharmony_ci fatal("%s: Invalid pattern '%s' code %d\n", 15058c2ecf20Sopenharmony_ci argv[0], pattern_source, err); 15068c2ecf20Sopenharmony_ci read_slab_dir(); 15078c2ecf20Sopenharmony_ci if (show_alias) { 15088c2ecf20Sopenharmony_ci alias(); 15098c2ecf20Sopenharmony_ci } else if (extended_totals) { 15108c2ecf20Sopenharmony_ci xtotals(); 15118c2ecf20Sopenharmony_ci } else if (show_totals) { 15128c2ecf20Sopenharmony_ci totals(); 15138c2ecf20Sopenharmony_ci } else { 15148c2ecf20Sopenharmony_ci link_slabs(); 15158c2ecf20Sopenharmony_ci rename_slabs(); 15168c2ecf20Sopenharmony_ci sort_slabs(); 15178c2ecf20Sopenharmony_ci output_slabs(); 15188c2ecf20Sopenharmony_ci } 15198c2ecf20Sopenharmony_ci return 0; 15208c2ecf20Sopenharmony_ci} 1521