	 Hi, Mark.   O Last year we spoke briefly about possible issues integrating Fast-IO and Dollar  for the THETA timeframe.  M As of this week, Fast-IO is pretty much completed and has become very stable. N Currently Fast-IO runs 18%-19% faster (i.e., less CPU time) than an equivalentN $QIO. I expect this percentage to improve more as we implement FASTPATH in our
 disk drivers.   F I'm wondering how we can best go about integrating Fast-IO and Dollar.B First question is: where does Dollar stand with respect to THETA? J Are you running on any THETA baselevels yet? I can see there's a FILES_64 $ facility but it looks pretty sparse.  M The only thing that should be required to have Dollar support Fast-IO (or the L other way around :) would be to write an FDT routine to handle Fast-IO readsO and writes. The only supported Fast-IO functions are read/write virtual/logical L blocks. The FDT routine would have to convert that to a physical read of theN "right" block number, and set up SVAPTE to handle the transfer. No I/O buffer J locking! Note that for cache hits there is already a valid SVA so you can + copy data directly without double mapping.    O You can see the FDT routine for F11 files in SYS\SYSFASTIO\ACP_STD$FASTIO_BLOCK @ which, all things considered, isn't too complex a piece of code.  M I'm also in the process of developing "Guidelines to teaching your driver how O to work with Fast-IO"; something for the V7 Release Notes. Would you be willing N to take a look at it and let me know if it delivers an understandable message? Thanks,      John  9 Modifying drivers to work with Fast-IO				 3-May-1995 JCH & ======================================  K Fast-IO system services are a new way applications can cause I/O to happen. L A major difference between $QIO and Fast-IO is that Fast-IO requires buffersL to be permanently locked down via \buffer objects/. Buffer objects are pagesN of memory that are always valid and have a system space address in addition toL a process space address. It is not necessary (in some cases it is wrong) to ( lock down such user buffers for Fast-IO.  G With some minor effort drivers can be taught about Fast-IO and can take 6 advantage of the performance features Fast-IO offers.   I In any event, drivers must adhere to some basic "ground rules" to prevent   eventual (complicated) crashes.   M Basic Ground Rules - apply to all drivers even if they do not support Fast-IO M -----------------------------------------------------------------------------   L All drivers need to be inspected for conformance to a few simple principles.  J As a rule, drivers that accept IRPs, use them for I/O and then return themL to the I/O Exec will need no modification. This is the "standard I/O model".  L Some drivers will create their own IRPs, use them for an I/O and then delete/ the IRPs they created. This is also acceptable.   J Problems can arise where a driver blindly copies an IRP (e.g., via MOVC orL memcpy() functions) and hands the COPY back to the I/O Exec for disposition.L "I/O exec" means any of the standard OpenVMS I/O completion routines, e.g., F IOC$REQCOM, COM$POST, their variants or the IPL4 postprocessing queue.  F * Any IRP given to the I/O exec that has IRP$V_FASTIO set must either:  = 	1. be an IRP originally given to the driver BY the I/O Exec.      or2 	2. have a negative dispatch address in IRP$L_PID.  M * An IRP supplied by the I/O Exec cannot be deleted if IRP$V_FASTIO is set -- @ it must be returned to the I/O Exec at the end of the operation.  M If a driver is unable to comply with the above restrictions, all FDT routines K should look for IRP$V_FASTIO and if set, abort the I/O with SS$_UNSUPPORTED J status. During driver development it would also be wise to bugcheck if the8 STARTIO routine were to be called with IRP$V_FASTIO set.  5 FAST_FDT Routine - how to code up support for Fast-IO 5 -----------------------------------------------------   H Drivers must supply a FAST_FDT routine if they wish to take advantage ofM improved performance offered by Fast-IO. A pointer to the FAST_FDT routine is N located in DDT offset DDT$PS_FAST_FDT and is usually assembled into the driver# or initialized at driver load time.   N For disk- and tape-like devices there is already a Fast-FDT routine available.M Routine ACP_STD$FASTIO_BLOCK is the Fast-IO equivalent of ACP_STD$READBLK and O ACP_STD$WRITEBLK. Disk and tape class drivers only need to make DDT$PS_FAST_FDT B point to ACP_STD$FASTIO_BLOCK and the driver will support Fast-IO.  I For other devices, special FAST_FDT routines must be written. Here's how:   L The FAST_FDT routine is a single FDT routine that handles all FDT operationsE from Fast-IO system service calls. The only valid function codes are  K IO$_READVBLK, IO$_READLBLK, IO$_WRITEVBLK and IO$_WRITELBLK. When a Fast-IO F system service is called it will verify arguments, prepare an IRP and / eventually call the driver's FAST_FDT routine.    G The FAST_FDT routine is called using a CALL interface with 4 arguments: M pointers to IRP, PCB, UCB and CCB. The FAST_FDT routine must do the same work L as an ordinary FDT routine, but there are some differences that may make the/ FDT routine and I/O postprocessing run faster.    8 These are the guidelines for writing a Fast-FDT routine:  L - At the call, IRP$L_SVAPTE points to the Buffer Object Descriptor (BOD) forI the data buffer. IRP$L_SVAPTE will need to be replaced with one of: a PTE J address (for direct I/O), a BUFIO packet address (for buffered I/O), or 0.I The BOD is useful in either the Direct or Buffered I/O case. BOD offsets  L are defined in module $BODDEF in LIB. NOTE: if a driver detects an error andI aborts a buffered I/O, it must clear IRP$L_SVAPTE before returning to the M I/O exec. Otherwise an attempt may be made to treat IRP$L_SVAPTE as a pointer . to a BUFIO packet, and transfer data randomly.  M - For direct I/O, do not attempt to lock down any buffers; there is no need.  K The caller's buffer is already locked. Instead of locking the buffers it is K only necessary to set up IRP$L_SVAPTE to point to the PTE of the first page K in the caller's buffer. Code that does this is available in SYS$EXAMPLES in  the file SVAPTE-BUFOBJ.C.   O - If a driver creates IRP Extensions (IRPEs) and uses them for direct I/O, then K the driver must lock down the IRPE areas as would be done without Fast-IO.  I This is because Fast-IO WILL unlock IRPEs on I/O completion, but will not J unlock the "main" data buffer in the primary IRP. Even if the IRPE area isH also part of a buffer object it must be locked down since I/O completion: always unlocks IRPEs regardless of status in the main IRP.  N - For buffered I/O it is often not necessary to use a buffer in pool. The userK buffer is double-mapped to a system space VA which is valid from any kernel K mode context, any IPL. The system space VA can be calculated by subtracting O (using 64-bit arithmetic!) the contents of BOD->BOD$PQ_BASEPVA from and adding  M BOD->BOD$PQ_BASESVA to the user buffer address. The resulting 64-bit SVA can  L be used directly instead of having to copy the data between a system buffer  and user space.   H - Only P1, P2 and P3 parameters exist. Anything stored in the IRP P4, P5K or P6 cells is undefined and might not be 0. The driver can use these cells M for scratch memory, but can not count on values persisting across operations. M If driver postprocessing requires knowing the buffer object address (what was L passed to the driver in IRP$L_SVAPTE), IRP$L_QIO_P4 is the standard place to< "remember" this. This is only convention, not a requirement.  O - Do not modify any of the following: PCB$L_ASTCNT, PCB$L_DIOCNT, PCB$L_BIOCNT. I Unlike $QIO, Fast-IO does not charge quotas on a per-operation basis. The J completion code will therefore not return any such quotas. Of course, if aL driver is creating its own IRPs and issuing mutiple I/O requests on its own,@ then it may deduct these quotas as long as it ALSO returns them.  L - Cell IRP$PQ_IOSB contains an always-valid-from-kernel-mode SVA of the IOSAN for the operation. An IOSA is the Fast-IO equivalent of an IOSB and is definedJ in STARLET module $IOSADEF. IOSA member IOSA$L_RESD is a longword reservedM for the driver. The driver may store anything there at any time while the I/O N operation is in progress. When the driver completes the I/O VMS will not writeI anything to this location, so whatever was written last will persist. The D driver may not write to this area after the operation has completed.