For Ubuntu 16.04:
$ modprobe -r ahci
$ sudo modprobe uio
$ sudo modprobe uio_pci_generic
$ echo "0x8086 0x1d02" > /sys/bus/pci/drivers/uio_pci_generic/new_id
$ ls /sys/class/uio0
$ lspci -v -d :0x1d02 | grep "Kernel driver in use"
$ chmod u+w /sys/class/uio/uio0/device/resource
$ sudo modprobe uio_dmem_genirq
$ echo "0x8086 0x1d02" > /sys/bus/pci/drivers/uio_dmem_genirq/new_id
https://lwn.net/Articles/232575/ http://alvarom.com/2014/12/17/linux-user-space-drivers-with-interrupts/ http://lxr.free-electrons.com/source/drivers/uio/uiocif.c https://www.kernel.org/doc/htmldocs/uio-howto/index.html http://lxr.free-electrons.com/source/drivers/uio/uiodmemgenirq.c http://www.osadl.org/projects/downloads/UIO/user/ http://dpdk.org/browse/dpdk/tree/tools/dpdknic_bind.py
Bind our AHCI to uiodmemgenirq
#
Let's check the disk read and write performance:
``` $ hdparm -Tt /dev/sdb
/dev/sdb: Timing cached reads: 17790 MB in 2.00 seconds = 8904.58 MB/sec Timing buffered disk reads: 1592 MB in 3.00 seconds = 530.02 MB/sec $ mkfs.ext4 /dev/sdb $ mount /dev/sdb /tmp/ $ dd if=/dev/zero of=/tmp/output conv=fdatasync bs=384k count=1k; rm -f /tmp/output 1024+0 records in 1024+0 records out 402653184 bytes (403 MB, 384 MiB) copied, 1.03824 s, 388 MB/s $ umount /tmp ```
Let's find out what device we want to use here, for this machine we pick /dev/sdb: We can find information about this device using udevadm:
``` $ udevadm info -a -n /dev/sdb
Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:1f.2/ata1/host1/target1:0:0/1:0:0:0/block/sdb': KERNEL=="sdb" SUBSYSTEM=="block" DRIVER=="" ATTR{alignmentoffset}=="0" ATTR{capability}=="50" ATTR{discardalignment}=="0" ATTR{events}=="" ATTR{eventsasync}=="" ATTR{eventspollmsecs}=="-1" ATTR{extrange}=="256" ATTR{inflight}==" 0 0" ATTR{range}=="16" ATTR{removable}=="0" ATTR{ro}=="0" ATTR{size}=="976773168" ATTR{stat}==" 25806 0 6504908 11036 17892 34298 996249960 498624 0 26420 509656"
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host1/target1:0:0/1:0:0:0': KERNELS=="1:0:0:0" SUBSYSTEMS=="scsi" DRIVERS=="sd" ATTRS{deviceblocked}=="0" ATTRS{devicebusy}=="0" ATTRS{dhstate}=="detached" ATTRS{ehtimeout}=="10" ATTRS{evtcapacitychangereported}=="0" ATTRS{evtinquirychangereported}=="0" ATTRS{evtlunchangereported}=="0" ATTRS{evtmediachange}=="0" ATTRS{evtmodeparameterchangereported}=="0" ATTRS{evtsoftthresholdreached}=="0" ATTRS{inquiry}=="" ATTRS{iocounterbits}=="32" ATTRS{iodonecnt}=="0xae77" ATTRS{ioerrcnt}=="0x27d" ATTRS{iorequestcnt}=="0xaf67" ATTRS{model}=="Samsung SSD 850 " ATTRS{queuedepth}=="31" ATTRS{queuerampupperiod}=="120000" ATTRS{queuetype}=="none" ATTRS{rev}=="2B6Q" ATTRS{scsilevel}=="6" ATTRS{state}=="running" ATTRS{timeout}=="30" ATTRS{type}=="0" ATTRS{vendor}=="ATA " ATTRS{vpdpg80}=="" ATTRS{vpd_pg83}==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host1/target1:0:0': KERNELS=="target1:0:0" SUBSYSTEMS=="scsi" DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host1': KERNELS=="host1" SUBSYSTEMS=="scsi" DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1': KERNELS=="ata1" SUBSYSTEMS=="" DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2': KERNELS=="0000:00:1f.2" SUBSYSTEMS=="pci" DRIVERS=="ahci" ATTRS{brokenparitystatus}=="0" ATTRS{class}=="0x010601" ATTRS{consistentdmamaskbits}=="64" ATTRS{d3coldallowed}=="1" ATTRS{device}=="0x1d02" ATTRS{dmamaskbits}=="64" ATTRS{driveroverride}=="(null)" ATTRS{enable}=="1" ATTRS{index}=="0" ATTRS{irq}=="55" ATTRS{label}=="PCH Integrated SATA Controller" ATTRS{localcpulist}=="0-9,20-29" ATTRS{localcpus}=="0000,00000000,00000000,00000000,00000000,00000000,00000000,3ff003ff" ATTRS{msibus}=="1" ATTRS{numanode}=="0" ATTRS{subsystemdevice}=="0x3582" ATTRS{subsystem_vendor}=="0x8086" ATTRS{vendor}=="0x8086"
looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" ```
lspci
gives us some more information:
$ lspci -vvv -d :0x1d02:
00:1f.2 SATA controller: Intel Corporation C600/X79 series chipset 6-Port SATA AHCI Controller (rev 06) (prog-if 01 [AHCI 1.0])
DeviceName: PCH Integrated SATA Controller
Subsystem: Intel Corporation C600/X79 series chipset 6-Port SATA AHCI Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin B routed to IRQ 55
Region 0: I/O ports at 5070 [size=8]
Region 1: I/O ports at 5060 [size=4]
Region 2: I/O ports at 5050 [size=8]
Region 3: I/O ports at 5040 [size=4]
Region 4: I/O ports at 5020 [size=32]
Region 5: Memory at d0f00000 (32-bit, non-prefetchable) [size=2K]
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee01000 Data: 4087
Capabilities: [70] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a8] SATA HBA v1.0 BAR4 Offset=00000004
Capabilities: [b0] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ahci
Kernel modules: ahci
$ lspci -xxxx -d :0x1d02
00:1f.2 SATA controller: Intel Corporation C600/X79 series chipset 6-Port SATA AHCI Controller (rev 06)
00: 86 80 02 1d 43 00 b0 02 06 01 06 01 00 00 00 00
10: 71 50 00 00 61 50 00 00 51 50 00 00 41 50 00 00
20: 21 50 00 00 00 00 f0 d0 00 00 00 00 86 80 82 35
30: 00 00 00 00 80 00 00 00 00 00 00 00 0b 02 00 00
40: 00 80 00 80 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 01 a8 03 40 08 00 00 00 00 00 00 00 00 00 00 00
80: 05 70 00 00 00 00 e0 fe b8 40 00 00 00 00 00 00
90: 60 00 3f 81 83 01 00 00 08 42 1c 01 00 00 00 00
a0: e0 00 00 00 39 00 00 00 12 b0 10 00 48 00 00 00
b0: 13 00 06 03 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 87 0f 07 08 00 00 00 00
ubuntu@ubuntu:~/lsuio-0.2.0$ ./lsuio -v
uio0: name=uio_pci_generic, version=0.01.0, events=0
Device attributes:
vendor=0x8086
uevent=DRIVER=uio_pci_generic
subsystem_vendor=0x8086
subsystem_device=0x3582
resource=0x0000000000005070 0x0000000000005077 0x0000000000040101
numa_node=0
msi_bus=1
modalias=pci:v00008086d00001D02sv00008086sd00003582bc01sc06i01
local_cpus=0000,00000000,00000000,00000000,00000000,00000000,00000000,3ff0
local_cpulist=0-9,20-29
label=PCH Integrated SATA Controller
irq=21
index=0
enable=1
driver_override=(null)
dma_mask_bits=64
device=0x1d02
d3cold_allowed=1
consistent_dma_mask_bits=64
config=��C
class=0x010601
broken_parity_status=0