Skip to the content.

Kernel Bypass

Linux 内核并不是为了极致性能而设计的,它追求的是通用性、兼容性、安全性,而不是专门服务某一种 workload。因此,如果我们能找到一种方式,将某些逻辑移出内核、交给用户态,自然可以获得更大的灵活性以及潜在的性能提升。

内核越来越多地在做“资源管理”和“隔离”,而将策略和高速路径交给用户态

复杂的文件系统,将功能放到内核中,真的好吗? 当然是不好的,但是用户态文件系统的性能实在是太差了

哪些内核功能可以放到用户态?

直接访问硬件

相关的配套设施,vfio iommufd iommu sriov siov

整体来说,和驱动打交道,就三个问题:

  1. 如何响应中断
  2. 数据面 (data plane) : 如何给设备发送命令
  3. 控制面 (control plane) : 如何设备发送数据

中断的解决办法:

  1. 用户态中断。从 vfio 的中断直接注入的到虚拟机中就可以想到,中断也是可以直接注册到用户态的
  2. 使用轮询

数据面主要使用 iommu 和 共享内存

控制面由于在低速路径上,总体来说,就比较容易了,一般通过 ioctl 来转发命令就可以了。

直接访问硬件的最经典的例子是 DPDK (用户态驱动) 和 将驱动直通到虚拟机,驱动让虚拟机中的驱动管理。 也有一些其他的有意思的例子,例如 qemu 的 block/nvme.c 中,可以直接将物理机中的 nvme 盘作为虚拟机中盘, 例如配置如下参数:

-blockdev driver=nvme,node-name=disk_backend,device=0000:03:00.0,namespace=1
-device virtio-blk-pci,drive=disk_backend

在虚拟机中就可以观察到:

vdb                251:16   0   1.5T  0 disk
├─vdb1             251:17   0 745.2G  0 part
└─vdb2             251:18   0 745.2G  0 part

提供虚拟驱动

用户态策略

基于 bpf 的 struct ops 可以将部分逻辑移动到用户态,目前支持的功能为:

参考 https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_STRUCT_OPS/tcp_congestion_ops/

进展

这些年的进步在于:

进一步的思考

  1. 相同的功能其实可以放到 用户态,内核态,固件中(nvidia GSP 固件),CPU 中,加速器中 virtio 作为案例
    1. kernel 中的 vhost-net
    2. qemu 中 hw/net/virtio-net.c
    3. vhost-user : dpdk 实现
    4. vduse : 用户态进程实现
    5. vdpa : 硬件实现,可能是 ASIC 电路,也可能是 FPGA
    6. 智能网卡,类似的 ovs 也可以放到硬件中
  2. 同样的,存储的案例,内核中的 raid / device mapper / bcache,在用户态的 ceph 之类的存储产品中都有实现
  3. 微内核可以解决这些问题吗?我理解是可以的
  4. https://github.com/theseus-os/Theseus 通过 rust 来消除用户态、内核态的操作系统
  5. https://engineering.fb.com/2024/03/12/data-center-engineering/building-metas-genai-infrastructure/
  6. https://github.com/topics/kernel-bypass

为了实现用户态驱动的努力

实验

ulef

内核新增了一个设备 /dev/uleds ,算是非常经典了:

sudo ./a.out mmmm

打开另外一个窗口,find /sys -name mmmm , 然后就可以观察到这个目录:

/sys/class/leds/mmmm
/sys/devices/virtual/misc/uleds/mmmm

cd /sys/devices/virtual/misc/uleds/mmmm 中, echo 10 | sudo tee brightness

那么之前的 a.out 就会有输出

uinput

关键参考

Linux drivers in user space — a survey

https://lwn.net/Articles/703785/

When one reflects on the tree-like nature of the driver model, as described in an earlier article, it is clear that there is a chain, or path, of drivers from the root out to the leaves, each making use of services provided by the driver closer to the root (or “upstream”) and providing services to the driver closer to the leaf (or “downstream”).

Where upstream interfaces provide direct access to hardware, downstream interfaces allow a program to emulate some hardware and so provide access to other programs that expect to use a particular sort of interface. Rather than just providing a different sort of access to an already existing device, a downstream interface must make it possible to create a new device, configure it, and then provide whatever functionality is expected of that device type.

Similarly there is a downstream interface for writing filesystems that is careful about how it interfaces with the page cache, and manages to avoid the writeback deadlocks described above: FUSE. (如果可以解决,那么 nfs 应该也可以解决才对的啊)

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。