From owner-freebsd-hackers Wed Aug 14 14:16:28 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id OAA26513 for hackers-outgoing; Wed, 14 Aug 1996 14:16:28 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id OAA26508; Wed, 14 Aug 1996 14:16:23 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id HAA04204; Thu, 15 Aug 1996 07:13:54 +1000 Date: Thu, 15 Aug 1996 07:13:54 +1000 From: Bruce Evans Message-Id: <199608142113.HAA04204@godzilla.zeta.org.au> To: msmith@atrad.adelaide.edu.au, nate@mt.sri.com Subject: Re: sio issues (silo overflows on a pentium, locked in ttywait, etc...) Cc: freebsd-hackers@freefall.freebsd.org, ponds!rivers@dg-rtp.dg.com, ponds!rivers@freefall.freebsd.org, sag.space.lockheed.com!handy@dg-rtp.dg.com Sender: owner-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk >see the overflows affecting me much. The funny thing is I don't see >overflows on the SLIP server box which is also running 16550A UARTS and >is running multiple sessions, but it's not running X and never touches >the hard disk. (Basically it's the same hardware on both boxes, 486/66 >with 16MB, although my box has an Adaptec 1542B and the server box is >IDE). Upgrade everything to IDE :-). Some busmastering SCSI controllers hog the bus for too long (e.g., Ultrastor U34Fs sometimes hog it for 160 us so they are unusable with single 8250s at speeds > 57600, unusable with single 16550s at speeds > 115200, and barely usable with single UARTS at exactly these speeds. The aha driver sets the bus on/off times to 7/4, so there should be no problems with single UARTs. Here is my throwaway lkm and auxiliarly program for testing bus hogging. Usage: make and load the lkm. Run modstat to see what its syscall number is. It will be 210 if there are no other syscall-lkms. If the number isn't 210, then change 210 in hogtime.c to the number. Compile and run the hogtime utility. Start processes to exercise the bus hog(s), e.g., `dd bs=1024k /dev/null'. Watch the output from hogtime. Bruce --- lkm/hogtime/Makefile --- BINDIR= /tmp SRCS= mycall.c KMOD= newsyscall_mod NOMAN= none CLEANFILES+= ${KMOD} .include --- lkm/hogtime/mycall.c --- #include #include #include #include #include #include #define mycall hogtime static int mycall(struct proc *p, void *uap, int *retval); static struct sysent newent = { 0, mycall, }; MOD_SYSCALL("newsyscall_mod", -1, &newent); extern int newsyscall_mod(struct lkm_table *lkmtp, int cmd, int ver); int newsyscall_mod(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp, cmd, ver, lkm_nullcmd, lkm_nullcmd, lkm_nullcmd) } #ifdef MEMTEST #define ADDR 0xf00d4000 #endif static int hogtime(struct proc *p, void *uap, int *retval) { int i, j, start, finish, delta; #ifdef MADDR volatile u_char *maddr; #endif long usec; disable_intr(); for (i = 0; i < 2; ++i) { /* * i = 0: load cache, if any. i = 1: calibrate and count. * Calibration must be combined with counting so that the * same i/o wait states apply to both. */ #ifdef MEMTEST maddr = (volatile u_char *)ADDR; #endif outb(0x43, 0x00); start = inb(0x40); start |= inb(0x40) << 8; #ifndef MEMTEST inb(0x43); /* 7 dummy i/o's to get 10 altogether */ inb(0x43); inb(0x43); inb(0x43); inb(0x43); inb(0x43); inb(0x43); for (j = 0; j < 100; ++j) ; #else for (j = 0; j < 0x100; j += 2) *(maddr + j); #endif outb(0x43, 0x00); finish = inb(0x40); finish |= inb(0x40) << 8; } enable_intr(); delta = start - finish; #define TIMER_FREQ 1193182 #define LATCH ((TIMER_FREQ + hz / 2) / hz) if (delta < 0) delta += LATCH; usec = (delta * tick + LATCH / 2) / LATCH; *retval = usec; return 0; } static long microtime_buf[4096]; static int microtime_test(struct proc *p, void *uap, int *retval) { int i; struct timeval tv; struct timeval tvp; microtime(&tvp); for (i = 0; i < 4096; ++i) { microtime(&tv); microtime_buf[i] = tv.tv_usec - tvp.tv_usec + 1000000 * (tv.tv_sec - tvp.tv_sec); tvp = tv; } return 0; } --- bin/hogtime.c --- #include #include #include int main(void) { for (;;) { int i; long max = 0; long min = LONG_MAX; long tot = 0; int val; for (i = 0; i < 10000; ++i) { val = syscall(210); if (val == -1) { perror("syscall"); exit(1); } if (max < val) max = val; if (min > val) min = val; tot += val; } printf("min = %ld, av = %ld, max = %ld\n", min, tot / i, max); } return 0; }