Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Alpha Guide to Upgrading Privileged-Code Applications


Previous Contents Index

A.6 Direct I/O Buffer Map (DIOBM)

The Direct I/O Buffer Map (DIOBM) is a new structure that is used to solve the "cross-process PTE problem" for buffers that have been locked into memory for direct I/O.

There are two variants of the DIOBM structure. The first is the primary DIOBM structure. The primary DIOBM structure can be used in the following mutually exclusive ways:

  1. To contain copies of the actual PTEs that map the buffer.
  2. To point to a larger secondary DIOBM structure if the primary DIOBM structure has insufficient room for all the PTEs that map the user buffer.
  3. To manage a PTE window in S0/S1 space onto the actual PTEs that map the buffer if the required PTE count exceeds the capacity of the largest allowable DIOBM structure.

Each of these methods yields a 32-bit system virtual address for the PTEs that map the buffer. This address is valid regardless of process or system context.

The fixed-size DIOBM structure contains room for exactly DIOBM$K_PTECNT_FIX (9) PTEs and is 88 bytes long. Most primary DIOBM structures are fixed-sized and embedded in other structures. For example, the IRP, IRPE, VCRP, and DCBE structures all contain an embedded fixed-sized primary DIOBM structure.

A secondary DIOBM structure can have room for up to ioc$gl_diobm_ptecnt_max PTEs and is used only for PTE copies.

Although the offsets and types for both the primary and secondary DIOBM structures are identical, for clarity, they are described in separate tables (see Table A-6 and Table A-7).

Table A-6 Primary DIOBM structure
Field Type Comments
diobm$ps_aux_diobm DIOBM * This a pointer to a secondary DIOBM structure that is valid if and only if DIOBM$M_AUX_INUSE in diobm$l_flags is set. The secondary DIOBM structure contains copies of the PTE that map the buffer. When a secondary DIOBM is used, the only use for the primary DIOBM is to locate the secondary.
diobm$l_pte_count unsigned int If DIOBM$M_PTE_WINDOW is clear in diobm$l_flags, this cell contains the count of PTEs that have been copied to the PTE vector diobm$q_pte_vector in this DIOBM structure.

If DIOBM$M_PTE_WINDOW is set in diobm$l_flags, this cell contains the count of SPTEs that have been allocated for a PTE window in S0/S1 space to the actual PTEs that map the buffer.

diobm$w_size unsigned short Size of the DIOBM packet in bytes.
diobm$b_type unsigned char Nonpaged pool packet type code, DYN$C_MISC
diobm$b_subtype unsigned char Nonpaged pool packet subtype code, new DYN$C_MISC subtype code DYN$C_DIOBM
diobm$l_flags unsigned int Flag bits.
diobm$v_rel_dealloc bit A bit equal to DIOBM$M_REL_DEALLOC in the diobm$l_flags cell. If set, routine IOC_STD$RELEASE_DIOBM deallocates this DIOBM structure. The routine IOC_STD$FILL_DIOBM sets this bit on any secondary DIOBM structure that it may allocate. The routine IOC_STD$CREATE_DIOBM sets this bit on the primary DIOBM structure that it allocates.
diobm$v_pte_window bit A bit equal to DIOBM$M_PTE_WINDOW in the diobm$l_flags cell. This bit is set if the direct I/O buffer is too large for a DIOBM packet (the buffer requires more than ioc$gl_diobm_ptecnt_max PTEs) and a window in S0 to its PTEs has been allocated. When this bit is set diobm$l_pte_count contains the count of SPTEs that have been allocated and the diobm$l_ptew_sva cell contains the system virtual address that is mapped by the first SPTE allocated for the PTE window. This bit must be clear if diobm$v_aux_inuse is set.
diobm$v_aux_inuse bit A bit equal to DIOBM$M_AUX_INUSE in the diobm$l_flags cell. The diobm$ps_aux_diobm cell contains a pointer to a secondary DIOBM structure if and only if the diobm$v_aux_inuse bit is set. This bit must be clear if diobm$v_pte_window is set.
diobm$v_inuse bit A bit equal to DIOBM$M_INUSE in the diobm$l_flags cell. This flag is an aid to detecting inproper use of DIOBM structures and is used only by the full-checking versions of the routines in the IO_ROUTINES_MON.EXE execlet. This flag is set by the IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM routines and is cleared by the IOC_STD$RELEASE_DIOBM routine. Prior to setting the flag, the IOC_STD$FILL_DIOBM routine checks this flag if the diobm$b_type cell contains the DYN$C_MISC value and diobm$b_subtype contains DYN$C_DIOBM. If the diobm$v_inuse flag is set under these conditions, the IOC_STD$FILL_DIOBM routine declares a INCONSTATE bugcheck.
diobm$v_s0pte_window bit A bit equal to DIOBM$M_S0PTE_WINDOW in the diobm$l_flags cell. This bit is set if the S0/S1 PTE window was used to derive a 32-bit PTE address for this buffer. When this bit is set the diobm$v_pte_window and diobm$v_aux_inuse flags must be clear and the diobm$l_pte_count cell must contain 0.
DIOBM$K_HDRLEN constant Size in bytes of the minimal DIOBM packet header excluding the PTE vector. This is equal to the byte offset of the diobm$q_pte_vector[0] cell (16).
diobm$q_pte_vector PTE[diobm$l_pte_count] Vector of diobm$l_pte_count quadword PTEs that are copies of the PTEs that map the buffer that has been locked for direct I/O. This vector is valid only if both DIOBM$M_AUX_INUSE and DIOBM$M_PTE_WINDOW in diobm$l_flags are clear.
DIOBM$K_PTECNT_FIX constant This constant specifies the number of PTE entries (9) that fit into the PTE vector in a fix-sized DIOBM structure.
DIOBM$K_PTECNT_MAX_UNI constant This constant specifies the number of PTE entries (94) that fit into the PTE vector in the largest allowable DIOBM structure on an uniprocessor system.
DIOBM$K_PTECNT_MAX_SMP constant This constant specifies the number of PTE entries (430) that fit into the PTE vector in the largest allowable DIOBM structure on an SMP system.
diobm$ps_ptew_sva void * The lowest S0/S1 space virtual address that is mapped by the PTEs that have been allocated for the window onto the direct I/O buffer PTEs. This cell is used to deallocate the PTE window. This cell is overlaid on a portion of diobm$q_pte_vector since their use is mutually exclusive. This cell is valid if and only if DIOBM$M_PTE_WINDOW in diobm$l_flags is set.
DIOBM$M_NORESWAIT constant This is an option bit mask for the flags parameter to the IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM routines.

When this option bit is set and there are insufficient resources for the needs of these routines an error status is returned to their callers instead of putting the process into a resource wait state.

Table A-7 Secondary DIOBM structure
Field Type Comments
diobm$ps_aux_diobm DIOBM * This cell must be zero in a secondary DIOBM structure.
diobm$l_pte_count unsigned int Contains the number of PTEs that can fit into the diobm$q_pte_vector in this DIOBM structure.
diobm$w_size unsigned short Size of the DIOBM packet in bytes.
diobm$b_type unsigned char Nonpaged pool packet type code, DYN$C_MISC
diobm$b_subtype unsigned char Nonpaged pool packet subtype code, new DYN$C_MISC subtype code DYN$C_DIOBM
diobm$l_flags unsigned int Flag bits.
diobm$v_rel_dealloc bit A bit equal to DIOBM$M_REL_DEALLOC in the diobm$l_flags cell. If set, routine IOC_STD$RELEASE_DIOBM deallocates this DIOBM structure.
diobm$v_pte_window bit A bit equal to DIOBM$M_PTE_WINDOW in the diobm$l_flags cell. This bit must be clear in a secondary DIOBM structure.
diobm$v_aux_inuse bit A bit equal to DIOBM$M_AUX_INUSE in the diobm$l_flags cell. This bit must be clear in a secondary DIOBM structure.
diobm$v_s0pte_window bit A bit equal to DIOBM$M_S0PTE_WINDOW in the diobm$l_flags cell. This bit must be clear in a secondary DIOBM structure.
diobm$q_pte_vector PTE[diobm$l_pte_count] Vector of diobm$l_pte_count quadword PTEs that are copies of the PTEs that map the buffer that has been locked for direct I/O.

A.7 Function Decision Table (FDT)

This section describes the additions to the driver Function Decision Table (FDT) structure (see Table A-8).

Table A-8 FDT Structure Changes
Field Type Comments
fdt$q_ok64bit unsigned int64 A 64-bit mask corresponding to the 64 possible I/O function codes. The corresponding bit is set if the function supports a 64-bit $QIO p1 parameter value. This cell is initialized to zero by the MACRO-32 macro FDT_INI, the BLISS macro FDTAB, and in the prototype FDT, DRIVER$FDT, which is used by drivers written in C. This cell has been added to the end of the existing FDT structure.

A.8 I/O Request Packet (IRP)

This section describes the additions and changes to cells in the I/O Request Packet (IRP) structure. The significant IRP changes are:

  1. The IRP resembles a 64-bit capable ACB64 structure instead of the existing ACB structure.
  2. A fixed-size primary DIOBM is embedded in the IRP for use in deriving a 32-bit system virtual address for the PTEs that map a buffer locked into memory for direct I/O.
  3. The IRP cells that contain copies of the 64-bit $QIO parameter values and the caller's IOSB address has been expanded from 32-bits to 64-bits.
  4. Any cells overlaid on the irp$l_ast, irp$l_astprm, or irp$l_iosb cells moves to the low-order longword of their quadword replacements.
  5. Alternative cell names have been defined for the ast, astprm, and iosb cells that can be used for arbitrary parameters in internal IRPs.

The size of an IRP has increased by 160 bytes (43%), from 376 to 536 bytes in size (see Table A-9).

Table A-9 IRP Changes
Field Type Comments
irp$b_mode unsigned char This is an existing cell in the IRP that contains the caller's mode in the low-order 2 bits. The irp$l_acb_flags cell is considered valid by SCH$QAST if and only if ACB$M_FLAGS_VALID mask is set in this cell. The ACB$M_FLAGS_VALID mask is always set in this cell by EXE$QIO when the IRP is allocated.
irp$l_acb64x_offset int Offset to the ACB64X structure embedded in this IRP. This cell is considered valid by SCH$QAST if and only if ACB$M_64BITS is set in the irp$l_acb_flags cell. This cell is initialized to the offset value of the irp$pq_acb64_ast field. This cell corresponds to the acb64$l_acb64x cell Because this cell is at the same offset as the acb$l_ast cell, the irp$l_ast cell has been removed.
irp$l_acb_flags unsigned int This cell has been initialized to the mask value ACB$M_64BITS to indicate that the irp$l_acb64x_offset field contains an offset to the ACB64X structure. Corresponds to the acb$l_flags cell.
irp$l_thread_pid int Corresponds to the acb$l_thread_pid cell. Reserved for use by the Kernel Threads project.
irp$pq_acb64_ast VOID_FUNC_PQ This cell corresponds to the acb64$pq_ast cell and replaces the irp$l_ast cell.
irp$l_ast - This cell has been removed. It has been replaced by the irp$pq_acb64_ast cell.
irp$l_shd_iofl IRP * This is an existing cell that contains the link to the cloned shadowing IRPs. This cell was overlaid on irp$l_ast and is now overlaid on the low-order longword of the irp$pq_acb64_ast cell.
irp$l_iirp_p0 int Generic parameter cell that is available in internal IRPs. This cell overlays the low-order longword of the irp$pq_acb64_ast cell and is intended for use by components that use the irp$l_ast cell for this purpose.
irp$q_acb64_astprm int64 This cell corresponds to the acb64$q_astprm cell and replaces the irp$l_astprm cell.
irp$l_astprm - This cell has been removed. It is replaced by the irp$q_acb64_astprm cell.
irp$l_shad SHAD * This is an existing cell in IRPs cloned by shadowing that points to the SHAD structure. This cell was overlaid on irp$l_astprm and is now overlaid on the low-order longword of the irp$q_acb64_astprm cell.
irp$l_hrb HRB * This is an existing cell in MSCP server IRPs that points to a Host Request Block structure. This cell was overlaid on irp$l_astprm and is now overlaid on the low-order longword of the irp$q_acb64_astprm cell.
irp$l_mv_tmo int This cell is used in internal mount verification IRPs to contain the timeout value. This cell overlays the low-order longword of the irp$q_acb64_astprm cell and is intended for use by components that currently use the irp$l_astprm cell for this purpose.
irp$l_iirp_p1 int Generic parameter cell that is available in internal IRPs. This cell overlays the low-order longword of the irp$q_acb64_astprm cell and is intended for use by components that use the irp$l_astprm cell for this purpose.
irp$q_user_thread_id uint64 Unique user thread identifier. Corresponds to the acb64$q_user_thread_id cell. Reserved for use by the Kernel Threads project.
irp$pq_iosb VOID_PQ 64-bit pointer to the caller's IOSB. This cell replaces irp$l_iosb.
irp$l_iosb - This cell has been removed. It is replaced by the irp$pq_iosb cell.
irp$l_cln_wle unsigned int This is an existing cell that contains the shadowing write log state. This cell was overlaid on irp$l_iosb and is now overlaid on the low-order longword of the irp$pq_iosb cell.
irp$l_iirp_p2 int Generic parameter cell that is available in internal IRPs. This cell overlays the low-order longword of the irp$pq_iosb cell and is intended for use by components that use the irp$l_iosb cell for this purpose.
irp$pq_va_pte PTE_PQ A 64-bit pointer to the actual PTEs that map the user buffer. If the user buffer is not in shared system space, then this PTE virtual address is only valid in the caller's process context.
irp$l_svapte PTE * A 32-bit pointer to PTE values that map the user buffer. The PTE values may be copies of the actual PTEs in Page Table Space that map the user buffer. If zero, then no PTEs have been locked for this request. Note that for compatibility with existing drivers, this cell remains overlaid on irp$ps_bufio_pkt and this use is valid only if IRP$M_BUFIO is clear in irp$l_sts. Note also that this cell contains a pointer into the CPT structure if IRP$M_CACHEIO is set in irp$l_sts2.
irp$ps_bufio_pkt BUFIO * Pointer for the buffered I/O packet for this request. If zero, then no packet has been allocated for this request. Note that for compatibility with existing drivers, this cell remains overlaid on irp$l_svapte and this use is valid only if IRP$M_BUFIO is set in irp$l_sts.
irp$r_diobm DIOBM Embedded fixed-size primary "direct I/O buffer map" structure. This embedded DIOBM structure is valid if and only if irp$l_svapte points to a set of PTEs whose pages have been locked down for direct I/O. Specifically, the DIOBM is in use when both IRP$M_BUFIO and IRP$M_CACHEIO in irp$l_sts are clear and the irp$l_svapte cell contains a non-zero value. See Section A.6 for a complete description of the DIOBM structure.
irp$q_qio_p1 int64 Copy of device dependent $QIO parameter p1. The low order 32-bits of this cell remain accesible via irp$l_qio_p1
irp$q_qio_p2 int64 Copy of device dependent $QIO parameter p2. The low order 32-bits of this cell remain accesible via irp$l_qio_p2
irp$q_qio_p3 int64 Copy of device dependent $QIO parameter p3. The low order 32-bits of this cell remain accesible via irp$l_qio_p3
irp$q_qio_p4 int64 Copy of device dependent $QIO parameter p4. The low order 32-bits of this cell remain accesible via irp$l_qio_p4
irp$q_qio_p5 int64 Copy of device dependent $QIO parameter p5. The low order 32-bits of this cell remain accesible via irp$l_qio_p5
irp$q_qio_p6 int64 Copy of device dependent $QIO parameter p6. The low order 32-bits of this cell remain accesible via irp$l_qio_p6

A.9 I/O Request Packet Extension (IRPE)

This section describes the additions and changes to cells in the I/O Request Packet Extension (IRPE) structure. An IRPE structure can contain additional driver-specific information that needs to be associated with an IRP. It can also be used to manage additional buffers that are locked down for direct I/O.

If the IRP$M_EXTEND bit is set in irp$l_sts then the irp$l_extend cell contains a pointer to an associated IRPE structure. Similarly, if the IRPE$M_EXTEND bit is set in the irpe$l_sts cell, then the irpe$l_extend cell contains a pointer to another IRPE. In general, if there is an IRPE cell with the name irpe$X and an IRP cell with then name irp$X, then the cells must be at the same offsets such that the IRP and the IRPE can be used interchangeably in contexts that depend only on these common cells.

Currently, a single IRPE structure can be used to keep track of two separate regions of locked down pages. The new IRPE structure can only manage a single region of locked down pages and contains a single fixed-size primary DIOBM structure for that purpose (see Table A-10).

Table A-10 IRPE Changes
Field Type Comments
irpe$b_rmod unsigned char Requestor's access mode. This corresponds to the irp$b_rmod cell. The space for this IRPE cell was reserved but the cell was not previously formally defined. The addition of this cell facilitates the usage of an IRPE with the EXE_STD$READLOCK routines because the irpe$b_rmod cell is one of the required implicit inputs.
irpe$l_oboff unsigned int Original byte offset into first page for buffer locked into memory. This corresponds to the irp$l_oboff cell that was added to the IRP on OpenVMS Alpha but was not formally defined in the IRPE. This corrects that omission.
irpe$q_driver_p0 int64 Available for use by driver. This cell is overlaid on what was previously filler space.
irpe$l_driver_p0 int Available for use by driver. This cell is overlaid on the low-order 32-bits of irpe$q_driver_p0.
irpe$l_driver_p1 int Available for use by driver. This cell is overlaid on the high-order 32-bits of irpe$q_driver_p0.
irpe$q_driver_p2 int64 Available for use by driver. This cell is overlaid on what was previously filler space.
irpe$l_driver_p2 int Available for use by driver. This cell is overlaid on the low-order 32-bits of irpe$q_driver_p2.
irpe$l_driver_p3 int Available for use by driver. This cell is overlaid on the high-order 32-bits of irpe$q_driver_p2.
irpe$pq_va_pte PTE_PQ A 64-bit pointer to the actual PTEs that map the user buffer. If the user buffer is not in shared system space, then this PTE virtual address is only valid in the caller's process context.
irpe$l_svapte PTE * A 32-bit pointer to a copy of the PTEs that map the user buffer. If zero, then no PTEs have been locked for this request. This cell replaces the irpe$l_svapte1 cell.
irpe$l_svapte1 - This cell has been removed. It is replaced by the irpe$l_svapte cell.
irpe$l_bcnt unsigned int Byte count for buffer locked into memory. This cell replaces the irpe$l_bcnt1 cell.
irpe$l_bcnt1 - This cell has been removed. It is replaced by the irpe$l_bcnt cell.
irpe$l_boff unsigned int Byte offset into first page for buffer locked into memory. This cell replaces the irpe$l_boff1 cell.
irpe$l_boff1 - This cell has been removed. It is replaced by the irpe$l_boff cell.
irpe$r_diobm DIOBM Embedded fixed-size primary "direct I/O buffer map" structure. This embedded DIOBM structure is valid if and only if the irpe$l_svapte cell contains a non-zero value. See Section A.6 for a complete description of the DIOBM structure.
irpe$l_svapte2 - This cell has been removed. It was used to contain a pointer to the first PTE for a second buffer that was locked into memory. If zero, then there was no second buffer.
irpe$l_bcnt2 - This cell has been removed. It was used for the byte count for the second buffer locked into memory.
irpe$l_boff2 - This cell has been removed. It was used for the byte offset for the second buffer locked into memory.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
6466PRO_007.HTML