Return to BSD News archive
Newsgroups: comp.os.386bsd.apps Path: sserve!csadfa.cs.adfa.oz.au!wkt From: wkt@csadfa.cs.adfa.oz.au (Warren Toomey) Subject: [src] Disk seek stats program Message-ID: <1993Nov21.221632.2247@sserve.cc.adfa.oz.au> Keywords: disk arm motion seek stats collector Sender: news@sserve.cc.adfa.oz.au Organization: Australian Defence Force Academy, Canberra, Australia Date: Sun, 21 Nov 1993 22:16:32 GMT Shar file below! # Readme # seekstat.c # seekstat.h # ufs_disksubr.c.diff # echo x - Readme sed 's/^X//' >Readme << 'END-of-Readme' XHere is a little stats program I wrote after reading the Nutshell book on XSystem Performance Tuning. It makes the kernel gather stats on the disk seek Xmotion, which can be accessed by the program. X XInstallation X------------ X XPatch /sys/ufs/ufs_disksubr.c with the included patch. There are only Xadditions, so if the patch fails you can do it manually. X XInstall seekstat.h in /sys/sys. X XAdd the option SEEKSTAT to your kernel config file. X XRecompile your kernel. BEFORE you install the new kernel, make sure you Xsave your old kernel and can reboot using it, either by hard disk or floppy. XJust in case! X XInstall the new kernel and reboot. X XCompile the seekstat program: X cc -o seekstat seekstat.c X X XMan Page X-------- X XFirst run seekstat with no arguments: X seekstat | less X XThe columns are: X + The device number (I haven't bothered mapping these to names). X + The cylinder of a read/write request. X + The seek to get the head there. X XNow, rerun seekstat with two arguments, a `clump' of cylinders and a device Xnumber from above, e.g X seekstat 10 8 | less X XWe bucketize the raw data into clumps, and print out stats per clump. You Xwill get the number of requests per clump, and in a second table the number Xof seeks, broken into the same sized clumps. For example: X X X607 Seeks Total # of seeks for device 8 X XCylgrp Use X0 0 X20 0 X ... X400 0 X420 0 X440 103 These cylinders are the ones X460 169 being accessed most X480 21 X500 2 X520 1 X540 14 X560 11 X580 16 X600 51 X620 4 X640 2 X660 2 X680 9 X XSeek Count X0 289 Most seeks are for <20 cylinders X20 33 X40 28 X60 13 X80 26 X100 16 X120 25 X140 35 X160 18 X180 4 X200 0 X ... X XSystem Requirements X------------------- X XThe extra code in the kernel is negligible. However, 2048 seekstat Xbuffers are added, increasing the kernel's data size by 12,288 bytes. XThe performance penalty to collect the statistics should also be Xnegligible. END-of-Readme echo x - seekstat.c sed 's/^X//' >seekstat.c << 'END-of-seekstat.c' X/* X * Seekstat: Print out statistics about the disk arm motion X * X * Written 11/93 by Warren wkt@csadfa.cs.adfa.oz.au X */ X X#include <sys/types.h> X#include <stdio.h> X#include <fcntl.h> X#include <nlist.h> X#include <sys/seekstat.h> X Xchar *fcore = "/dev/kmem"; /* Device to read from */ Xchar *fnlist = "/386bsd"; /* File to nlist thru */ Xint fc; /* File desc of fcore */ X X /* List of kernel names we desire */ Xstruct nlist nl[] = { X X { "_seekst" }, X { "" } X}; X Xstruct seekstat seekst[NUMSEEKSTATS]; X Xusage() X { fprintf(stderr,"Usage: seekstat [cyls device#]\n"); exit(1); } X Xmain(argc,argv) X int argc; X char *argv[]; X{ X int i,cnt,got,device; X int seeks, cyls, maxcyl=0, maxseek=0; X int *cylbox, *seekbox; X X /* Check and get the args */ X if (argc!=1 && argc!=3) usage(); X if (argc==3) X { cyls=atoi(argv[1]); X if (cyls<1) { fprintf(stderr,"Cyls cannot be <1\n"); exit(1); } X device=atoi(argv[2]); X } X /* Find the data structures */ X /* in the kernel */ X i=nlist(fnlist, nl); X if (i==-1) { perror("nlist"); exit(1); } X X for (i=0;nl[i].n_name;i++) X if (nl[0].n_type == 0) X { fprintf(stderr,"%s not found in namelist\n",nl[0].n_name); exit(1); } X X /* Open up the kernel memory */ X fc= open(fcore,O_RDONLY); X if (fc==-1) { perror("opening /dev/kmem"); exit(1); } X X X /* Get the stat info */ X i=lseek(fc, nl[0].n_value, SEEK_SET); X if (i==-1) { perror("lseeking /dev/kmem"); exit(1); } X if (argc==1) printf("Dev\tCyl\tSeek\n"); X X for (got=NUMSEEKSTATS,cnt=i=0;i<NUMSEEKSTATS;i++) X { read(fc, &seekst[cnt], sizeof(struct seekstat)); X if (seekst[cnt].b_dev==0 && seekst[cnt].b_cyl==0 && seekst[cnt].b_seek==0) X break; X if (argc==3 && seekst[cnt].b_dev!=device) continue; X if (seekst[cnt].b_seek<0) seekst[cnt].b_seek=-seekst[cnt].b_seek; X if (argc==1) printf("%x\t%d\t%d\n", X seekst[cnt].b_dev,seekst[cnt].b_cyl,seekst[cnt].b_seek); X if (seekst[cnt].b_cyl> maxcyl) maxcyl=seekst[cnt].b_cyl; X if (seekst[cnt].b_seek> maxseek) maxseek=seekst[cnt].b_seek; X cnt++; X } X got=cnt; X X if (argc==1) exit(0); X printf("%d Seeks\n\n",got); X /* Now get buckets for stats */ X cylbox=(int *)calloc(1+(maxcyl/cyls), sizeof(int)); X if (cylbox==NULL) { fprintf(stderr,"Can't malloc cylbox\n"); exit(1); } X seekbox=(int *)calloc(1+(maxseek/cyls), sizeof(int)); X if (seekbox==NULL) { fprintf(stderr,"Can't malloc seekbox\n"); exit(1); } X X /* Drop seek, cyl into bucket */ X for (cnt=0;cnt<got;cnt++) X { i=seekst[cnt].b_cyl/cyls; cylbox[i]++; X i=seekst[cnt].b_seek/cyls; seekbox[i]++; X } X X printf("Cylgrp\tUse\n"); X for (i=0;i<(maxcyl/cyls);i++) printf("%d\t%d\n", i * cyls, cylbox[i]); X X /* Find highest !0 seek */ X for (i=maxseek/cyls;i>=0;i--) if (seekbox[i]) { seeks=i+1; break; } X X printf("\nSeek\tCount\n"); X for (i=0;i<seeks;i++) printf("%d\t%d\n", i * cyls, seekbox[i]); X } END-of-seekstat.c echo x - seekstat.h sed 's/^X//' >seekstat.h << 'END-of-seekstat.h' X#ifndef _SEEKSTAT_H X#define _SEEKSTAT_H X X/* Structure to gather statistics about disk seek patterns. X * Author: Warren Toomey, wkt@csadfa.cs.adfa.oz.au X * X * This is only used in ufs_disksubr.c, with SEEKSTAT defined. X */ X X#define NUMSEEKSTATS 2048 /* We record up to 2048 statistics */ X Xstruct seekstat { X short b_dev; /* The device that is seeking */ X short b_cyl; /* A seek to this cylinder */ X short b_seek; /* With this seek movement */ X}; X#endif /* _SEEKSTAT_H */ END-of-seekstat.h echo x - ufs_disksubr.c.diff sed 's/^X//' >ufs_disksubr.c.diff << 'END-of-ufs_disksubr.c.diff' X*** z Sat Nov 20 13:30:59 1993 X--- ufs_disksubr.c Sat Nov 20 09:05:34 1993 X*************** X*** 37,48 **** X--- 37,54 ---- X #include "systm.h" X #include "buf.h" X #include "dkbad.h" X #include "disklabel.h" X #include "syslog.h" X X+ #ifdef SEEKSTAT X+ #include "seekstat.h" X+ struct seekstat seekst[NUMSEEKSTATS]; X+ int sscount=0; X+ #endif X+ X /* X * Seek sort for disks. We depend on the driver X * which calls us using b_resid as the current cylinder number. X * X * The argument dp structure holds a b_actf activity chain pointer X * on which we keep two queues, sorted in ascending cylinder order. X*************** X*** 134,145 **** X--- 140,157 ---- X /* X * Neither a second list nor a larger X * request... we go at the end of the first list, X * which is the same as the end of the whole schebang. X */ X insert: X+ #ifdef SEEKSTAT X+ seekst[sscount].b_dev= ap->b_dev; X+ seekst[sscount].b_cyl= ap->b_cylin; X+ seekst[sscount].b_seek= ap->b_cylin - bp->b_cylin; X+ sscount++; sscount%= NUMSEEKSTATS; X+ #endif X bp->av_forw = ap->av_forw; X ap->av_forw = bp; X if (ap == dp->b_actl) X dp->b_actl = bp; X } X END-of-ufs_disksubr.c.diff exit #! rnews 7949 sserve.cc.adfa.oz.au Xref: sserve comp.os.386bsd.questions:7059 comp.windows.x.i386unix:5103 comp.os.386bsd.apps:716 Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!howland.reston.ans.net!xlink.net!rz.uni-karlsruhe.de!uni-mannheim!andrew From: andrew@wipux2.wifo.uni-mannheim.de (Andrew Wheadon) Newsgroups: comp.os.386bsd.questions,comp.windows.x.i386unix,comp.os.386bsd.apps Subject: Re: XFree86-2.0, NetBSD-current, shared libs Date: 21 Nov 1993 19:16:05 GMT Organization: Rechenzentrum Uni-Mannheim Lines: 247 Message-ID: <2coepl$7qj@darum.uni-mannheim.de> References: <2clt2o$gpu@news.rhrz.uni-bonn.de> NNTP-Posting-Host: wipux2.wifo.uni-mannheim.de In article <2clt2o$gpu@news.rhrz.uni-bonn.de>, Henry G. Juengst <juengst@saph2.physik.uni-bonn.de> wrote: >questions. Later when the following problems are sovled I could publish >the new files + patches. a patch which solves all the problems except that libphigs is still built statically, was posted a short time ago to netbsd-current-users@sun-lamp.cs.berkeley.edu (The fact that libphigs is not built as a shared-libs is due to the fact that it is not built the same way as the others, and it's to much trouble to create a new patch just for 1 library. > available). Initialize.c from the libXt reports an "Unresolved inheritance > ... > isn't it ? Does anybody have a good idea how to solve this problem ? You should do: COPTS=-DEXPERIMENTAL ; export COPTS and recompile /usr/src/gnu/usr.bin/ld following is the patch for XFree86-2.0: To: xfree86-beta@physics.su.oz.au Cc: current-users@sun-lamp.cs.berkeley.edu Subject: Yet another patch for XFree-2.0 for shared libraries Date: Mon, 15 Nov 1993 15:07:53 -0500 From: John Brezak <brezak@ch.hp.com> Since I haven't seen what should be the *right* patch for XFree-2.0 NetBSD shared libraries, I'll add this one to the maze. All of the others are *flawed* IMHO 'cause they fell back to the Sun shlib behavior or were plain broken. Features of this patch: - No source code changes - Just config/x386.cf and lib/Xmu/Imakefile - Add new shlib type - config/netbsdLib.{tmpl,rules} - No libxx.sa's needed - libXt based apps work - libXmu only apps work - Tested with netbsd-current 11/14/93 - Started verison numbers at 5.0 (for most things) - Added a -DBSDSHLIB (not used) for just in case... *** config/x386.cf.orig Mon Nov 15 14:56:02 1993 --- config/x386.cf Mon Nov 15 14:56:05 1993 *************** *** 978,983 **** --- 978,988 ---- # define CppCmd /usr/libexec/cpp #endif + #ifdef i386NetBsd + # define ForceNormalLib YES + # include <netbsdLib.rules> + #endif + #if HasGcc # define AnsiCCOptions /**/ # if HasGcc2 *** /dev/null Mon Nov 15 02:34:33 1993 --- config/netbsdLib.rules Fri Nov 12 07:43:50 1993 *************** *** 0 **** --- 1,72 ---- + XCOMM $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $ + + /* + * NetBSD shared library rules + */ + + #ifndef HasSharedLibraries + #define HasSharedLibraries YES + #endif + #ifndef SharedDataSeparation + #define SharedDataSeparation NO + #endif + #ifndef SharedCodeDef + #define SharedCodeDef + #endif + #ifndef SharedLibraryDef + #define SharedLibraryDef -DBSDSHLIB + #endif + #ifndef ShLibIncludeFile + #define ShLibIncludeFile <netbsdLib.tmpl> + #endif + #ifndef SharedLibraryLoadFlags + #define SharedLibraryLoadFlags -Bshareable -assert pure-text + #endif + #ifndef PositionIndependentCFlags + #define PositionIndependentCFlags -fpic + #endif + + /* + * InstallSharedLibrary - generate rules to install the shared library. + */ + #ifndef InstallSharedLibrary + #define InstallSharedLibrary(libname,rev,dest) @@\ + install:: Concat(lib,libname.so.rev) @@\ + MakeDir($(DESTDIR)dest) @@\ + $(INSTALL) -c $(INSTLIBFLAGS) Concat(lib,libname.so.rev) $(DESTDIR)dest @@\ + + #endif /* InstallSharedLibrary */ + + /* + * InstallSharedLibraryData - generate rules to install the shared library data + */ + #ifndef InstallSharedLibraryData + #define InstallSharedLibraryData(libname,rev,dest) + #endif /* InstallSharedLibraryData */ + + /* + * NormalSharedLibraryTarget - generate rules to create a shared library; + * build it into a different name so that the we do not hose people by having + * the library gone for long periods. + */ + #ifndef SharedLibraryTarget + #define SharedLibraryTarget(libname,rev,solist,down,up) @@\ + AllTarget(Concat(lib,libname.so.rev)) @@\ + @@\ + Concat(lib,libname.so.rev): solist @@\ + $(RM) $@~ @@\ + (cd down; $(LD) -o up/$@~ $(SHLIBLDFLAGS) solist $(REQUIREDLIBS)) @@\ + $(RM) $@ @@\ + $(MV) $@~ $@ @@\ + @@\ + clean:: @@\ + $(RM) Concat(lib,libname.so.rev) + + #endif /* SharedLibraryTarget */ + + /* + * SharedLibraryDataTarget - generate rules to create shlib data file; + */ + #ifndef SharedLibraryDataTarget + #define SharedLibraryDataTarget(libname,rev,salist) + #endif /* SharedLibraryDataTarget */ *** /dev/null Mon Nov 15 02:34:33 1993 --- config/netbsdLib.tmpl Mon Nov 15 15:00:37 1993 *************** *** 0 **** --- 1,81 ---- + XCOMM $XConsortium: sunLib.tmpl,v 1.14.1.2 92/11/11 09:55:02 rws Exp $ + + /* + * NetBSD shared library template + */ + + #ifndef SharedXlibRev + #define SharedXlibRev 5.0 + #endif + #ifndef SharedOldXRev + #define SharedOldXRev 5.0 + #endif + #ifndef SharedXtRev + #define SharedXtRev 5.0 + #endif + #ifndef SharedXawRev + #define SharedXawRev 5.0 + #endif + #ifndef SharedXmuRev + #define SharedXmuRev 5.0 + #endif + #ifndef SharedXextRev + #define SharedXextRev 5.0 + #endif + #ifndef SharedXinputRev + #define SharedXinputRev 5.0 + #endif + #ifndef SharedXTrapRev + #define SharedXTrapRev 1.0 + #endif + #ifndef SharedPexRev + #define SharedPexRev 1.0 + #endif + + SHLIBLDFLAGS = SharedLibraryLoadFlags + PICFLAGS = PositionIndependentCFlags + + /* + * and now a little bit of magic for using imake without source tree; if we + * are using shared libraries, we really do not need to depend on anything + */ + #if SharedLibXpm + DEPXPMLIB = + XPMLIB = _Use(-lXpm,-L$(XPMSRC)/lib -lXpm) + #endif + #if SharedLibXext + DEPEXTENSIONLIB = + EXTENSIONLIB = _Use(-lXext,-L$(EXTENSIONSRC)/lib -lXext) + #endif + #if SharedLibX + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) _Use(-lX11,-L$(XLIBSRC) -lX11) + #endif + #if SharedLibXmu + DEPXMULIB = + XMULIBONLY = _Use(-lXmu,-L$(XMUSRC) -lXmu) + XMULIB = _Use(-lXmu,-L$(XMUSRC) -lXmu -L$(TOOLKITSRC) -L$(EXTENSIONSRC)/lib -L$(XLIBSRC)) + #if !defined(UseInstalled) && !defined(XawClientLibs) + #define XawClientLibs $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XLIB) + #endif + #endif + #if SharedOldLibX + DEPOLDXLIB = + OLDXLIB = _Use(-loldX,-L$(OLDXLIBSRC) -loldX) + #endif + #if SharedLibXt + DEPXTOOLLIB = + XTOOLLIB = _Use(-lXt,-L$(TOOLKITSRC) -lXt) + #endif + #if SharedLibXaw + DEPXAWLIB = + XAWLIB = _Use(-lXaw,-L$(AWIDGETSRC) -lXaw) + #endif + #if SharedLibXinput + DEPXILIB = + XILIB = _Use(-lXi,-L$(XILIBSRC) -lXi) + #endif + #if SharedLibPex + DEPPEXLIB = + PEXLIB = _Use(-lPEX5,-L$(PEXLIBSRC) -lPEX5) + #endif *** lib/Xmu/Imakefile.orig Mon Nov 15 14:56:35 1993 --- lib/Xmu/Imakefile Sun Nov 14 16:11:03 1993 *************** *** 11,17 **** #define DoProfileLib ProfileLibXmu #include <Library.tmpl> ! #if defined(RsArchitecture) || SunPost411FCSLd #if DoNormalLib REQUIREDLIBS = -L../$(TOOLKITSRC) -lXt -L../$(EXTENSIONSRC)/lib -lXext -L../$(XLIBSRC) -lX11 #else --- 11,17 ---- #define DoProfileLib ProfileLibXmu #include <Library.tmpl> ! #if defined(RsArchitecture) || SunPost411FCSLd || defined(i386NetBsd) #if DoNormalLib REQUIREDLIBS = -L../$(TOOLKITSRC) -lXt -L../$(EXTENSIONSRC)/lib -lXext -L../$(XLIBSRC) -lX11 #else --- end of the patch Enjoy -- Eat the rich -- the poor are tough and stringy.