1# System Configuration User Guide {#system_configuration} 2 3This system configuration guide describes how to configure a system for use with SPDK. 4 5## IOMMU configuration {#iommu_config} 6 7An IOMMU may be present and enabled on many platforms. When an IOMMU is present and enabled, it is 8recommended that SPDK applications are deployed with the `vfio-pci` kernel driver. SPDK's 9`scripts/setup.sh` script will automatically select `vfio-pci` in this case. 10 11However, some devices do not function correctly when bound to `vfio-pci` and instead must be 12attached to the `uio_pci_generic` kernel driver. In that case, users should take care to disable 13the IOMMU or to set it into passthrough mode prior to running `scripts/setup.sh`. 14 15To disable the IOMMU or place it into passthrough mode, add `intel_iommu=off` 16or `amd_iommu=off` or `intel_iommu=on iommu=pt` to the GRUB command line on 17x86_64 system, or add `iommu.passthrough=1` on arm64 systems. 18 19There are also some instances where a user may not want to use `uio_pci_generic` or the kernel 20version they are using has a bug where `uio_pci_generic` [fails to bind to NVMe drives](https://github.com/spdk/spdk/issues/399). 21In these cases, users can build the `igb_uio` kernel module which can be found in dpdk-kmods repository. 22To ensure that the driver is properly bound, users should specify `DRIVER_OVERRIDE=/path/to/igb_uio.ko`. 23 24## Running SPDK as non-privileged user {#system_configuration_nonroot} 25 26One of the benefits of using the `VFIO` Linux kernel driver is the ability to 27perform DMA operations with peripheral devices as unprivileged user. The 28permissions to access particular devices still need to be granted by the system 29administrator, but only on a one-time basis. Note that this functionality 30is supported with DPDK starting from version 18.11. 31 32### Hugetlbfs access 33 34Make sure the target user has RW access to at least one hugepage mount. 35A good idea is to create a new mount specifically for SPDK: 36 37~~~{.sh} 38# mkdir /mnt/spdk_hugetlbfs 39# mount -t hugetlbfs -o uid=spdk,size=<value> none /mnt/spdk_hugetlbfs 40~~~ 41 42Then start SPDK applications with an additional parameter `--huge-dir /mnt/spdk_hugetlbfs` 43 44Full guide on configuring hugepage mounts is available in the 45[Linux Hugetlbpage Documentation](https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt) 46 47### Device access {#system_configuration_nonroot_device_access} 48 49`VFIO` device access is protected with sysfs file permissions and can be 50configured with chown/chmod. 51 52Please note that the VFIO device isolation is based around IOMMU groups and it's 53only possible to change permissions of the entire group, which might possibly 54consist of more than one device. (You could also apply a custom kernel patch to 55further isolate those devices in the kernel, but it comes with potential risks 56as described on 57[Alex Williamson's VFIO blog](https://vfio.blogspot.com/2014/08/iommu-groups-inside-and-out.html), 58with the patch in question available here: 59[[PATCH] pci: Enable overrides for missing ACS capabilities](https://lkml.org/lkml/2013/5/30/513)) 60 61Let's assume we want to use PCI device `0000:04:00.0`. First of all, verify 62that it has an IOMMU group assigned: 63 64~~~{.sh} 65readlink "/sys/bus/pci/devices/0000:00:04.0/iommu_group" 66~~~ 67 68The output should be e.g. 69`../../../kernel/iommu_groups/5` 70 71Which means that the device is a part of the IOMMU group 5. We can check if 72there are any other devices in that group. 73 74~~~{.sh} 75$ ls /sys/kernel/iommu_groups/5/devices/ 760000:00:04.0 0000:00:04.1 0000:00:04.2 0000:00:04.3 0000:00:04.4 0000:00:04.5 0000:00:04.6 0000:00:04.7 77~~~ 78 79In this case `0000:04:00.0` is an I/OAT channel which comes with 7 different 80channels associated with the same IOMMU group. 81 82To give the user `spdk` full access to the VFIO IOMMU group 5 and all its 83devices, use the following: 84 85~~~{.sh} 86# chown spdk /dev/vfio/5 87~~~ 88 89### Memory constraints {#system_configuration_nonroot_memory_constraints} 90 91As soon as the first device is attached to SPDK, all of SPDK memory will be 92mapped to the IOMMU through the VFIO APIs. VFIO will try to mlock that memory and 93will likely exceed user ulimit on locked memory. Besides having various 94SPDK errors and failures, this would also pollute the syslog with the following 95entries: 96 97`vfio_pin_pages: RLIMIT_MEMLOCK` 98 99The limit can be checked by running the following command as target user: 100(output in kilobytes) 101 102~~~{.sh} 103ulimit -l 104~~~ 105 106On Ubuntu 18.04 this returns 16384 (16MB) by default, which is way below 107what SPDK needs. 108 109The limit can be increased with one of the methods below. Keep in mind SPDK will 110try to map not only its reserved hugepages, but also all the memory that's 111shared by its vhost clients as described in the 112[Vhost processing guide](https://spdk.io/doc/vhost_processing.html#vhost_processing_init). 113 114#### Increasing the memlock limit permanently 115 116Open the `/etc/security/limits.conf` file as root and append the following: 117 118```bash 119spdk hard memlock unlimited 120spdk soft memlock unlimited 121``` 122 123Then logout from the target user account. The changes will take effect after the next login. 124 125#### Increasing the memlock for a specific process 126 127Linux offers a `prlimit` utility that can override limits of any given process. 128On Ubuntu, it is a part of the `util-linux` package. 129 130~~~{.sh} 131# prlimit --pid <pid> --memlock=<soft>:<hard> 132~~~ 133 134Note that the above needs to be executed before the first device is attached to 135the SPDK application. 136