Skip to content

About

SKKU SYSLAB Project: Optimize the UDP in Linux Kernel

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

47 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UDP-Optimization

Linux UDP 수신 경로(RX)를 계측·분석하고, 커널을 수정해 단일코어 성능을 끌어올리는 프로젝트.

대학원 네트워크시스템설계 텀프로젝트. 100GbE ConnectX-5 환경에서 진짜 단일코어 (NIC IRQ + NAPI + consumer 프로세스를 모두 같은 코어에 고정) 조건으로 측정한다.


문제

동일 조건 단일코어에서 UDP는 TCP보다 느리다. 하지만 그 원인은 통념과 다르다.

구성 goodput core busy 바이트당 효율
Linux 기본값 UDP (208KB rcvbuf) 8-22 G 26-55% —
TCP (최적: DIM off, rmem 6MB) 39.6 G 100% 0.396 G/%CPU
UDP 최적 구성 (기댓값) 48.5 G @ 52 G offered 100% 0.485 G/%CPU
UDP 최적 구성 (최선 관측) 51.7 G @0.5% loss 98% 0.53 G/%CPU

UDP RX는 per-byte로 TCP보다 싸다. 문제는 처리 비용이 아니라 수신 버퍼 오버런과 그로 인한 상태 붕괴(collapse) 이고, 이를 제거하면 같은 코어 하나로 TCP보다 22% 높은 처리량(기댓값 기준)을 낸다.

부하 구간별로 동작이 다르다.

offered 동작
~42 Gbps 이하 항상 무손실, CPU 여유
43-50 Gbps bistable — 무손실이거나 41.5 Gbps로 붕괴 (진입률 약 56%)
52 Gbps 이상 단일 CPU 포화 영역, 46-51 Gbps 전달 (bistability 소멸)

기댓값이 최대가 되는 지점은 52 Gbps를 제공해 48.5 Gbps를 받는 것이다.

최적 구성 = 정적 rcvbuf 1.5 MB + DIM off + app GSO/GRO (+ flood 시에만 shed)

확인된 사실 (측정 기반)

  1. 드롭은 NIC ring이 아니라 socket buffer에서 발생 — UdpRcvbufErrors가 rx_out_of_buffer의 15~18배
  2. lock도 syscall도 병목이 아니다 — producer lock을 99.9% 줄여도(patch 0003), recvmsg를 100배 줄여도(patch 0004) throughput 변화 없음
  3. bistable: 같은 offered rate에서 0% loss와 7-12% loss가 갈린다. 진입률은 약 **56%**이고 flow 시작 시점에 결정된다. 좋은 쪽에 들어가면 46 Gbps 무손실이 60초 이상 유지되고, 무너진 쪽은 41.5 Gbps에서 복구되지 않는다. 무엇이 진입을 결정하는지는 아직 규명하지 못했다 — DIM, 스케줄링 우선순위, 서버 프로세스 메모리 레이아웃, rate별 공진은 모두 실험으로 기각됐다
  4. threaded NAPI는 해법이 아니다: flood에서 19.2 G로 shed 없는 경우(19.6 G)와 동일. 문제는 스케줄링 공정성이 아니라 버려질 패킷에 낭비되는 작업량이다
  5. 캐시 효과는 TCP에서도 재현된다: tcp_rmem 상한을 6MB에서 512MB로 올리면 39.3 → 33.8 G (-14%), IPC 0.94 → 0.77. 프로토콜 무관한 일반 현상이다
  6. bad state의 정체는 DRAM-bound: IPC 1.08→0.64, cache-miss 17.5%→44%, LLC-miss 3.1배. 큐에 536MB가 적체되어 copyout 시점에 데이터가 캐시에서 밀려남
  7. GRO는 무죄: 두 상태에서 recvmsg 반환 크기 분포가 동일 (32-64KB super-skb)

수정 사항

patch 내용 결과
0006-udp-rcvbuf-autotune occupancy(rmem > rcvbuf/2) 기반 sk_rcvbuf 동적 확장 기본값 208KB에서 수동 512MB 튜닝과 동일 성능. plain 6.0→22 G (3.7배). 실사용 메모리는 1/100
0007-udp-early-drop socket layer에서 overflow 시 whole-skb 선폐기 효과 없음 (negative result) — 그 지점은 이미 skb build/GRO/스택 비용을 지불한 뒤라 너무 늦다
0008-udp-rx-shed-driver overflow 시 RX 큐에 shed window를 걸고 mlx5 CQE 레벨(skb 생성 전)에서 폐기 flood 시 goodput 9.5→16.7 G (+76%), %soft 52→27, consumer %sys 34→58

세 기능 모두 sysctl 런타임 토글이라 재부팅 없이 A/B 가능: net.ipv4.udp_rmem_autotune, udp_rmem_autotune_max, udp_early_drop, udp_rx_shed

설계 원칙

UDP 수신 버퍼의 상한은 "메모리"가 아니라 "캐시" 기준으로 정해야 한다.

버퍼 크기는 비단조(non-monotonic) 최적점을 가진다. 너무 작으면 GSO 버스트를 흡수하지 못하고, 너무 크면 적체가 LLC를 넘겨 copyout이 DRAM-bound가 된다.

정적 버퍼 크기 스윕 (진짜 단일코어, 2회 평균, L3 = 36 MiB):

정적 버퍼 b=35G b=40G flood 82G flood busy
208 KB (리눅스 기본값) 8.4 G 12.8 G 7.3 G 34%
512 KB 23.8 G 23.6 G 15.6 G 55%
1 MB 34.0 G 37.1 G 25.4 G 80%
1.5 MB 34.2 G 38.8 G 32.3 G 99%
3 MB 34.4 G 37.5 G 26.9 G 100%
8 MB 34.6 G 33.9 G 21.8 G 100%

최적점은 1.5 MB = L3의 1/24. 기본값 대비 4.4배, 512 MB 대비 2배다. 양쪽 실패 원인이 다르다는 점이 중요하다.

  • 너무 작으면(208 KB512 KB) core busy가 2655%에 그친다. CPU가 남는데도 받지 못한다 — GSO 버스트를 흡수하지 못해 shed가 과도하게 발동한다.
  • 너무 크면(3 MB 이상) core busy는 100%인데 goodput이 떨어진다. 적체가 LLC를 넘겨 copyout이 DRAM-bound가 되는 순손실이다.
  • 1.5 MB만 busy 99% 로 낭비 없이 포화한다. b=40G에서 38.8 G로 TCP(36.5 G)를 넘는다.

저장소 구성

patches/   커널 및 iperf3 패치 (0001-0008)
           iperf3 패치는 receiver/sender 빌드가 다르므로 주의 (ENVIRONMENT.md)
scripts/   실험 자동화 스크립트 (baseline, A/B, sweep, perf/bpftrace probe)
tools/     벤치마크 도구 (udp_blast, udp_sink, af_xdp_sink)
results/   측정 결과 요약 (raw 로그는 제외, summary와 CSV만)
docs/      분석 노트, 설계 문서, 실험 환경 문서

주요 문서:

재현

# 1. 환경 검증 후 baseline (docs/ENVIRONMENT.md의 방법론 필수)
./scripts/baseline_confirm_1c.sh vanilla30s 3

# 2. autotune A/B (stock / 수동 512MB / autotune)
./scripts/ab_autotune_1c.sh 2

# 3. driver-level shed A/B
./scripts/ab_shed_1c.sh 2

# 4. collapse curve (논문 Figure)
./scripts/sweep_collapse_curve.sh 2

# 5. 버퍼 크기 최적점 정밀 스윕
./scripts/sweep_static_rcvbuf.sh 2 15

스크립트는 control node(WSL2)에서 실행하며 sslab3/sslab4에 SSH로 명령을 보낸다.

상태

  • baseline 확정 (vanilla, 진짜 단일코어, 30s×3)
  • 비용 분해 (perf, bpftrace)
  • rcvbuf autotune 구현·검증
  • driver-level RX shed 구현·검증
  • bistability 원인 규명 (캐시 지역성)
  • 버퍼 최적점 정밀 확정 (1.5 MB)
  • autotune 기본 cap을 32 MB에서 1.5 MB로 수정
  • shed 히스테리시스 / startup guard (상태 진입 제어)
  • transparent GRO (app opt-in 없이 GRO 이득 제공)

About

SKKU SYSLAB Project: Optimize the UDP in Linux Kernel

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages