1*7f631442SPierrick Bouvier.. _ebpf-rss: 2*7f631442SPierrick Bouvier 394645620SAndrew Melnychenko=========================== 494645620SAndrew MelnychenkoeBPF RSS virtio-net support 594645620SAndrew Melnychenko=========================== 694645620SAndrew Melnychenko 794645620SAndrew MelnychenkoRSS(Receive Side Scaling) is used to distribute network packets to guest virtqueues 894645620SAndrew Melnychenkoby calculating packet hash. Usually every queue is processed then by a specific guest CPU core. 994645620SAndrew Melnychenko 1094645620SAndrew MelnychenkoFor now there are 2 RSS implementations in qemu: 1194645620SAndrew Melnychenko- 'in-qemu' RSS (functions if qemu receives network packets, i.e. vhost=off) 1294645620SAndrew Melnychenko- eBPF RSS (can function with also with vhost=on) 1394645620SAndrew Melnychenko 1494645620SAndrew MelnychenkoeBPF support (CONFIG_EBPF) is enabled by 'configure' script. 1594645620SAndrew MelnychenkoTo enable eBPF RSS support use './configure --enable-bpf'. 1694645620SAndrew Melnychenko 1794645620SAndrew MelnychenkoIf steering BPF is not set for kernel's TUN module, the TUN uses automatic selection 1894645620SAndrew Melnychenkoof rx virtqueue based on lookup table built according to calculated symmetric hash 1994645620SAndrew Melnychenkoof transmitted packets. 2094645620SAndrew MelnychenkoIf steering BPF is set for TUN the BPF code calculates the hash of packet header and 2194645620SAndrew Melnychenkoreturns the virtqueue number to place the packet to. 2294645620SAndrew Melnychenko 2394645620SAndrew MelnychenkoSimplified decision formula: 2494645620SAndrew Melnychenko 2594645620SAndrew Melnychenko.. code:: C 2694645620SAndrew Melnychenko 2794645620SAndrew Melnychenko queue_index = indirection_table[hash(<packet data>)%<indirection_table size>] 2894645620SAndrew Melnychenko 2994645620SAndrew Melnychenko 3094645620SAndrew MelnychenkoNot for all packets, the hash can/should be calculated. 3194645620SAndrew Melnychenko 3294645620SAndrew MelnychenkoNote: currently, eBPF RSS does not support hash reporting. 3394645620SAndrew Melnychenko 3494645620SAndrew MelnychenkoeBPF RSS turned on by different combinations of vhost-net, vitrio-net and tap configurations: 3594645620SAndrew Melnychenko 3694645620SAndrew Melnychenko- eBPF is used: 3794645620SAndrew Melnychenko 3894645620SAndrew Melnychenko tap,vhost=off & virtio-net-pci,rss=on,hash=off 3994645620SAndrew Melnychenko 4094645620SAndrew Melnychenko- eBPF is used: 4194645620SAndrew Melnychenko 4294645620SAndrew Melnychenko tap,vhost=on & virtio-net-pci,rss=on,hash=off 4394645620SAndrew Melnychenko 4494645620SAndrew Melnychenko- 'in-qemu' RSS is used: 4594645620SAndrew Melnychenko 4694645620SAndrew Melnychenko tap,vhost=off & virtio-net-pci,rss=on,hash=on 4794645620SAndrew Melnychenko 4894645620SAndrew Melnychenko- eBPF is used, hash population feature is not reported to the guest: 4994645620SAndrew Melnychenko 5094645620SAndrew Melnychenko tap,vhost=on & virtio-net-pci,rss=on,hash=on 5194645620SAndrew Melnychenko 5294645620SAndrew MelnychenkoIf CONFIG_EBPF is not set then only 'in-qemu' RSS is supported. 5394645620SAndrew MelnychenkoAlso 'in-qemu' RSS, as a fallback, is used if the eBPF program failed to load or set to TUN. 5494645620SAndrew Melnychenko 5594645620SAndrew MelnychenkoRSS eBPF program 5694645620SAndrew Melnychenko---------------- 5794645620SAndrew Melnychenko 5894645620SAndrew MelnychenkoRSS program located in ebpf/rss.bpf.skeleton.h generated by bpftool. 5994645620SAndrew MelnychenkoSo the program is part of the qemu binary. 6094645620SAndrew MelnychenkoInitially, the eBPF program was compiled by clang and source code located at tools/ebpf/rss.bpf.c. 6194645620SAndrew MelnychenkoPrerequisites to recompile the eBPF program (regenerate ebpf/rss.bpf.skeleton.h): 6294645620SAndrew Melnychenko 6394645620SAndrew Melnychenko llvm, clang, kernel source tree, bpftool 6494645620SAndrew Melnychenko Adjust Makefile.ebpf to reflect the location of the kernel source tree 6594645620SAndrew Melnychenko 6694645620SAndrew Melnychenko $ cd tools/ebpf 6794645620SAndrew Melnychenko $ make -f Makefile.ebpf 6894645620SAndrew Melnychenko 6994645620SAndrew MelnychenkoCurrent eBPF RSS implementation uses 'bounded loops' with 'backward jump instructions' which present in the last kernels. 7094645620SAndrew MelnychenkoOverall eBPF RSS works on kernels 5.8+. 7194645620SAndrew Melnychenko 7294645620SAndrew MelnychenkoeBPF RSS implementation 7394645620SAndrew Melnychenko----------------------- 7494645620SAndrew Melnychenko 7594645620SAndrew MelnychenkoeBPF RSS loading functionality located in ebpf/ebpf_rss.c and ebpf/ebpf_rss.h. 7694645620SAndrew Melnychenko 77f0d7b970SPeter MaydellThe ``struct EBPFRSSContext`` structure that holds 4 file descriptors: 7894645620SAndrew Melnychenko 7994645620SAndrew Melnychenko- ctx - pointer of the libbpf context. 8094645620SAndrew Melnychenko- program_fd - file descriptor of the eBPF RSS program. 8194645620SAndrew Melnychenko- map_configuration - file descriptor of the 'configuration' map. This map contains one element of 'struct EBPFRSSConfig'. This configuration determines eBPF program behavior. 8294645620SAndrew Melnychenko- map_toeplitz_key - file descriptor of the 'Toeplitz key' map. One element of the 40byte key prepared for the hashing algorithm. 8394645620SAndrew Melnychenko- map_indirections_table - 128 elements of queue indexes. 8494645620SAndrew Melnychenko 85f0d7b970SPeter Maydell``struct EBPFRSSConfig`` fields: 8694645620SAndrew Melnychenko 87f0d7b970SPeter Maydell- redirect - "boolean" value, should the hash be calculated, on false - ``default_queue`` would be used as the final decision. 8894645620SAndrew Melnychenko- populate_hash - for now, not used. eBPF RSS doesn't support hash reporting. 89f0d7b970SPeter Maydell- hash_types - binary mask of different hash types. See ``VIRTIO_NET_RSS_HASH_TYPE_*`` defines. If for packet hash should not be calculated - ``default_queue`` would be used. 9094645620SAndrew Melnychenko- indirections_len - length of the indirections table, maximum 128. 9194645620SAndrew Melnychenko- default_queue - the queue index that used for packet that shouldn't be hashed. For some packets, the hash can't be calculated(g.e ARP). 9294645620SAndrew Melnychenko 9394645620SAndrew MelnychenkoFunctions: 9494645620SAndrew Melnychenko 95f0d7b970SPeter Maydell- ``ebpf_rss_init()`` - sets ctx to NULL, which indicates that EBPFRSSContext is not loaded. 96f0d7b970SPeter Maydell- ``ebpf_rss_load()`` - creates 3 maps and loads eBPF program from the rss.bpf.skeleton.h. Returns 'true' on success. After that, program_fd can be used to set steering for TAP. 97f0d7b970SPeter Maydell- ``ebpf_rss_set_all()`` - sets values for eBPF maps. ``indirections_table`` length is in EBPFRSSConfig. ``toeplitz_key`` is VIRTIO_NET_RSS_MAX_KEY_SIZE aka 40 bytes array. 98f0d7b970SPeter Maydell- ``ebpf_rss_unload()`` - close all file descriptors and set ctx to NULL. 9994645620SAndrew Melnychenko 10094645620SAndrew MelnychenkoSimplified eBPF RSS workflow: 10194645620SAndrew Melnychenko 10294645620SAndrew Melnychenko.. code:: C 10394645620SAndrew Melnychenko 10494645620SAndrew Melnychenko struct EBPFRSSConfig config; 10594645620SAndrew Melnychenko config.redirect = 1; 10694645620SAndrew Melnychenko config.hash_types = VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | VIRTIO_NET_RSS_HASH_TYPE_TCPv4; 10794645620SAndrew Melnychenko config.indirections_len = VIRTIO_NET_RSS_MAX_TABLE_LEN; 10894645620SAndrew Melnychenko config.default_queue = 0; 10994645620SAndrew Melnychenko 11094645620SAndrew Melnychenko uint16_t table[VIRTIO_NET_RSS_MAX_TABLE_LEN] = {...}; 11194645620SAndrew Melnychenko uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {...}; 11294645620SAndrew Melnychenko 11394645620SAndrew Melnychenko struct EBPFRSSContext ctx; 11494645620SAndrew Melnychenko ebpf_rss_init(&ctx); 11594645620SAndrew Melnychenko ebpf_rss_load(&ctx); 11694645620SAndrew Melnychenko ebpf_rss_set_all(&ctx, &config, table, key); 11794645620SAndrew Melnychenko if (net_client->info->set_steering_ebpf != NULL) { 11894645620SAndrew Melnychenko net_client->info->set_steering_ebpf(net_client, ctx->program_fd); 11994645620SAndrew Melnychenko } 12094645620SAndrew Melnychenko ... 12194645620SAndrew Melnychenko ebpf_unload(&ctx); 12294645620SAndrew Melnychenko 12394645620SAndrew Melnychenko 12494645620SAndrew MelnychenkoNetClientState SetSteeringEBPF() 12594645620SAndrew Melnychenko~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 12694645620SAndrew Melnychenko 127f0d7b970SPeter MaydellFor now, ``set_steering_ebpf()`` method supported by Linux TAP NetClientState. The method requires an eBPF program file descriptor as an argument. 128