uio 0.1.0

Helper library for writing linux user-space drivers with UIO.
Documentation

Set-up

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/uio_cif.c https://www.kernel.org/doc/htmldocs/uio-howto/index.html http://lxr.free-electrons.com/source/drivers/uio/uio_dmem_genirq.c http://www.osadl.org/projects/downloads/UIO/user/ http://dpdk.org/browse/dpdk/tree/tools/dpdk_nic_bind.py

Bind our AHCI to uio_dmem_genirq

is this needed?

echo "00:1f.2" > /sys/bus/pci/drivers/uio_pci_generic/bind

You can create the file /etc/udev/rules.d/10-local.rules and insert the line:

KERNEL==”uio0″, MODE=”666″, ATTRS{class}=="0x010601", ATTRS{device}=="0x1d02", DRIVER=="uio_pci_generic"

$ ls /sys/class/uio/uio0/maps/map0

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{alignment_offset}=="0"
    ATTR{capability}=="50"
    ATTR{discard_alignment}=="0"
    ATTR{events}==""
    ATTR{events_async}==""
    ATTR{events_poll_msecs}=="-1"
    ATTR{ext_range}=="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{device_blocked}=="0"
    ATTRS{device_busy}=="0"
    ATTRS{dh_state}=="detached"
    ATTRS{eh_timeout}=="10"
    ATTRS{evt_capacity_change_reported}=="0"
    ATTRS{evt_inquiry_change_reported}=="0"
    ATTRS{evt_lun_change_reported}=="0"
    ATTRS{evt_media_change}=="0"
    ATTRS{evt_mode_parameter_change_reported}=="0"
    ATTRS{evt_soft_threshold_reached}=="0"
    ATTRS{inquiry}==""
    ATTRS{iocounterbits}=="32"
    ATTRS{iodone_cnt}=="0xae77"
    ATTRS{ioerr_cnt}=="0x27d"
    ATTRS{iorequest_cnt}=="0xaf67"
    ATTRS{model}=="Samsung SSD 850 "
    ATTRS{queue_depth}=="31"
    ATTRS{queue_ramp_up_period}=="120000"
    ATTRS{queue_type}=="none"
    ATTRS{rev}=="2B6Q"
    ATTRS{scsi_level}=="6"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{type}=="0"
    ATTRS{vendor}=="ATA     "
    ATTRS{vpd_pg80}==""
    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{broken_parity_status}=="0"
    ATTRS{class}=="0x010601"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{device}=="0x1d02"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{index}=="0"
    ATTRS{irq}=="55"
    ATTRS{label}=="PCH Integrated SATA Controller"
    ATTRS{local_cpulist}=="0-9,20-29"
    ATTRS{local_cpus}=="0000,00000000,00000000,00000000,00000000,00000000,00000000,3ff003ff"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="0"
    ATTRS{subsystem_device}=="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