Subject: disc cache readahead count not being incremented Index: sys/ufs_bio.c 2.11BSD Description: If the readahead block is currently in the buffer cache then the statistic 'BHITRA' is not incremented. Repeat-By: Install and run the 'trace' program included below. Observe that the 'bhitra' count remains 0 even though the readahead logic is operating correctly. Fix: Apply the patch to ufs_bio.c and remake the kernel. The 'trace' program must be setgid to kmem (the patch to /usr/src/local/Makefile will take care of this if a "make install" is done. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # /tmp/c # /usr/src/local/trace.c # This archive created: Sun Jun 30 12:37:45 1991 export PATH; PATH=/bin:/usr/bin:$PATH if test -f '/tmp/c' then echo shar: "will not over-write existing file '/tmp/c'" else sed 's/^X//' << \SHAR_EOF > '/tmp/c' X*** /sys/sys/ufs_bio.c.old Mon May 27 02:31:28 1991 X--- /sys/sys/ufs_bio.c Sat Jun 29 17:04:36 1991 X*************** X*** 81,100 **** X * If there's a read-ahead block, start i/o X * on it also (as above). X */ X! if (rablkno && !incore(dev, rablkno)) { X! rabp = getblk(dev, rablkno); X! if (rabp->b_flags & (B_DONE|B_DELWRI)) { X! brelse(rabp); X! trace(TR_BREADHITRA); X! } else { X! rabp->b_flags |= B_READ|B_ASYNC; X! rabp->b_bcount = DEV_BSIZE; /* XXX? KB */ X! (*bdevsw[major(dev)].d_strategy)(rabp); X! trace(TR_BREADMISSRA); X #ifdef UCB_RUSAGE X! u.u_ru.ru_inblock++; /* pay in advance */ X #endif X! } X } X X /* X--- 81,103 ---- X * If there's a read-ahead block, start i/o X * on it also (as above). X */ X! if (rablkno) { X! if (!incore(dev, rablkno)) { X! rabp = getblk(dev, rablkno); X! if (rabp->b_flags & (B_DONE|B_DELWRI)) { X! brelse(rabp); X! trace(TR_BREADHITRA); X! } else { X! rabp->b_flags |= B_READ|B_ASYNC; X! rabp->b_bcount = DEV_BSIZE; /* XXX? KB */ X! (*bdevsw[major(dev)].d_strategy)(rabp); X! trace(TR_BREADMISSRA); X #ifdef UCB_RUSAGE X! u.u_ru.ru_inblock++; /* pay in advance */ X #endif X! } X! } else X! trace(TR_BREADHITRA); X } X X /* X*** /usr/src/local/Makefile.old Mon Jul 2 15:18:52 1990 X--- /usr/src/local/Makefile Sun Jun 30 12:09:42 1991 X*************** X*** 10,16 **** X # C programs that live in the current directory and do not need X # explicit make lines. X # X! STD= none X X # C programs that live in the current directory and need explicit make lines. X # X--- 10,16 ---- X # C programs that live in the current directory and do not need X # explicit make lines. X # X! STD= trace X X # C programs that live in the current directory and need explicit make lines. X # X*************** X*** 32,42 **** X X # Files listed in ${NSTD} have explicit make lines given below. X X! install: X -for i in ${SUBDIR}; do \ X (cd $$i; make ${MFLAGS} DESTDIR=${DESTDIR} install); done X -for i in ${STD} ${NSTD}; do \ X (install $$i ${DESTDIR}/usr/local/$$i); done X -for i in ${SHELL}; do \ X (install -c -m 755 $$i.sh ${DESTDIR}/usr/local/$$i); done X X--- 32,44 ---- X X # Files listed in ${NSTD} have explicit make lines given below. X X! install: ${SUBDIR} ${STD} ${NSTD} X -for i in ${SUBDIR}; do \ X (cd $$i; make ${MFLAGS} DESTDIR=${DESTDIR} install); done X -for i in ${STD} ${NSTD}; do \ X (install $$i ${DESTDIR}/usr/local/$$i); done X+ -chmod 2755 ${DESTDIR}/usr/local/trace X+ -chgrp kmem ${DESTDIR}/usr/local/trace X -for i in ${SHELL}; do \ X (install -c -m 755 $$i.sh ${DESTDIR}/usr/local/$$i); done X SHAR_EOF fi if test -f '/usr/src/local/trace.c' then echo shar: "will not over-write existing file '/usr/src/local/trace.c'" else sed 's/^X//' << \SHAR_EOF > '/usr/src/local/trace.c' X#include X#include X#include X#include X Xstruct nlist nl[] = X { X { "_tracebuf" }, X { "" }, X }; X X int mf, hdr(), lines = 1; X Xmain(argc, argv) X int argc; X char **argv; X { X register i; X int iter; X X nlist("/vmunix", nl); X if (nl[0].n_type == 0) X { X fprintf(stderr, "no /vmunix namelist\n"); X exit(1); X } X mf = open("/dev/kmem", 0); X if (mf < 0) X { X fprintf(stderr, "cannot open /dev/kmem\n"); X exit(1); X } X iter = 0; X argc--, argv++; X if (argc > 1) X iter = atoi(argv[1]); X signal(SIGCONT, hdr); Xloop: X if (--lines == 0) X hdr(); X nmstats(); X fflush(stdout); X if (--iter &&argc > 0) X { X sleep(atoi(argv[0])); X goto loop; X } X } X Xhdr() X { X X puts("bhit bmiss bwrite bhitra bmissra brelse %bhit"); X lines = 19; X } X Xnmstats() X { X float pct; X long tracebuf[TR_NUM_210]; X X lseek(mf, (long)nl[0].n_value, 0); X read(mf, tracebuf, sizeof tracebuf); X pct = tracebuf[TR_BREADHIT]; X pct /= (tracebuf[TR_BREADHIT] + tracebuf[TR_BREADMISS]); X pct *= 100.0; X printf("%-9D %-9D %-9D %-9D %-9D %-9D %.2f\n", X tracebuf[TR_BREADHIT], X tracebuf[TR_BREADMISS], X tracebuf[TR_BWRITE], X tracebuf[TR_BREADHITRA], X tracebuf[TR_BREADMISSRA], X tracebuf[TR_BRELSE], X pct); X } SHAR_EOF fi exit 0 # End of shell archive