Skip to content

[STORPORT][VIOSTOR] virtio-blk storage path: per-request SCSI contexts, LUN PDOs, and a Storport miniport - #9530

Draft
jr551 wants to merge 6 commits into
reactos:masterfrom
jr551:virtio-storage-rework
Draft

[STORPORT][VIOSTOR] virtio-blk storage path: per-request SCSI contexts, LUN PDOs, and a Storport miniport#9530
jr551 wants to merge 6 commits into
reactos:masterfrom
jr551:virtio-storage-rework

Conversation

@jr551

@jr551 jr551 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Draft — opening for early review while I finish the last runtime checks.

What this adds

A working virtio-blk storage path for ReactOS, in six commits:

  1. Fix the vendored VirtIO library buildVirtIO.h, virtio_ring.h, virtio_pci.h used PHYSICAL_ADDRESS/ULONG without including osdep.h, and virtio_pci.h declared a function FORCEINLINE that isn't defined for kernel code here. Guarded with __REACTOS__ so the files still match upstream for other consumers.
  2. STORPORT: per-request SCSI path — replaces the stub request path. PortFdoScsi allocates a per-request STOR_REQUEST_CONTEXT + miniport SrbExtension in one allocation, publishes it in Srb->SrbExtension, and serializes submission with StartIoLock. StorPortNotification(RequestComplete) finds the context via the SrbExtension back-pointer and queues completions on a 16-byte-aligned SLIST drained by PortCompletionDpc at DISPATCH_LEVEL — no work items, no single-flight gate, so multiple requests can be in flight. Also implements IssueDpc, per-request StorPortGetScatterGatherList (built from the IRP's MDL PFN array), StorPortGetPhysicalAddress (translates inside the SRB buffer via the MDL PFNs, not a process-dependent VA), and StorPortSynchronizeAccess via KeSynchronizeExecution.
  3. STORPORT: enumerate LUNs as PDOs — real BusRelations list, PortPdoPnp (START/QUERY_ID/QUERY_DEVICE_TEXT/TargetDeviceRelation/REMOVE), PortPdoDeviceControl for the storage IOCTLs a disk PDO receives.
  4. VIOSTOR: legacy virtio-blk Storport miniport — new miniport for PCI\VEN_1AF4&DEV_1001 (transitional/legacy virtio-blk): single split virtqueue, line interrupts, direct descriptors. Request wire format follows the BSD-3-Clause virtio-win viostor sources; Storport integration is ReactOS-specific. Per-request state in Srb->SrbExtension; completions drained from the used ring in the ISR. Negotiates FLUSH, CONFIG_WCE, SEG_MAX, SIZE_MAX. Debug output defaults off.
  5. VIOSTOR: per-device unit serial — was answering VPD 0x80/0x83 with a fixed string so every virtio disk reported the same ID; now derives a stable serial from PCI bus/slot + capacity.
  6. VIOSTOR: negotiate VIRTIO_BLK_F_RO — was presenting read-only disks as writable; now fails write CDBs early with SRB_STATUS_INVALID_REQUEST and sets the WP bit in MODE_SENSE.

Testing

Built i386 Release; booted the live CD under QEMU (qemu-system-i386, -M pc) with a virtio-blk-pci bench disk and ran a stress.exe battery plus sequential/random throughput benchmarks.

Throughput vs the previous single-flight build (transitional virtio): SEQ write 126.97 MB/s (8.2x), SEQ read 233.06 MB/s (14.4x); legacy virtio: SEQ write 170.33 MB/s (11.2x), SEQ read 447.23 MB/s (27.5x). Debug serial log over the run: 2417 completions, 2416 success, 0 errors, 0 busy, 0 duplicate completions, 0 context mismatches, 0 SG leaks, 0 bugchecks.

Stress variants all passed with 0 bugchecks: modern, legacy, packed, twodisk, lowmem, pause, reset.

Notes

  • The storport request-path rework is the load-bearing change; viostor depends on it (upstream StorPortGetScatterGatherList was an UNIMPLEMENTED stub and IssueDpc did not exist).
  • MultipleRequestPerLu is set TRUE — the per-request context + SLIST completion path is what makes that safe.
  • No JIRA ticket; found by inspection + measurement. Happy to file one if a reviewer wants the reference.

Marked draft pending a final clean re-run of the stress battery on this exact branch.

John Rowe added 6 commits September 11, 2026 13:25
The vendored virtio-win library does not build in-tree as shipped:

- VirtIO.h, virtio_ring.h and virtio_pci.h use PHYSICAL_ADDRESS/ULONG
  without including osdep.h; they only compile when the consumer happens
  to include a kernel header first.
- virtio_pci.h declares virtio_get_queue_descriptor_size() with
  FORCEINLINE, which is not defined for kernel code in this tree.

Guard the additions with __REACTOS__ so the files still match upstream
for other consumers.
Replace the stub request path with a real implementation:

- PortFdoScsi allocates a per-request STOR_REQUEST_CONTEXT (from a
  look-aside list) plus the miniport's SrbExtension in one allocation,
  publishes it in Srb->SrbExtension, marks the IRP pending before calling
  HwStartIo, and serializes submission with StartIoLock (now actually
  initialized in PortAddDevice).
- StorPortNotification(RequestComplete) finds the context through the
  SrbExtension back-pointer, maps SrbStatus to NTSTATUS, preserves
  IoStatus.Information for SRB_STATUS_DATA_OVERRUN, and queues the
  completion on a 16-byte-aligned SLIST drained by PortCompletionDpc at
  DISPATCH_LEVEL -- no work items, no single-flight gate, so multiple
  requests can be in flight.
- StorPortNotification(IssueDpc) now sets *Succ and forwards the DPC
  arguments; miniport DPCs requested from an ISR are deferred through
  PendingMiniportDpc and queued by the port's interrupt wrapper.
- StorPortGetScatterGatherList builds a per-request SG list from the
  IRP's MDL PFN array; StorPortExtendedFunction gains
  ExtFunctionPutScatterGatherList to free it.
- StorPortGetPhysicalAddress translates addresses inside the SRB data
  buffer through the MDL PFN array instead of calling
  MmGetPhysicalAddress on a process-dependent VA.
- StorPortSynchronizeAccess is implemented via KeSynchronizeExecution.
- PortPdoScsi forwards to PortFdoScsi so SCSI requests sent to a PDO
  reach the miniport.
- PortFdoQueryBusRelations returns a real DEVICE_RELATIONS list built
  from the PDO list under PdoListLock, instead of scanning the bus and
  reporting zero children.
- PortPdoPnp implements START_DEVICE, QUERY_ID (hardware/compatible/
  instance ids built from the inquiry data), QUERY_DEVICE_TEXT,
  TargetDeviceRelation, and REMOVE_DEVICE. BusRelations on a PDO are
  completed without touching IoStatus so partmgr's relations survive.
- PortPdoDeviceControl handles the storage IOCTLs a disk PDO receives
  (STORAGE_QUERY_PROPERTY, IOCTL_DISK_GET_LENGTH_INFO and friends);
  PortDispatchDeviceControl routes PDO requests to it.
- IRP_MN_REMOVE_DEVICE on the FDO drains the request-context look-aside
  list.
New miniport for PCI\VEN_1AF4&DEV_1001 (transitional/legacy virtio-blk):
single split virtqueue, line interrupts, direct descriptors. The request
wire format follows the BSD-3-Clause virtio-win viostor sources; the
Storport integration is ReactOS-specific.

- INQUIRY, READ_CAPACITY(16), MODE_SENSE, TEST_UNIT_READY, VERIFY and
  REQUEST_SENSE are answered locally; READ/WRITE/FLUSH go on the queue.
- Per-request state lives in Srb->SrbExtension; completions are drained
  from the used ring in the ISR and reported via
  StorPortNotification(RequestComplete).
- Negotiates FLUSH, CONFIG_WCE, SEG_MAX and SIZE_MAX; the transfer and
  physical-breaks limits reported to the port come from the negotiated
  device config.
- Debug output through the shared virtio kdebugprint sink defaults to
  off (virtioDebugLevel = 0, bDebugPrint = 0).
The driver answered VPD pages 0x80 and 0x83 with a fixed string
("ROS-VIRTIO-9241-0001"), so every virtio disk reported the same
unique ID. The virtio-blk config space carries no serial field, so
derive a stable serial from the PCI bus/slot and device capacity
instead.
The feature mask dropped VIRTIO_BLK_F_RO, so a read-only virtio disk
was presented as writable and writes failed at the device with a
generic I/O error. Negotiate the feature, fail write CDBs early with
SRB_STATUS_INVALID_REQUEST, and set the WP bit in the MODE_SENSE
device-specific parameter byte.
@github-actions github-actions Bot added the drivers Kernel mode drivers and frameworks label Sep 12, 2026
@HBelusca HBelusca added the AI-assisted PR PRs that are likely written with AI with a very high probability. label Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-assisted PR PRs that are likely written with AI with a very high probability. drivers Kernel mode drivers and frameworks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants