2.1.22+ slab allocator statistics tool (kernel memory linux)
Ключевые слова: kernel, memory, linux, (найти похожие документы)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Boris Tobotras 2:5020/510 15 May 97 06:29:44
Subj : 2.1.22+ slab allocator statistics tool
________________________________________________________________________________
/* Slabinfo - peek into the slab allocator - By Aaron Tiensivu *
* Version 0.1 - [05/08/97] - Under GPL, standard disclaimers apply *
* *
* Usage: slabinfo [-a] *
* -a will also show empty slab catagories *
* *
* Could this be a perl script? Sure. *
* Why did I write it? Hack value and curiosity *
* Limited amount of error checking since this is a QuickHack(tm) *
* *
* Compile *
* For pgcc: *
* gcc -o slabinfo -s -O6 -frisc -mpentium slabinfo.c *
* *
* For GCC 2.7.2: *
* gcc -o slabinfo -s -O2 -m486 -fomit-frame-pointer slabinfo.c */
#ifdef __alpha__
#define PROC_SUPER_MAGIC ((short)0x9fa0)
#else
#define PROC_SUPER_MAGIC 0x9fa0
#endif
#define PROC "/proc"
/* Arbitrary number picked, 256 should suffice for now */
#define MAX_SLABS 256
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <linux/version.h>
#include <asm/page.h>
#define pagetok(x) ((x) << (PAGE_SHIFT - 10))
/* Taken from linux/drivers/scsi/advansys.h */
/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2, 1, 22)
#error You need kernel version 2.1.22+ for this to work.
#endif
/* Taken from linux/mm/slab.c */
/* /proc/slabinfo
* cache-name num-active-objs total-objs num-active-slabs total-slabs
num-pages-per-slab
*/
struct slabinfo_stat {
char cache_name[20];
unsigned long active_objs;
unsigned long total_objs;
unsigned long active_slabs;
unsigned long total_slabs;
unsigned long pages_per_slab;
};
static inline char *
skip_token(const char *p)
{
while (isspace(*p)) p++;
while (*p && !isspace(*p)) p++;
return (char *)p;
}
static inline char *
skip_ws(const char *p)
{
while (isspace(*p)) p++;
return (char *)p;
}
int main(argc, argv)
int argc;
char **argv;
{
struct statfs sb;
struct slabinfo_stat sbstat[MAX_SLABS];
struct slabinfo_stat overall;
char buffer[4096+1];
char ch;
register int count = -1;
int fd, len, i, show_all = 0;
char *p;
/* overall.cache_name is never used */
overall.active_objs = 0;
overall.total_objs = 0;
overall.active_slabs= 0;
overall.total_slabs = 0;
overall.pages_per_slab = 0;
while ((ch = getopt(argc, argv, "a")) != EOF)
switch(ch)
{
case 'a':
show_all = 1;
break;
default:
printf("\n\nslabinfo version 0.1 [05/08/97] - By Aaron Tiensivu \n");
printf("usage: slabinfo [-a]\n");
printf(" -a includes empty slabs in output \n\n");
exit(0);
}
/* Check to see that /proc is really there */
if (statfs(PROC, &sb) < 0 || sb.f_type != PROC_SUPER_MAGIC)
{
fprintf(stderr, "slabinfo: proc not mounted on " PROC "\n");
exit(-1);
}
/* Relative filename lookups are faster than absolute. */
/* I realize that we're only reading one file, but it is */
/* the thought that counts. ;-) */
chdir(PROC);
if ( (fd = open("slabinfo", O_RDONLY)) < 0)
{
fprintf(stderr,"slabinfo: slabinfo not found\n");
exit(-1);
}
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
buffer[len] = '\0';
p = buffer;
do
{
count++;
/* FIXME: Should check 'slabinfo' version number */
p = strchr(p, '\n') + 1;
memcpy(sbstat[count].cache_name, p, 19);
sbstat[count].active_objs = strtoul(skip_token(p), &p, 10);
sbstat[count].total_objs = strtoul(skip_ws(p) , &p, 10);
sbstat[count].active_slabs = strtoul(skip_ws(p) , &p, 10);
sbstat[count].total_slabs = strtoul(skip_ws(p) , &p, 10);
sbstat[count].pages_per_slab = strtoul(skip_ws(p) , &p, 10);
overall.active_objs += sbstat[count].active_objs;
overall.active_slabs += sbstat[count].active_slabs;
overall.pages_per_slab += (sbstat[count].pages_per_slab *
sbstat[count].total_slabs);
overall.total_objs += sbstat[count].total_objs;
overall.total_slabs += sbstat[count].total_slabs;
} while (*p);
/* This still counts empty slab catagories as real catagories */
/* The number of catagories printed may not equal actual amount */
printf("\n\nSlab Active Total Active Total Memory\n");
printf("Name Objs Objs Slabs Slabs (in K)\n");
printf("--------------------------------------------------------\n");
for (i = 0; i < count; i++)
{
if (show_all || (sbstat[i].total_slabs > 0) )
{
printf("%-20s %6lu %6lu %6lu %6lu %6lu\n",
sbstat[i].cache_name,
sbstat[i].active_objs,
sbstat[i].total_objs,
sbstat[i].active_slabs,
sbstat[i].total_slabs,
pagetok((sbstat[i].pages_per_slab * sbstat[i].total_slabs)));
}
}
printf("--------------------------------------------------------\n");
printf("%-3i slab catagories %6lu %6lu %6lu %6lu %6luk\n\n",
count,
overall.active_objs,
overall.total_objs,
overall.active_slabs,
overall.total_slabs,
pagetok(overall.pages_per_slab));
return 0;
}
--
Best regards, -- Boris.
--- Gnus v5.4.37/XEmacs 19.15
* Origin: Linux inside (2:5020/510@fidonet)