raw I/O enhancement
Jeff Gilliam
jeff at voder.UUCP
Sat Feb 27 09:33:31 AEST 1988
Subject: raw I/O enhancement
Index: sys/{h,sys,vax,vaxuba,vaxmba}/... 4.3BSD
Description:
Since the beginning of time each mass storage device driver has
statically allocated one buf structure per controller (disk
controller or tape formatter) exclusively for use by raw I/O.
As noted by Don Speck, the new multi-process dump program
encounters contention as the multiple reader processes all fight
over a single buf structure. Also, as noted by Chris Torek, many
of the drivers have raw read and write routines that are identical
except for the names of the raw I/O buffer and strategy routine.
Repeat-By:
Examine code.
Fix:
The changes below add a new field in the cdevsw structure for the
strategy routine, and new generic raw I/O routines. physio() is
changed to allocate a buffer from the pool of swap buffers if no
buffer pointer is passed to it. Driver specific raw I/O routines
are removed where appropriate, and cdevsw[] is set up to call the
generic raw I/O routines instead.
To apply these patches:
cd /sys
patch -p1 < thisfile
Index: sys/h/conf.h
Add a new field to the cdevsw structure which points to the device's
strategy routine.
RCS file: RCS/conf.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** /tmp/,RCSt1001410 Fri Feb 26 10:47:00 1988
--- /tmp/,RCSt2001410 Fri Feb 26 10:47:00 1988
***************
*** 43,48 ****
--- 43,49 ----
struct tty *d_ttys;
int (*d_select)();
int (*d_mmap)();
+ int (*d_strategy)();
};
#ifdef KERNEL
struct cdevsw cdevsw[];
Index: sys/vax/conf.c
Change the cdevsw[] to initialize the new strategy fields properly. Also
use the generic raw I/O routines instead of device specific routines wherever
possible.
RCS file: RCS/conf.c,v
retrieving revision 1.2
retrieving revision 1.6
diff -r1.2 -r1.6
21c21
< int hpopen(),hpstrategy(),hpread(),hpwrite(),hpdump(),hpioctl(),hpsize();
---
> int hpopen(),hpstrategy(),hpdump(),hpioctl(),hpsize();
25,26d24
< #define hpread nodev
< #define hpwrite nodev
47c45
< int rkopen(),rkstrategy(),rkread(),rkwrite(),rkintr();
---
> int rkopen(),rkstrategy(),rkintr();
52,53d49
< #define rkread nodev
< #define rkwrite nodev
77c73
< int tmscpopen(),tmscpclose(),tmscpstrategy(),tmscpread(),tmscpwrite();
---
> int tmscpopen(),tmscpclose(),tmscpstrategy();
83,84d78
< #define tmscpread nodev
< #define tmscpwrite nodev
121c115
< int udopen(),udstrategy(),udread(),udwrite(),udreset(),uddump(),udsize();
---
> int udopen(),udstrategy(),udreset(),uddump(),udsize();
125,126d118
< #define udread nodev
< #define udwrite nodev
134c126
< int upopen(),upstrategy(),upread(),upwrite(),upreset(),updump(),upsize();
---
> int upopen(),upstrategy(),upreset(),updump(),upsize();
138,139d129
< #define upread nodev
< #define upwrite nodev
162c152
< int idcopen(),idcstrategy(),idcread(),idcwrite();
---
> int idcopen(),idcstrategy();
167,168d156
< #define idcread nodev
< #define idcwrite nodev
208c196
< int rlopen(),rlstrategy(),rlread(),rlwrite();
---
> int rlopen(),rlstrategy();
213,214d200
< #define rlread nodev
< #define rlwrite nodev
511a498
> int rawread(), rawwrite();
517c504
< ttselect, nodev,
---
> ttselect, nodev, nodev,
520c507
< ttselect, nodev,
---
> ttselect, nodev, nodev,
523c510
< syselect, nodev,
---
> syselect, nodev, nodev,
526,527c513,514
< mmselect, nodev,
< hpopen, nulldev, hpread, hpwrite, /*4*/
---
> mmselect, nodev, nodev,
> hpopen, nulldev, rawread, rawwrite, /*4*/
529c516
< seltrue, nodev,
---
> seltrue, nodev, hpstrategy,
532c519
< seltrue, nodev,
---
> seltrue, nodev, nodev,
535c522
< vpselect, nodev,
---
> vpselect, nodev, nodev,
538c525
< nodev, nodev,
---
> nodev, nodev, nodev,
541,542c528,529
< seltrue, nodev,
< udopen, nulldev, udread, udwrite, /*9*/
---
> seltrue, nodev, nodev,
> udopen, nulldev, rawread, rawwrite, /*9*/
544c531
< seltrue, nodev,
---
> seltrue, nodev, udstrategy,
547,548c534,535
< vaselect, nodev,
< rkopen, nulldev, rkread, rkwrite, /*11*/
---
> vaselect, nodev, nodev,
> rkopen, nulldev, rawread, rawwrite, /*11*/
550c537
< seltrue, nodev,
---
> seltrue, nodev, nodev,
553,554c540,541
< ttselect, nodev,
< upopen, nulldev, upread, upwrite, /*13*/
---
> ttselect, nodev, nodev,
> upopen, nulldev, rawread, rawwrite, /*13*/
556c543
< seltrue, nodev,
---
> seltrue, nodev, nodev,
559c546
< seltrue, nodev,
---
> seltrue, nodev, nodev,
562c549
< seltrue, nodev,
---
> seltrue, nodev, nodev,
565c552
< seltrue, nodev,
---
> seltrue, nodev, nodev,
568c555
< seltrue, nodev,
---
> seltrue, nodev, nodev,
571c558
< seltrue, nodev,
---
> seltrue, nodev, nodev,
574c561
< seltrue, nodev,
---
> seltrue, nodev, nodev,
577c564
< ttselect, nodev,
---
> ttselect, nodev, nodev,
580c567
< ptcselect, nodev,
---
> ptcselect, nodev, nodev,
583,584c570,571
< ttselect, nodev,
< idcopen, nulldev, idcread, idcwrite, /*23*/
---
> ttselect, nodev, nodev,
> idcopen, nulldev, rawread, rawwrite, /*23*/
586c573
< seltrue, nodev,
---
> seltrue, nodev, nodev,
589c576
< seltrue, nodev,
---
> seltrue, nodev, nodev,
593c580
< seltrue, nodev,
---
> seltrue, nodev, nodev,
596c583
< seltrue, nodev,
---
> seltrue, nodev, nodev,
599c586
< seltrue, nodev,
---
> seltrue, nodev, nodev,
602c589
< nodev, nodev,
---
> nodev, nodev, nodev,
605c592
< seltrue, nodev,
---
> seltrue, nodev, nodev,
608c595
< seltrue, nodev,
---
> seltrue, nodev, nodev,
611,612c598,599
< seltrue, nodev,
< rlopen, nodev, rlread, rlwrite, /*32*/
---
> seltrue, nodev, nodev,
> rlopen, nodev, rawread, rawwrite, /*32*/
614c601
< seltrue, nodev,
---
> seltrue, nodev, nodev,
617c604
< logselect, nodev,
---
> logselect, nodev, nodev,
620c607
< ttselect, nodev,
---
> ttselect, nodev, nodev,
623c610
< seltrue, nodev,
---
> seltrue, nodev, nodev,
626c613
< vsselect, nodev,
---
> vsselect, nodev, nodev,
629,630c616,617
< ttselect, nodev,
< tmscpopen, tmscpclose, tmscpread, tmscpwrite, /*38*/
---
> ttselect, nodev, nodev,
> tmscpopen, tmscpclose, rawread, rawwrite, /*38*/
632c619
< seltrue, nodev,
---
> seltrue, nodev, nodev,
635c622
< nodev, nodev,
---
> nodev, nodev, nodev,
638c625
< nodev, nodev,
---
> nodev, nodev, nodev,
641c628
< nodev, nodev,
---
> nodev, nodev, nodev,
645c632
< nodev, nodev,
---
> nodev, nodev, nodev,
Index: sys/sys/vm_swp.c
Add the new generic raw I/O routines rawread() and rawwrite(). Change
physio() so that when the buffer pointer passed to it is null, it allocates
a buffer from the swap I/O pool.
RCS file: RCS/vm_swp.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** /tmp/,RCSt1001343 Fri Feb 26 10:34:42 1988
--- /tmp/,RCSt2001343 Fri Feb 26 10:34:43 1988
***************
*** 200,205 ****
--- 200,206 ----
register int c;
char *a;
int s, error = 0;
+ int localbuf = 0;
nextiov:
if (uio->uio_iovcnt == 0)
***************
*** 208,213 ****
--- 209,223 ----
if (useracc(iov->iov_base,(u_int)iov->iov_len,rw==B_READ?B_WRITE:B_READ) == NULL)
return (EFAULT);
s = splbio();
+ if (bp == (struct buf *)NULL) {
+ while (bswlist.av_forw == NULL) {
+ bswlist.b_flags |= B_WANTED;
+ sleep((caddr_t)&bswlist, PRIBIO+1);
+ }
+ bp = bswlist.av_forw;
+ bswlist.av_forw = bp->av_forw;
+ localbuf++;
+ }
while (bp->b_flags&B_BUSY) {
bp->b_flags |= B_WANTED;
sleep((caddr_t)bp, PRIBIO+1);
***************
*** 243,251 ****
}
bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS);
error = geterror(bp);
/* temp kludge for tape drives */
! if (bp->b_resid || error)
return (error);
uio->uio_iov++;
uio->uio_iovcnt--;
goto nextiov;
--- 253,273 ----
}
bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS);
error = geterror(bp);
+ (void) splbio();
+ if (localbuf) {
+ bp->av_forw = bswlist.av_forw;
+ bswlist.av_forw = bp;
+ if (bswlist.b_flags & B_WANTED) {
+ bswlist.b_flags &= ~B_WANTED;
+ wakeup((caddr_t)&bswlist);
+ }
+ }
/* temp kludge for tape drives */
! if (bp->b_resid || error) {
! splx(s);
return (error);
+ }
+ splx(s);
uio->uio_iov++;
uio->uio_iovcnt--;
goto nextiov;
***************
*** 260,263 ****
--- 282,301 ----
if (bp->b_bcount > MAXPHYS)
bp->b_bcount = MAXPHYS;
+ }
+
+ rawread(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+ {
+ return (physio(cdevsw[major(dev)].d_strategy,
+ (struct buf *)NULL, dev, B_READ, minphys, uio));
+ }
+
+ rawwrite(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+ {
+ return (physio(cdevsw[major(dev)].d_strategy,
+ (struct buf *)NULL, dev, B_WRITE, minphys, uio));
}
Index: sys/vaxmba/hp.c
Remove the now-unused raw I/O routines and rhpbuf[] from the hp driver.
RCS file: RCS/hp.c,v
retrieving revision 1.1
diff -c -r1.1 hp.c
*** /tmp/,RCSt1001486 Fri Feb 26 10:58:48 1988
--- hp.c Fri Feb 26 10:56:44 1988
***************
*** 255,261 ****
0, 0, 0, 0,
};
- struct buf rhpbuf[NHP];
struct buf bhpbuf[NHP];
struct dkbad hpbad[NHP];
--- 255,260 ----
***************
*** 776,803 ****
if (i == 0)
printf("hp%d: intr, not ready\n", mi->mi_unit);
return (i);
- }
-
- hpread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = hpunit(dev);
-
- if (unit >= NHP)
- return (ENXIO);
- return (physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys, uio));
- }
-
- hpwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = hpunit(dev);
-
- if (unit >= NHP)
- return (ENXIO);
- return (physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys, uio));
}
/*ARGSUSED*/
--- 775,780 ----
Index: sys/vaxuba/idc.c
Remove the now-unused raw I/O routines and ridcbuf[] from the idc driver.
RCS file: RCS/idc.c,v
retrieving revision 1.2
diff -c -r1.2 idc.c
*** /tmp/,RCSt1001710 Fri Feb 26 11:21:05 1988
--- idc.c Fri Feb 26 11:21:01 1988
***************
*** 116,123 ****
512, NRB80SECT, NRB80TRK, NRB80SECT*NRB80TRK, NRB80CYL, rb80_sizes,
};
- struct buf ridcbuf[NRB];
-
#define b_cylin b_resid
int idcwstart, idcwticks, idcwatch();
--- 116,121 ----
***************
*** 660,687 ****
for (i = 10; i; i--)
;
return (n);
- }
-
- idcread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = idcunit(dev);
-
- if (unit >= NRB)
- return (ENXIO);
- return (physio(idcstrategy, &ridcbuf[unit], dev, B_READ, minphys, uio));
- }
-
- idcwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = idcunit(dev);
-
- if (unit >= NRB)
- return (ENXIO);
- return (physio(idcstrategy, &ridcbuf[unit], dev, B_WRITE, minphys, uio));
}
idcecc(ui)
--- 658,663 ----
Index: sys/vaxuba/rk.c
Remove the now-unused raw I/O routines and rrkbuf[] from the rk driver.
RCS file: RCS/rk.c,v
retrieving revision 1.2
diff -c -r1.2 rk.c
*** /tmp/,RCSt1001718 Fri Feb 26 11:21:33 1988
--- rk.c Fri Feb 26 11:21:30 1988
***************
*** 111,118 ****
RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
};
- struct buf rrkbuf[NRK];
-
#define b_cylin b_resid
int rkwstart, rkwatch();
--- 111,116 ----
***************
*** 526,553 ****
while ((addr->rkcs1 & RK_CRDY) == 0)
;
- }
-
- rkread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = rkunit(dev);
-
- if (unit >= NRK)
- return (ENXIO);
- return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio));
- }
-
- rkwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = rkunit(dev);
-
- if (unit >= NRK)
- return (ENXIO);
- return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio));
}
rkecc(ui, flag)
--- 524,529 ----
Index: sys/vaxuba/rl.c
Remove the now-unused raw I/O routines and rrlbuf[] from the rl driver.
RCS file: RCS/rl.c,v
retrieving revision 1.2
diff -c -r1.2 rl.c
*** /tmp/,RCSt1001726 Fri Feb 26 11:21:56 1988
--- rl.c Fri Feb 26 11:21:53 1988
***************
*** 97,104 ****
20, 2, 40, 512, 20*512, rl02_sizes /* rl02/DEC*/
};
- struct buf rrlbuf[NRL];
-
#define b_cylin b_resid /* Last seek as CYL<<1 | HD */
int rlwstart, rlwatch(); /* Have started guardian */
--- 97,102 ----
***************
*** 555,582 ****
while ((rladdr->rlcs & RL_CRDY) == 0)
;
- }
-
- rlread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = rlunit(dev);
-
- if (unit >= NRL)
- return (ENXIO);
- return (physio(rlstrategy, &rrlbuf[unit], dev, B_READ, minphys, uio));
- }
-
- rlwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = rlunit(dev);
-
- if (unit >= NRL)
- return (ENXIO);
- return (physio(rlstrategy, &rrlbuf[unit], dev, B_WRITE, minphys, uio));
}
/*
--- 553,558 ----
Index: sys/vaxuba/tmscp.c
Remove the now-unused raw I/O routines and rtmsbuf[] from the tmscp driver.
RCS file: RCS/tmscp.c,v
retrieving revision 1.2
diff -c -r1.2 tmscp.c
*** /tmp/,RCSt1001734 Fri Feb 26 11:22:30 1988
--- tmscp.c Fri Feb 26 11:22:24 1988
***************
*** 200,206 ****
* ifdef other tmscp devices here if they allow more than 1 unit/controller
*/
struct uba_device *tmscpip[NTMSCP][1];
- struct buf rtmsbuf[NTMS]; /* raw i/o buffer */
struct buf ctmscpbuf[NTMSCP]; /* internal cmd buffer (for ioctls) */
struct buf tmsutab[NTMS]; /* Drive queue */
struct buf tmscpwtab[NTMSCP]; /* I/O wait queue, per controller */
--- 200,205 ----
***************
*** 1873,1910 ****
return(0);
}
return(1);
- }
-
-
- /*
- * Perform raw read
- */
-
- tmscpread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = TMSUNIT(dev);
-
- if (unit >= NTMS)
- return (ENXIO);
- return (physio(tmscpstrategy, &rtmsbuf[unit], dev, B_READ, minphys, uio));
- }
-
-
- /*
- * Perform raw write
- */
-
- tmscpwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = TMSUNIT(dev);
-
- if (unit >= NTMS)
- return (ENXIO);
- return (physio(tmscpstrategy, &rtmsbuf[unit], dev, B_WRITE, minphys, uio));
}
--- 1872,1877 ----
Index: sys/vaxuba/uda.c
Remove the now-unused raw I/O routines and rudbuf[] from the uda driver.
RCS file: RCS/uda.c,v
retrieving revision 1.2
retrieving revision 1.5
diff -c -r1.2 -r1.5
*** /tmp/,RCSt1001617 Fri Feb 26 11:02:26 1988
--- /tmp/,RCSt2001617 Fri Feb 26 11:02:34 1988
***************
*** 177,183 ****
struct uba_ctlr *udminfo[NUDA];
struct uba_device *uddinfo[NRA];
struct uba_device *udip[NUDA][8]; /* 8 == max number of drives */
- struct buf rudbuf[NRA];
struct buf udutab[NRA];
struct buf udwtab[NUDA]; /* I/O wait queue, per controller */
--- 177,182 ----
***************
*** 1192,1219 ****
}
(void) splx(s);
return(NULL);
- }
-
- udread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = udunit(dev);
-
- if (unit >= NRA)
- return (ENXIO);
- return (physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys, uio));
- }
-
- udwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = udunit(dev);
-
- if (unit >= NRA)
- return (ENXIO);
- return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio));
}
udreset(uban)
--- 1191,1196 ----
Index: sys/vaxuba/up.c
Remove the now-unused raw I/O routines and rupbuf[] from the up driver.
RCS file: RCS/up.c,v
retrieving revision 1.2
diff -c -r1.2 up.c
*** /tmp/,RCSt1001742 Fri Feb 26 11:23:02 1988
--- up.c Fri Feb 26 11:22:58 1988
***************
*** 147,153 ****
0, 0, 0, 0
};
- struct buf rupbuf[NUP];
struct buf bupbuf[NUP];
struct dkbad upbad[NUP];
--- 147,152 ----
***************
*** 736,763 ****
needie = 0;
if (needie)
upaddr->upcs1 = UP_IE;
- }
-
- upread(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = upunit(dev);
-
- if (unit >= NUP)
- return (ENXIO);
- return (physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys, uio));
- }
-
- upwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
- {
- register int unit = upunit(dev);
-
- if (unit >= NUP)
- return (ENXIO);
- return (physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys, uio));
}
/*
--- 735,740 ----
--
Jeff Gilliam {ucbvax,pyramid,nsc}!voder!jeff
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list