- Today
- Total
Byeo
The eXpress Data Path (XDP): Fast Programmable Packet Processing in the Operating System Kernel 3 본문
The eXpress Data Path (XDP): Fast Programmable Packet Processing in the Operating System Kernel 3
BKlee 2023. 8. 30. 21:32이 글은 Conext '18에 공개된 The eXpress Data Path (XDP): Fast Programmable Packet Processing in the Operating System Kernel 를 번역해 정리한 글입니다.
이전 게시글
4. Performance Evaluation
이 section에서는 XDP에 대한 성능 평가를 보인다. Packet processing을 위한 framework는 다수 존재하나 이들을 모두 비교하는 것은 현실적으로 어렵고, 대신 최고 성능으로 알려져 있는 DPDK의 testpmd 18.05버전을 비교군으로 삼았다. 또한 XDP로 인한 성능 상승을 파악하기 위해 Linux kernel stack의 성능도 비교하였다. 다음 section에서는 XDP를 사용해 구현된 real-world application을 통해 성능 향상과 programmability를 증명할 것이다. (real-world application은 포스트에서 제외하였습니다.)
실험 환경은 CPU cache에 데이터를 바로 전송할 수 있는 기능인 DDIO가 활성화된 Intel Xeon E5-1650 v4 3.6GHz CPU를 사용하였다. 두 서버는 Mellanox ConnectX-5 Ex 100Gbps NIC을 장착하였다.
4.1 Packet Drop Performance
Figure 3은 CPU core 수에 따라 packet drop 성능이 어떻게 변화하는지 보여준다. DPDK의 single core packet drop 성능은 43.5 Mpps인 반면, XDP의 single core 성능은 24 Mpps를 보였다. 이 두 시스템의 성능은 CPU 개수에 따라 비례하여 증가하다가, 115 Mpps인 PCI bus 성능이 한계로 작용하였다 (CPU cycle과 PCI bus bandwidth를 교환하는 PCI descriptor 압축 기법을 사용).
해당 그래프에는 Linux networking stack에 2가지 configuration이 포함되어있다. 하나는 Linux의 Iptables 방화벽에서 일찍이 packet을 drop시키는 "raw"이며, 다른 하나는 overhead가 크지만 많은 Linux distribution에서 사용하는 conntrack (connection tracking) module을 사용한 환경이다. Single-core에서는 conntrack을 사용할 때 1.8Mpps를, raw에서는 4.8Mpps를 보였다. Linux 환경에서는 하드웨어의 bottleneck에 도달하기 어렵기 때문에 CPU 개수에 따라 비례하여 성능이 증가한다. 결국, XDP는 일반 Linux kernel strack의 가장 빠른 실험 환경 ("raw")보다도 5배의 빠른 성능을 보일 수 있었다.
Linux raw mode 테스트의 일부로, 아무 작업을 하지 않는 XDP 프로그램을 설치하여 XDP 프로그램의 overhead를 측정하였다. 이 실험에서는 4.5Mpps로의 성능 저하를 보였다 (환산시 13.3ns).
4.2 CPU 사용량
Figure 4는 Single CPU만을 사용하여 packet drop application 실행했을 때, packet의 양에 따라 CPU 사용량이 어떻게 변화하는지를 mpstat 툴로 측정한 결과이다. DPDK는 CPU core 전부를 packet processing과 busy polling을 수행하는데 전념하도록 하기에 항상 100%를 보인다. 반면 XDP와 Linux는 유입되는 packet의 양에 따라 비례하는 모습을 보인다. 다만 packet의 양이 적은 부분에서 선형으로 증가하는 모습은 아닌데, 이는 interrupt processing의 고정 비용 때문이다. Packet의 유입 양이 적을 때에는 interrupt당 처리되는 packet의 수도 감소하고, 그에 따라 packet당 CPU 비용이 증가하는 것으로 해석할 수 있기 때문이다.
4.3 Packet Forwarding 성능
Figure 5는 packet forwarding 성능을 나타낸다. 실험에 사용된 forwarding application은 L2 mac source과 mac destination을 뒤집어서 내보내는, forwarding에 있어서 가장 기본적인 작업을 수행한다. 따라서 이 실험의 결과는 forwarding의 uppe bound를 제시한다 (forwarding에 필요한 가장 최소 작업만을 수행했으므로). Figure 5에 나타난 XDP 그래프는 2개인데, 하나는 packet이 들어온 interface에 다시 내보내는 방식 (same NIC), 다른 하나는 packet이 들어온 interface와 다른 interface로 내보내는 방식 (different NIC)을 의미한다. DPDK는 다른 NIC으로만 보내는 것을 지원한다. Linux의 networking stack은 비용이 비싼 bridge와 routing lookup을 설정해야 했고, 최소 forwarding을 위한 방법을 지원하지 않아 직접적인 비교가 어려워 실험에서 제외했다고 한다. (대신, Section 5.1에 software routing 응용 비교 실험이 있으니 참고하면 좋을 듯하다.)
Figure 5에 나타난 것처럼, 병목에 도달하기 전까지 CPU core의 개수에 따라 성능이 선형으로 증가한다. Forwarding overhead 때문에 성능은 drop 실험보다 다소 낮은 모습을 보인다. 같은 NIC으로 보내는 방식에서는 2개 이상의 코어를 사용할 때부터 DPDK보다 성능이 좋은 것을 볼 수 있다. 이는 메모리 관리 측면에서 차이가 나는 부분인데, interface 1이 device driver에서 packet을 위한 공간을 할당했다면, 반납도 interface 1이 해야한다. 즉, interface가 다르면 메모리 반납에서 추가 비용이 발생한다.
Table 1은 forwarding latency 나타낸다. pps가 낮은 영역에서는 XDP가 interrupt 처리에 조금 더 많은 시간을 필요로 하기에 latency가 높아서, busy polling을 하고 있는 DPDK보다 latency가 높다는 단점이 있다.
4.4 Discussion
지금까지 내용을 살펴보면 XDP는 Linux networking stack보다 상당히 높은 성능을 달성할 수 있음을 확인했다. 다만, 많은 부분에서 XDP가 DPDK의 성능에 미치지 못했는데, 이는 그동안 DPDK에 들어간 다양한 노력과 최적화 때문이라고 저자는 이야기한다. Packet drop 실험을 보면, XDP는 24 Mpps (packet 1개당 41.6 ns), DPDK는 43.5 Mpps (packet 1개당 22.9 ns)를 보였다. 즉, XDP와 DPDK의 packet 1개당 연산은 18.7 ns의 시간 차이를 보였으며, 3.6 GHz processor 기준 67 clock cycle 차이이다. 저자의 환경에서 single function call은 1.3 ns의 시간을 필요로 했는데, mlx5 driver가 하나의 packet을 처리하는데 10번의 function call이 있었으므로 18.7 ns 중에 13 ns가 이 차이에서 온 것이라고 볼 수 있는 것이다.
이러한 비용은 general-purpose를 위해서, 즉 Linux에서 device driver와 다양한 subsystem들을 수용하기 위한 목적임이 크다. 그래서 저자는 이 부분에 최적화를 가하면 XDP가 성능이 끌어올려질 것이라고 제안한다. 예를 들어, 저자의 특정 hardward에서 DMA-related function call 없이 작업을 수행할 수 있다면, 10개 중에 4개의 function call을 제거할 수 있음과 동시에 29 Mpps를 달성할 수 있다고 말한다. 이를 기반으로 추정컨대, 10개를 모두 제거하면 37.6 Mpps로 예상하였다.
결론으로, 저자들은 이러한 최적화 등을 통해 XDP가 DPDK를 쫓아갈 수 있을것이라고 의견을 제안하였다. 물론 성능뿐만 아니라 유연함 (flexibility)과 다른 시스템과의 통합 측면에서는 여전히 XDP가 좋은 선택지이다. 이는 Seciton 5. real-world use cases (5.1 software routing / 5.2 dos protection / 5.3 load balancing) 에서 다룬다. (실 사용 사례는 포스트에서 생략하였습니다!)
6. XDP 미래 방향
XDP는 고성능을 제공하면서 많은 실제 사용 사례들(section 5)을 볼 수 있었다. 그러나 아직 XDP의 발전은 끝나지 않았고, Linux kernel의 일부로서 꾸준히 개선되는 중이다. 그 노력으로는 general-purpose operating system kernel에 잘 통합될 수 있도록 하는 것, 그리고 XDP의 능력을 꾸준히 상승시키는 것 등이 있다.
6.1. eBPF 프로그램의 한계
지금까지 설명된 것처럼 eBPF 프로그램은 eBPF verifier에 의해 kernel의 기능을 망치지 않는지 검사한 뒤에 eBPF VM에 로드된다. 이 검사 과정에서 두 가지 제약이 발생한다: (a) program이 종료될 수 있음을 보장해야 하기에, loop와 최대 프로그램 사이즈가 제한된다. (b) register tracking기법에 의해 일부 memory access가 제한된다.
eBPF verifier의 중요한 기능은 kernel의 안정성을 보장하는 것이 최우선이기에, verifier가 안전하다고 증명하지 못하는 프로그램은 전부 실행을 거부하는 보수적인 접근을 취하고 있다. 이는 실제로 실행시켜보면 안전한 프로그램일수도 있지만 거부당하는 케이스를 발생시킬 수도 있다는 단점이 있다. 이러한 착오를 줄이기 위한 노력은 계속 진행되고 있다. eBPF verifier가 프로그램을 거부할 때 출력하는 에러 메시지도 개발자가 쉽게 수정할 수 있도록 친화적으로 안내하고 있다. eBPF에서 함수 호출 기능은 최근 추가되었으며, 제한된 수치의 loop와 verifier 효율 개선 등은 진행 중이다.
또 다른 한계로는 user-space C 프로그램처럼 표준 라이브러리 (메모리 할당, 쓰레딩, lock)가 없다는 것이다. 다만, 이는 kernel의 help function과 kernel의 execution context management에 의해 약간 완화될 수 있기는 하다.
마지막으로는 network interface 각각에 하나의 XDP 프로그램만 붙을 수 있다는 것이다. 이는 packet의 내용을 확인하고 이 후 실행할 XDP 프로그램을 결정하는 등의 협업 방식으로 어느 정도 해결을 할 수 있다.
6.2. User Experience와 Debugging
XDP 프로그램은 kernel에서 실행되기 때문에 userspace 프로그램에서 널리 사용되던 디버깅 도구를 그대로 사용하기 어렵다. 대신, 기존의 kernel 디버깅 도구나 자가 진단 기법 등이 XDP와 다른 eBPF 프로그램들에 적용이 가능하다. 예제로는 kprobes, perf 등이 있다. 단, kernel 시스템에 익숙하지 않는 개발자는 해당 kernel 디버깅 툴들에 적응하기 어려울 것이다. 이를 쉽게 하기 위해서 BPF Compiler Collection, bpftool, libbpf library 등이 다양하게 존재한다.
6.3. Driver Support
XDP 프로그램을 실행하기 위해서는 device driver가 XDP 프로그램 실행을 지원해야 한다. 이는 core networking stack에 의해 노출된 API를 지원함으로써 가능하다. 이 XDP를 지원하는 device driver는 점차 늘어나는 추세이다. 다만, XDP 지원 device driver는 여전히 전체에서 일부기 때문에 하드웨어를 고를 때 개발하고자 하는 응용을 위한 기능을 지원하는지 확인하면서 구매해야 한다. (XDP는 kernel device driver에 통합되어 있기에 실질적으로 소프트웨어 구현의 부족이지 하드웨어의 한계가 아니긴 하다.)
XDP 시스템이 꾸준히 발전할때도, XDP를 지원하기 위한 driver의 수정 요구량은 최소화되도록 유지해야 한다. 예를들어, redirection action에서 새로운 target을 추가할 때, driver에는 수정이 필요하지 않도록 구현되었다.
6.4. 성능 개선
Section 4.4에서 논의된 것 처럼, XDP와 DPDK는 여전히 성능 차이가 존재한다. 현재 성능을 개선하기 위한 노력을 쏟고 있으며, 예로는 driver code 마이크로 최적화, core XDP 코드에서 필요 없는 연산 제거, batching을 통한 processing cost amortization 등이 있다.
6.5. QoS와 Rate transitions
현재 XDP는 QoS (Quality of Service)를 지원하기 위한 매커니즘이 구현되어 있지 않다. 특히, XDP 프로그램은 packet이 유입되는 속도보다 성능이 낮은 destination쪽으로 packet을 보내더라도(rate transition), XDP 서버는 back pressure를 처리하지 않는다 (이해한 바로는 100Gbps로 유입받은 packet 모두를 10Gbps 처리 가능한 서버로 보낼 때, 이 서버는 해당 packet을 전부 처리할 수 없으니 back-pressure 조치를 취할 것이다. 하지만 XDP는 이를 처리할 기능이 없다는 것으로 이해했다.)
XDP에 QoS기능은 없지만 Linux kernel에서는 Active Queue Management (AQM)과 packet scheduling algorithm을 제공한다. 이들이 XDP 구조에 최고의 선택지는 아니지만, 선택적으로 XDP에 적용하는 것이 QoS를 지원하는 데 좋은 선택지가 될 것이라고 믿고 있다. 현재는 QoS를 지원하기 위해 꾸준히 조사중이다.
* backpressure: https://medium.com/@jayphelps/backpressure-explained-the-flow-of-data-through-software-2350b3e77ce7
위 블로그가 backpressure 설명을 굉장히 잘해 놓은 듯하다
6.6. Transport Protocol 가속
XDP는 현재 stateless packet processing 집중되었다. 하지만 동일한 XDP 모델을 TCP와 같은 stateful protocol에 확장하는 것 역시 application에 동일한 성능 향상을 가져올 것으로 예상한다. 실제로, 다른 이들이 transport protocol을 가속하는 것이 기존 operating system stack보다 성능을 상당히 끌어올릴 수 있는 것을 확인하였다.
이들 중에서 하나 (stackmap)은 in-kernel TCP stack을 유지하면서 raw packet processing을 하는 방법이 상당한 성능 향상의 잠재력이 있음을 보였다. XDP도 결을 같이하며, 관련하여 어떻게 이 문제를 해결할 수 있을지 토론이 진행중이다.
6.7. Zero-copy to userspace
Section 3.1에서 언급된 것처럼 XDP 프로그램은 user space application에 의해 열린 특수 socket에 데이터를 바로 redirect 할 수 있다. 이는 network의 작업이 많은 응용을 수행하는 서버의 성능을 향상시킬 수 있을 것이다. 다만, 아직 초기 구현 단계로서 현재는 packet copy를 하고 있다. 현재 AF_XDP socket을 통해 user space로 data를 바로 zero-copy할 수 있는 작업을 수행 중이다. 이 작업은 Linux kernel 4.19에 포함되었으며, zero-copy XDP를 지원하는 device driver는 점차 포함해 갈 예정이다. 초기 구현은 single core에서 20Mpps의 성능을 보여, 유망한 방향으로 평가되고 있다.
6.8. XDP building block
DPDK는 high level packet processing framework를 구현하기 위한 building block으로서 사용되었다. XDP도 동일한 역할을 수행할 수 있을 것이라고 예상하고 있으며, 실 사례로도 Cilium security middle-ware, Suricata entwork monitor, Openvswitch, P4-to-XDP copmiler project와 같이 다양하게 존재한다. 심지어는 DPDK의 low-level driver로서 XDP를 사용하려는 노력도 있다.
7. 결론
논문에서는 OS에 통합된 고성능 programmable packet processing 시스템인 XDP를 다뤘다. XDP는 단순 packet processing 성능을 single core만 활용하여 최대 24 Mpps낼 수 있음을 확인하였다.
이는 완벽한 kernel bypass 해결책은 아니다. 그래서 다른 고성능 패킷 처리 시스템과 비교하여 조금 부족한 성능을 보인다. 하지만, 기존의 kernel security 활용 가능, kernel의 다양한 관리기능 호환성, kernel 기능을 취사선택할 수 있는 점, 안정적인 programming interface, 그리고 application에 투명하게 기능을 제공할 수 있다는 점에서, 부족한 성능을 커버할 수 있으리라 생각한다. 추가로, 서비스 중단 없이 programming이 가능하며, 특수 하드웨어 및 자원 전부 할당 (DPDK cpu core) 등을 필요로 하지 않는다.
저자는 이러한 특징들이 XDP가 all-or-nothing 성격을 보이는 kernel bypass 방법들을 대체할 수 있으리라 믿는다. 이러한 믿음은 현재 실 사례로 구현된 많은 응용들이 뒷받침한다. 나아가 XDP는 꾸준히 진보중이며, 여전히 XDP를 발전시킬 다양한 방향들이 있음을 section 6에서 다뤘다.