Re: [PATCH RFC] drivers/rufs: add Rust UFS host controller driver
From: Andreas Hindborg
Date: Sat Sep 12 2026 - 07:25:30 EST
"Bean Huo" <beanhuo@xxxxxxxx> writes:
> On Sat, 2026-09-12 at 00:52 +0900, Jaemyung Lee via B4 Relay wrote:
>> From: Jaemyung Lee <jaemyung.lee@xxxxxxxxxxx>
>>
>> Add a Rust UFS host controller driver that exposes UFS logical units as
>> native blk-mq block devices without depending on the SCSI midlayer.
>>
>> Implement host controller setup, UIC link startup and power-mode
>> configuration, device and unit descriptor discovery, query operations, and
>> SCSI protocol command construction. Support normal read, write, flush, and
>> discard I/O with coherent UTP descriptors and owned streaming DMA mappings.
>>
>> Provide both single-doorbell and multi-circular-queue transfer backends.
>> Map shared blk-mq tags directly to UFS task tags, retain request ownership
>> while commands are in flight, dispatch completion per MCQ completion queue,
>> and return polled completions through the blk-mq completion batch.
>>
>> Add PCI and Qualcomm platform frontends. The PCI frontend supports the QEMU
>> UFS controller and existing Intel and Samsung IDs. The Qualcomm frontend
>> provides the clocks, PHY, reset, interconnect, power-domain, OPP, GPIO, and
>> controller-specific initialization needed by supported SoCs.
>>
>> This establishes normal-I/O support for UFSHCI single-doorbell and MCQ
>> controllers. Full timeout recovery, error handling, and power management
>> are left for follow-up work.
>>
>> Signed-off-by: Jaemyung Lee <jaemyung.lee@xxxxxxxxxxx>
>> ---
>> This RFC introduces RUFS, a UFS host controller driver that sits directly
>> on the block layer and does not use the SCSI midlayer. UFS logical units
>> are exposed as native blk-mq block devices, the same way NVMe namespaces
>> are. The driver is written in Rust.
>>
>> Why decouple UFS from SCSI
>> --------------------------
>>
>> The existing UFS driver is built on the SCSI subsystem. That made sense
>> historically: UFS adopted the SCSI Architecture Model as its application
>> layer, so reusing the SCSI midlayer's command queuing, error handling,
>> power management, and logical-unit addressing let UFS reach Linux quickly
>> and reliably. ufshcd bridges the SCSI midlayer to UFS Protocol Information
>> Units.
>>
>> That foundation has become a source of friction. The evolution of UFS is
>> governed by JEDEC and increasingly includes UFS-specific features outside
>> the SCSI command set standardized by T10. These features must still be
>> expressed through, and constrained by, a SCSI-shaped driver. Features that
>> are meaningful only to UFS are difficult to land in a subsystem whose
>> maintainers reasonably want to keep SCSI focused on SCSI, and block layer
>> or shared infrastructure changes that UFS needs end up mediated through
>> SCSI's priorities. In practice UFS is treated as an add-on to SCSI rather
>> than as a first-class storage interface, and a significant amount of UFS
>> functionality lives off-tree as a result, with the back- and forward-
>> porting cost that implies.
>>
>> We propose to decouple UFS from SCSI with a standalone driver that sits
>> directly on the block layer, alongside drivers like NVMe. This lets
>> JEDEC-specific features evolve independently of T10, gives UFS
>> its own dedicated review surface, and removes the impedance mismatch
>> between the UFS data model and the SCSI command model. UFS uses a subset of
>> the SCSI command set within command UPIUs, so the driver can construct the
>> required CDBs directly without depending on the SCSI midlayer.
>>
>> The driver is designed around the UFS and UFSHCI specifications rather than
>> as a line-by-line translation of ufshcd. Its target is JEDEC UFS 4.1 and
>> UFSHCI 4.1.
>>
>> Why Rust
>> --------
>>
>> The architectural question above would be the same for a C driver. We chose
>> Rust because UFS features arrive at a high pace, and turning new
>> specification features into stable, validated code on tight timelines is
>> where memory- and concurrency-safety guarantees pay off: fewer classes of
>> bugs reach production, and iteration is faster. Rust's growing acceptance
>> in the kernel makes a block-layer-native UFS driver a realistic
>> architecture to evaluate.
>>
>> Initial feature set
>> --------------------
>>
>> The new driver supports single-doorbell and multi-circular-queue operation,
>> PCI and Qualcomm platform frontends, logical-unit discovery, and normal
>> read, write, flush, and discard I/O. It uses shared blk-mq tags as UFS task
>> tags, keeps request ownership through completion, and uses owned DMA
>> mappings for the complete I/O lifetime.
>>
>> Full timeout recovery, error handling, and power management remain
>> follow-up work.
>>
>> Patch layout and dependencies
>> -----------------------------
>>
>> The single patch contains the complete driver. This keeps review focused on
>> the RUFS architecture and the SCSI-independent blk-mq model.
>>
>> The driver depends on Rust block, DMA, IRQ, and platform abstractions that
>> are intentionally excluded from this posting. Some of these abstractions
>> have already been posted to the list, most notably in the Rust null block
>> driver v2 series, the Ownable/OwnableRefCounted page series, and the
>> impl_flags extensions. The remaining abstractions are new and will be
>> posted as separate series before the first non-RFC version of this driver.
>>
>> A buildable tree based on v7.3-rc2 with all dependencies and this patch is
>> at:
>>
>> https://github.com/SamsungDS/rufs/tree/rfc/rufs-public
>>
>> Testing
>> -------
>>
>> The v7.2 development version has been exercised with SDB and MCQ on the
>> QEMU UFS model, including ext4 fio workloads and module load/unload cycles.
>> SDB probe and normal I/O have also been exercised on Intel PCI and Qualcomm
>> UFS hardware. The current port has been compile-tested independently with
>> PCI-only and Qualcomm-platform-only configurations.
>>
>> The exact v7.2 tree used for the hardware measurements is available at:
>>
>> https://github.com/SamsungDS/rufs/tree/rufs-7.2
>>
>> On Intel UFS 2.1 hardware, 4 KiB direct io_uring at QD32/job gave
>> these optimized-mode ranges over 1/2/4 jobs (three samples):
>>
>> Workload Op RUFS kIOPS C kIOPS Difference
>> -------- ----- ----------- ----------- ---------------
>> randread read 48.91-61.26 41.56-41.60 +17.6% to +47.4%
>> randwrite write 8.19-8.30 8.21-8.22 -0.4% to +1.1%
>> randrw read 5.26-5.34 5.28-5.38 -0.9% to -0.4%
>> randrw write 5.27-5.34 5.29-5.37 -0.8% to -0.5%
>>
>> The coefficient of variation (CV), calculated as the sample standard
>> deviation divided by the sample mean, measures run-to-run variability
>> relative to the mean. CV is a descriptive statistic; no normal or other
>> distribution was fitted to model the variation. The accompanying
>> two-sided 95% confidence intervals for the mean used Student's
>> t-distribution because each point contains only three samples. Those
>> intervals assume independent, approximately normally distributed sample
>> means and should be interpreted cautiously at this sample count.
>>
>> RUFS randread had a CV of 28-57%, versus below 0.8% for C. Its apparent
>> gain therefore has low confidence and should be treated as preliminary.
>> Both drivers also logged platform UIC errors. Stable write and mixed
>> points differed by no more than 1.1%.
>>
>> Feedback
>> --------
>>
>> Comments on the decision to bypass the SCSI midlayer, the blk-mq model used
>> in its place, and the proposed prerequisite API boundaries would be
>> especially welcome.
>
> Jaemyung,
>
> thanks sharing.
>
> You still use scsi everywhere in your implementation protocol/scsi.rs builds
> READ_10/16, WRITE_10/16, SYNCHRONIZE_CACHE and UNMAP CDB, so "decouple UFS from
> SCSI" really means "copy a small part of sd and the SCSI error handling into a
> UFS driver." while JEDEC defines the UFS application layer as SCSI, the SCSI
> work doesn't go away, you just move somewhere else, and it has to be written
> again.
See my response to Greg. The SCSI specific code in this driver is very
minimal.
>
> The "friction" claim is weak. SCSI has already been changed to fit UFS. Two
> examples: UFS now uses SCSI simple copy, group number in scsi write command.
>
> I doubt how far this can go. do we really need to pay effort for a new RUST UFS
> driver, I am not very confident, unless SCSI is removed from the UFS spec and
> JEDEC defines native UFS commands, or we talk to the device directly with UPIU.
> please name the JEDEC feature that the SCSI midlayer really blocked, or that was
> historial issue which has been fixed.
I am sure the UFS experts will be able to answer this better than me.
> I would also like to see the heavy and hard parts, because they are the parts
> that decide if this design worrks:
>
> 1, error handling: abort, LU reset, retries with limits, sense decoding, this is
> the very hard part of UFS driver.
I agree. However, we decided to get the discussion going with a smaller
feature set. We can build an efficient feature complete driver, but we
would really like to talk to the community about it first.
> 2, user-space tools interface: SG_IO and bsg (sg3_utils, ufs-utils, FFU with
> WRITE BUFFER), and the UFS sysfs tree..
On the account of this not being a scsi driver, some changes would have
to be made. But we should be able support
/sys/bus/platform/drivers/ufshcd/* just fine.
> Did any AI tool help write this code? If so, please add the Assisted-by: tag.
We use AI for code review and spell checking, so I guess the tag is warranted.
Best regards,
Andreas Hindborg