5 puan yazan GN⁺ 2024-07-29 | 1 yorum | WhatsApp'ta paylaş
  • Linux ağ performansı ayarı, paketlerin NIC halka tamponu, IRQ, NAPI, softIRQ, qdisc ve TCP tamponlarından geçerek uygulama soketine kadar ilerleyen akışını darboğazlar açısından yorumlama işidir
  • Alım yolunda NIC, paketleri DMA ile RAM’e yazar ve HardIRQ üretir; sürücü NAPI’yi zamanlayarak NET_RX_SOFTIRQ içinde halka tamponunu boşaltır, ardından IP/TCP katmanlarına ve soket alım tamponuna iletir
  • ethtool, /proc/net/softnet_stat, ss, netstat, sysctl gözlem ve ayarlamanın başlangıç noktalarıdır; kesme birleştirme, IRQ affinity, RSS/RPS/RFS/aRFS, netdev_budget, netdev_max_backlog, txqueuelen ve TCP read/write tamponları başlıca eksenlerdir
  • Tüm sistemlerde geçerli tek bir ayar yoktur; halka tamponunu büyütmek drop’ları azaltabilir ama gecikmeyi artırır, kesme birleştirme ise CPU kullanımını ve HardIRQ’ları azaltırken gecikme maliyeti yaratabilir
  • Yüksek performanslı paket işleme PACKET_MMAP, DPDK, PF_RING, XDP/AF_XDP gibi seçeneklerle genişler; ancak kernel bypass, zero-copy ve kernel içi hızlı yolun her birinde donanım bağımlılıkları, CPU işgali ve kernel sürümü gereksinimleri farklıdır

Linux alım yolu: NIC’ten sokete

  • Ağ aygıtı, paketin geldiğini bildirmek için IRQ üretir; Linux’ta IRQ eşlemeleri /proc/interrupts içinde tutulur
  • IRQ handler çok yüksek öncelikle çalışır ve bazı durumlarda ek IRQ üretilmesini engeller; bu yüzden sürücü uzun süren işleri IRQ bağlamının dışına erteler
  • Bu ertelenmiş işleme için softIRQ kullanılır; ağ alım işlemede her CPU için ksoftirqd/<cpu-number> kernel thread’i, softnet_data ve poll_list oluşturulur
  • net_dev_init, NET_RX_SOFTIRQ’yu softIRQ sistemine kaydeder; ilgili handler net_rx_action’dır
  • Paket gelişi ve NAPI işleme

    • NIC, ağdan aldığı veriyi DMA ile RAM’deki halka tamponuna yazar
    • Bazı NIC’ler birden fazla halka tamponuna sahip multiqueue NIC’lerdir
    • NIC HardIRQ ürettiğinde sürücünün IRQ handler’ı çalışır
    • Sürücü NIC’in IRQ’sunu temizler ve NAPI softIRQ poll döngüsünü başlatmak için napi_schedule çağırır
    • napi_schedule, sürücünün NAPI poll yapısını mevcut CPU’nun poll_list’ine ekler ve softIRQ pending bit’ini ayarlar
    • ksoftirqd, __do_softirq çağırdığında pending durumdaki NET_RX_SOFTIRQ’nun handler’ı olan net_rx_action çalışır
  • GRO ve protokol yığınına giriş

    • net_rx_action, NAPI poll listesini kontrol eder; softIRQ’nun CPU’yu tekeline almaması için budget ve geçen süreyi denetler
    • Sürücünün poll fonksiyonu, RAM’deki halka tamponundan paketleri toplar
    • Paketler napi_gro_receive’e iletilir
    • GRO (Generic Receive Offloading), küçük paketleri daha büyük paketler halinde yeniden birleştirerek uygulamanın işlemesi gereken paket sayısını azaltan yazılım tabanlı bir offloading tekniğidir
    • GRO paketi bekletmezse paket netif_receive_skb üzerinden protokol yığınının üst tarafına ilerler
  • RPS’nin etkin olup olmamasına göre dallanma

    • RPS devre dışıysa:
      • netif_receive_skb, veriyi __netif_receive_core’a iletir
      • __netif_receive_core, veriyi tap’lere ve kayıtlı protokol katmanı handler’larına iletir
    • RPS etkinse:
      • netif_receive_skb, veriyi enqueue_to_backlog’a iletir
      • Paket CPU başına input queue’ya girer
      • Uzak CPU’nun NAPI yapısı, o CPU’nun poll_list’ine eklenir ve uzak CPU’nun softIRQ thread’ini uyandırmak için bir IPI kuyruğa alınır
      • Uzak CPU’nun ksoftirqd’i, process_backlog poll fonksiyonuyla CPU input queue’dan paketleri toplar
  • IP, TCP ve soket alım tamponu

    • Paket IPv4 katmanında ip_rcv ile alınır; netfilter ve yönlendirme optimizasyonundan geçer
    • Mevcut sisteme yönelen veri, UDP veya TCP gibi üst protokol katmanlarına iletilir
    • TCP alım yolunda tcp_v4_rcv, TCP finite state machine ve soket aramasından geçerek alım tamponuna girer
    • Alım tamponu boyutu tcp_rmem kurallarına uyar
    • tcp_moderate_rcvbuf etkinleştirilirse kernel alım tamponunu otomatik olarak ayarlar
    • tcp_rmem, TCP soket alım tamponunun minimum, varsayılan ve maksimum değerlerini içerir
    • SO_RCVBUF kullanılırsa ilgili soketin alım tamponu otomatik ayarı devre dışı kalır
    • net.core.rmem_max, TCP alım tamponu boyutunun üst sınırıdır; daha büyük bir pencere, ACK gönderilmeden önce daha fazla verinin gönderilmesini sağlayarak gecikmeyi azaltıp throughput’u artırabilir

Linux gönderim yolu: uygulamadan NIC’e

  • Gönderim yolu alıma göre daha basittir, ancak qdisc, TCP write buffer, DMA ve IRQ devreye girer
  • Uygulama sendmsg gibi bir çağrıyla mesaj gönderdiğinde TCP gönderim yolu bir skb_buff ayırır
  • Paket, tcp_wmem boyutundaki soket write buffer’a girer
    • tcp_wmem, TCP soket gönderim tamponunun minimum, varsayılan ve maksimum değerlerini içerir
    • Kernel, TCP gönderim tamponu boyutunu minimum ve maksimum değerler arasında dinamik olarak ayarlar
    • SO_SNDBUF kullanılırsa ilgili soketin gönderim tamponu otomatik ayarı devre dışı kalır
    • net.core.wmem_max, TCP gönderim tamponu boyutunun üst sınırıdır
  • TCP header ve IP header oluşturulur; LOCAL_OUT, yönlendirme, POST_ROUTING ve fragmentation aşamalarından geçtikten sonra dev_queue_xmit ile L2 gönderim fonksiyonu çağrılır
  • Çıkış qdisc’i, txqueuelen uzunluğunu ve default_qdisc algoritmasını kullanır
  • Sürücü paketi TX halka tamponuna koyar ve tx-usecs timeout veya tx-frames sonrasında NET_TX_SOFTIRQ yürütülür
  • NIC, DMA ile paketi RAM’den alıp gönderir ve aktarım tamamlandıktan sonra HardIRQ üretir
  • Sürücü bu IRQ’yu işler ve RAM’i serbest bırakmak için NAPI poll sistemini zamanlar

Gözlem araçları ve temel kontrol noktaları

  • /proc/net/softnet_stat

    • /proc/net/softnet_stat içindeki her satır, CPU0’dan başlayarak bir CPU çekirdeğini temsil eder
    • Her sütundaki istatistikler onaltılık biçimde sağlanır
      1. sütun, interrupt handler’ın aldığı frame sayısıdır
      1. sütun, netdev_max_backlog aşıldığı için drop edilen frame sayısıdır
      1. sütun, işlenecek işler kalmışken ksoftirqd’nin netdev_budget veya CPU süresini tükettiği durumların sayısıdır
    • Kalan sütunlar Linux sürümüne göre değişebilir
  • /proc/net/sockstat ve ss

    • /proc/net/sockstat içinde mem alanı kontrol edilir
    • Bu değer, tüm socket’lerin sk_buff->truesize değerleri toplanarak hesaplanır
    • ss, socket istatistiklerini dump eden bir araçtır; netstat ile benzer bilgileri ve daha fazla TCP ile durum bilgisini gösterebilir
    • ss -tm, TCP socket’lerinin bellek kullanımını kontrol etmek için kullanılır
    • rmem_alloc: Alınan paketlere ayrılmış bellek
    • rcv_buf: Alınan paketlere ayrılabilecek toplam bellek
    • wmem_alloc: Katman 3’e zaten iletilmiş gönderim paketleri için kullanılan bellek
    • snd_buf: Gönderim paketlerine ayrılabilecek toplam bellek
    • wmem_queued: Henüz Katman 3’e iletilmemiş gönderim paketlerine ayrılmış bellek
    • sock_drop: Socket’e demultiplex edilmeden önce drop edilen paket sayısı
  • netstat ve sysctl

    • netstat, açık ağ bağlantılarını ve protokol stack istatistiklerini yazdıran bir komut satırı aracıdır; bilgileri /proc/net/ dosya sisteminden alır
    • /proc/net/dev: Cihaz bilgileri
    • /proc/net/tcp: TCP socket bilgileri
    • /proc/net/unix: Unix domain socket bilgileri
    • sysctl, /proc dosya sistemine doğrudan değer yazmak yerine sistem ve ağ ayarlarını değiştiren komuttur
    • sysctl -w variable=value geçici değişiklikler için kullanılır; kalıcı değişiklik için /etc/sysctl.conf düzenlenir ve ardından sysctl -p ile uygulanır

NIC ring buffer ve interrupt ayarı

  • NIC ring buffer

    • RX ring buffer, RAM’de bulunan sabit boyutlu bir FIFO dairesel buffer’dır
    • Ring buffer’ın kendisi paket verisini tutmaz; DMA ile RAM’e giren skb’yi işaret eden descriptor’ları tutar
    • Drop veya overrun görülürse queue boyutu artırılabilir, ancak yan etki olarak gecikme artabilir
    • Çoğu durumda yalnızca receive buffer boyutunu artırmak paket drop’larını önleyebilir ve kernel’a buffer’ı boşaltmak için biraz daha zaman kazandırır
    • Kontrol ve değişiklik ethtool ile yapılır
    • ethtool -g eth3: Mevcut RX/TX ring boyutlarını ve maksimum değerleri kontrol etme
    • ethtool -G eth3 rx 8192 tx 8192: RX/TX buffer’larını maksimum değere artırma
    • ethtool -S eth3 ve err, drop, over, miss, timeout, reset, collis gibi counter’larla izlenir
  • Donanım interrupt birleştirme

    • NIC, rx-usecs timeout’u veya rx-frames koşuluna kadar RX ring buffer’da paket reference’ları biriktirip ardından HardIRQ üretebilir; buna Interrupt coalescence denir
    • Interrupt çok erken verilirse kernel, çalışmakta olduğu işi sık sık keser ve sistem performansı kötüleşir
    • Interrupt çok geç verilirse NIC trafiği yeterince hızlı boşaltamaz; overwrite ve trafik kaybı oluşabilir
    • Interrupt birleştirme ayarı CPU kullanımını ve HardIRQ’leri azaltıp throughput’u artırabilir, ancak gecikme maliyeti doğurabilir
    • ethtool -c eth3 ile coalesce parametreleri kontrol edilir; ethtool -C eth3 adaptive-rx off rx-usecs 0 rx-frames 0 gibi değiştirilebilir
    • Adaptive mode, kartın trafik pattern’lerine ve kernel receive pattern’lerine bakarak coalescing ayarlarını dinamik olarak tahmin etmesini sağlar

IRQ affinity ve CPU’lar arasında yük dengeleme

  • IRQ affinity

    • IRQ’larda, ilgili IRQ’nun ISR’ını çalıştırabilecek CPU çekirdeklerini tanımlayan smp_affinity özelliği bulunur
    • Interrupt affinity ve uygulama thread affinity belirli CPU çekirdeklerine hizalanırsa, cache line paylaşımı sayesinde uygulama performansı iyileşebilir
    • Varsayılan olarak kontrol irqbalance daemon’undadır
    • Manuel ayardan önce irqbalance durdurulmalıdır
    • /proc/irq/<IRQ_NUMBER>/smp_affinity, CPU çekirdeklerini temsil eden onaltılık bir bitmask saklar
    • 4 çekirdekli bir sunucuda varsayılan değer f, IRQ’nun tüm CPU’larda işlenebileceği anlamına gelir
    • echo 1 > /proc/irq/32/smp_affinity yalnızca CPU0’ın kullanılmasını sağlar
    • 32 çekirdeği aşan sistemlerde 32-bit group’lar virgülle ayrılır
    • IRQ affinity, yalnızca çok belirli yapılandırmalarda ve önceden tanımlanmış iş yüklerinde performansı artırabilir; iki ucu keskin kılıç olabilir
  • RSS

    • Hızlı bir NIC’te paketler tek bir queue ve tek bir CPU ile alınırsa, veri işleme sorumluluğunun tamamı tek bir çekirdeğe kalabilir ve diğer çekirdekler idle durumda olabilir
    • RSS(Receive-side scaling), NIC’in trafiği birden fazla gönderim/alım queue’suna dağıtmasını sağlayan bir NIC teknolojisidir
    • NIC, source/destination IP ile TCP/UDP source/destination port temelinde hash hesaplar; aynı flow’a ait paketleri tek bir queue’ya atar ve flow’ları queue’lar arasında dengeli dağıtır
    • RSS, multiprocessing ortamlarında paralel receive processing avantajı sağlar
    • Linux kernel belgelerine göre RSS, gecikmenin önemli olduğu veya receive interrupt işlemenin darboğaz olduğu durumlarda etkinleştirilmelidir; düşük gecikmeli networking’de sistemdeki CPU sayısı kadar queue atanması en iyi ayardır
  • RPS, RFS, aRFS

    • RPS(Receive Packet Steering), RSS’in yazılım uygulamasına yakındır
    • RSS donanım interrupt handler’ını çalıştıracak queue ve CPU’yu seçerken, RPS interrupt handler’ın üstündeki protokol işlemesini yapacak CPU’yu seçer
    • CONFIG_RPS gereklidir ve SMP’de varsayılan olarak etkindir
    • Ayar, /sys/class/net/<dev>/queues/rx-<n>/rps_cpus içindeki CPU bitmap’iyle yapılır
    • RSS varsa gereksiz olabilir, ancak CPU sayısı queue sayısından fazlaysa kullanışlı olabilir
    • RFS(Receive Flow Steering), RPS’i uygulama locality’sine kadar genişletir
    • RPS paketleri flow temelinde dağıtır, ancak user space uygulamasının hangi CPU’da çalıştığını dikkate almaz
    • RFS, global flow-to-CPU table olan rps_sock_flow_table’ı tutar
    • net.core.rps_sock_flow_entries ile table boyutu ayarlanabilir
    • Per-queue rps_dev_flow_table, scheduler uygulamayı yeni bir CPU’ya taşıdığında kalan paketler nedeniyle sıralamanın bozulması sorununu azaltmak için kullanılır
    • aRFS(Accelerated RFS), RFS için donanım hızlandırmalı bir yük dengeleme mekanizmasıdır
    • Paketleri veriyi tüketen thread’e yakın CPU’ya doğrudan gönderdiği için RFS’ten daha iyi performans sağlayabilir
    • NIC’in ndo_rx_flow_steer, ntuple filtering ve CONFIG_RFS_ACCEL desteği gerekir
    • CPU ve queue eşlemesi, her receive queue’sunun IRQ affinity’sinden otomatik olarak türetildiği için ek ayar gerekmez

softIRQ, qdisc, TCP arabellek ayarı

  • softIRQ bütçesi

    • NAPI polling rutini netdev_budget_usecs, netdev_budget, dev_weight ile sınırlandırılarak softIRQ’nun CPU’yu tekeline almaması sağlanır
    • net.core.netdev_budget varsayılan değeri 300’dür; bu, softIRQ sürecinin CPU’dan ayrılmadan önce NIC’ten 300 mesajı boşaltması anlamına gelir
    • net.core.netdev_budget_usecs, bir NAPI polling cycle’ının maksimum mikrosaniye sayısıdır
    • net.core.dev_weight, bir NAPI interrupt’ında çekirdeğin CPU başına işleyebileceği maksimum paket sayısıdır
    • /proc/net/softnet_stat içinde 1. sütun dışındaki sütunlar artıyorsa budget değişikliği gerekebilir; küçük artışlar normal olabilir
  • ingress qdisc ve netdev_max_backlog

    • netdev_max_backlog, NIC’ten alındıktan sonra IP/TCP gibi protokol yığını tarafından işlenmeden önce trafiğin saklandığı çekirdeğin dahili kuyruğudur
    • Her CPU çekirdeği için bir backlog queue bulunur
    • Arayüz, çekirdeğin işleyebileceğinden daha hızlı paket alırsa INPUT tarafındaki kuyruk netdev_max_backlog değerine kadar dolar ve aşılırsa paketler düşürülür
    • Varsayılan değer 1000’dir; birden fazla 1Gbps arayüz veya tek bir 10Gbps arayüz için yetersiz olabilir
    • /proc/net/softnet_stat içindeki 2. sütun, backlog queue overflow nedeniyle artan sayaçtır
    • Değer değişikliği sysctl -w net.core.netdev_max_backlog <value> ile yapılır
  • egress qdisc, txqueuelen, default_qdisc

    • txqueuelen, ağ arayüzü aygıtının çekirdek transmit queue’sunda izin verilen paket sayısını ayarlar
    • Varsayılan değer arayüz sürücüsüne bağlı olarak 1000 olabilir
    • ifconfig <interface> txqueuelen value ile değiştirilir; ip -s link içinde RX/TX dropped değerleri kontrol edilir
    • default_qdisc, ağ aygıtında kullanılacak varsayılan queuing discipline’dır
    • pfifo_fast yerine sfq, codel, fq_codel gibi alternatifler belirtilebilir
    • tc -s qdisc ls dev <interface> içinde dropped, overlimits, requeues gibi metrikler kontrol edilir
  • TCP okuma/yazma arabelleği ve bağlantı kuyrukları

    • tcp_rmem ve tcp_wmem, sırasıyla TCP alma ve gönderme arabelleklerinin minimum, varsayılan ve maksimum değerlerini tanımlar
    • Değişiklik aşağıdaki gibi yapılır
      • sysctl -w net.ipv4.tcp_rmem="min default max"
      • sysctl -w net.ipv4.tcp_wmem="min default max"
    • Arabellek kullanım durumu /proc/net/sockstat ile kontrol edilir
    • Accept queue ve SYN queue, net.core.somaxconn ile net.ipv4.tcp_max_syn_backlog tarafından etkilenir
    • net.core.somaxconn, listen() içindeki backlog parametresinin üst sınırıdır; bu değeri değiştirirseniz uygulamanın da uyumlu bir değere değiştirilmesi gerekir
    • net.ipv4.tcp_syncookies, SYN flood saldırılarına karşı korumada yararlı olan SYN cookie’lerini açar veya kapatır
    • net.ipv4.tcp_congestion_control, yeni bağlantılarda kullanılacak congestion control algoritmasını ayarlar

NUMA ve ağ performansı

  • NUMA (Non-uniform memory access), işlemcinin local memory’ye non-local memory’den daha hızlı erişebildiği bir bellek mimarisidir
  • Ağ işlemede CPU’nun ring buffer belleğine erişmesi gerektiğinden, NUMA locality ağ performansını etkileyebilir
  • NUMA; CPU, bellek ve aygıtları birden fazla node’a ayırır ve hızlı interconnect ile ortak bir OS’e sahip birkaç küçük bilgisayar gibi çalışır
  • NUMA sistemlerinde tuning hedefi, bir aygıtın interrupt’larını o aygıtın ait olduğu tek bir node’daki CPU çekirdeklerinde toplamaktır
  • Ancak NUMA sistemleri gerçek zamanlı uygulamalarla iyi etkileşmeyerek beklenmeyen olay gecikmeleri yaratabilir
  • NUMA node’ları /sys/devices/system/node/node* ile kontrol edilir
  • Aygıt locality’si /sys/class/net/<interface>/device/numa_node ile kontrol edilir
    • -1, donanım platformunun gerçek NUMA olmadığı, çekirdeğin NUMA’yı taklit ettiği veya aygıtta NUMA locality bulunmadığı anlamına gelir
  • Linux kernel 2.5’ten beri NUMA’yı destekler; RedHat ve Debian tabanlı dağıtımlar numactl, numad sağlar
  • numad, sistem topology’sini ve kaynak kullanımını izler; yeterince büyük bellek ve CPU yüküne sahip süreçleri verimli NUMA locality’ye yerleştirmeye çalışır

Daha Hızlı Paket İşleme Seçenekleri

  • AF_PACKET v4 ve PACKET_MMAP

    • AF_PACKET v4, Linux’un hızlı paket arayüzüdür; veri yolunda system call’ları ortadan kaldırır ve varsayılan olarak copy-mode kullanır
    • PACKET_ZEROCOPY kullanıldığında, DMA packet buffer’ını kullanıcı alanına eşleyen gerçek zero-copy modu kullanılabilir
    • Tipik file read ardından socket send yolu, user mode ile kernel mode arasında context switch ve verinin birden çok kez copy edilmesini gerektirir
    • zero-copy, yinelenen veri copy işlemlerini ortadan kaldırarak performansı artırır
    • PACKET_MMAP, hızlı packet sniffing için bir Linux API’sidir
    • Kullanıcı alanı ile çekirdeğin paylaştığı mmapped ring buffer sağlar
    • Gönderilen ve alınan paketlerde system call’ları ve kullanıcı alanı ile çekirdek arasındaki copy işlemlerini azaltır
  • DPDK

    • DPDK(Data Plane Development Kit), hızlı paket işleme için kullanıcı alanı kütüphaneleri ve sürücü framework’üdür
    • Amacı, NIC ile kullanıcı uygulaması arasında ağ paketlerini native speed ile alıp göndermektir
    • 10Gb veya 40Gb NIC’leri hedefler; hız en önemli ölçüttür
    • Ağ stack’inden ziyade packet forwarding’e odaklanır
    • DPDK NIC’i kontrol ettiğinde tüm trafik çekirdeği bypass eder ve ilgili NIC çekirdek tarafından görünmez
    • Portlar Linux çekirdek sürücüsünden unbind edilir ve vfio_pci, igb_uio, uio_pci_generic gibi sürücüler tarafından yönetilir
    • Sonrasında uygulama ile NIC arasındaki iletişimden DPDK PMD sorumlu olur
    • DPDK, büyük memory chunk’ları ayırmak için hugepages yapılandırması gerektirir
    • Başlıca bileşenler:
      • EAL: ortam farklarını gizleyen generic interface
      • librte_ring: lockless multi-producer, multi-consumer FIFO API
      • librte_mempool: bellek nesnesi pool tahsisi
      • librte_mbuf: ağ paketlerini tutan buffer oluşturma ve işleme
      • librte_timer: asenkron fonksiyon çalıştırma için timer service
      • PMD: interrupt yerine CPU’nun NIC’i sürekli poll ettiği sürücü
    • Sınırlamalar:
      • Donanıma bağımlılığı yüksektir
      • PMD’yi çalıştırmak için CPU core’u özel olarak ayırmak gerekir ve %100 CPU kullanır
  • PF_RING

    • PF_RING, paketleri yüksek hızda işleyen ve paket işleme uygulamalarına tutarlı bir API sağlayan bir Linux kernel module ve user-space framework’tür
    • PF_RING, NIC’ten paketleri Linux NAPI ile poll eder
    • NAPI, paketleri NIC’ten PF_RING circular buffer’a kopyalar; kullanıcı alanı uygulaması da ring’den paketleri okur
    • Bu yapıda uygulama ve NAPI olmak üzere iki poller vardır; CPU cycle’ları polling için harcanır
    • Avantajı, incoming packet’ları aynı anda birden çok ring’e dağıtabilmesidir
    • Modüler yapısıyla ZC module, FPGA-based card module, Stack module, Timeline module, Sysdig module gibi ek bileşenler kullanılabilir
    • PF_RING, packet capture ve userland forwarding maliyetini azaltmıştır; ancak çekirdeğin NIC’ten ring’e kopyalaması ve userland’in ring’den okuyup işlemesi şeklindeki iki actor’lü yapı nedeniyle en iyi performansın bir sınırı vardır
    • PF_RING, 7.5 sürümünden itibaren AF_XDP adapter desteği içerir
  • XDP ve AF_XDP

    • XDP(eXpress Data Path), Linux ağ veri yolunda paketleri erken aşamada yakalayan bir eBPF uygulamasıdır
    • XDP, SKB tahsisinden önce, device driver RX function içinde RX packet page’i doğrudan işler
    • eBPF, çekirdekte çalışan kullanıcı tanımlı sandboxed bytecode’dur
    • 11 adet 64-bit register ve 512-byte stack kullanır
    • LLVM backend ile C, Lua, Go, P4, Rust gibi dillerden eBPF’ye derlenebilir
    • in-kernel verifier ve JIT compiler sağlar; map, tail call, helper gibi özellikleri destekler
    • XDP kullanım alanları:
      • DoS azaltımı için pre-stack filtering
      • forwarding ve load balancing
      • GRO gibi batching teknikleri
      • flow sampling ve monitoring
      • ULP processing
    • XDP, kernel bypass değil; çekirdek stack’i içindeki fast path’tir ve TCP/IP stack’inin yerini almaz
    • Özel donanım gerekmez, ancak multi-queue NIC, TX/RX checksum offload, RSS, TSO gibi gereksinimler vardır
    • DPDK’ye kıyasla XDP avantajları:
      • busy polling veya interrupt driven networking seçilebilir
      • huge pages gerekmez
      • Özel donanım gereksinimi yoktur
      • Adanmış CPU zorunlu değildir
      • 3rd party userspace application’dan paketleri tekrar çekirdeğe enjekte etmek gerekmez
      • Ağ donanımına erişim için yeni bir security model gerekmez
      • 3rd party code/licensing gerekmez
    • AF_XDP, Linux 4.18’de tanıtılan yeni bir socket türüdür
    • Çekirdeği tamamen bypass etmeden, çekirdek özelliklerinden yararlanarak DPDK veya AF_PACKET benzeri bir yapı oluşturabilir
    • XDP programı, eBPF ile frame’i kullanıcı alanındaki memory buffer’a redirect edebilir
    • DMA transfer, kullanıcı alanı belleğini kullanarak zero-copy’yi destekler
    • AF_PACKET’a kıyasla 3 ila 20 kat performans artışı sağlayabilir
    • Sınırlamalar:
      • Görece genç bir projedir
      • Tam destek için Linux kernel 5.4 veya üzeri gerekir

1 yorum

 
GN⁺ 2024-07-29
Hacker News yorumları
  • Bunu sadece birkaç hafta önce görmüş olsaydım gerçekten çok faydalı olurdu
    Veri merkezleri arasında L2 bağlantı şifrelemesi yapmak için çeşitli satıcılardan donanım appliance teklifleri aldım, ama maliyetleri fazla yüksek bulduğum için kendim yapmayı denedim
    Genel amaçlı donanım üzerinde, WireGuard overlay ağı üzerinden Ethernet frame'leri taşıyıp 10Gbps verecek şekilde kurdum; yaklaşık on günlük çalışmanın sonunda en ucuz tekliften yaklaşık %70, en pahalı tekliften ise yaklaşık %95 daha ucuza gerçekleştirdim, ama bunun için çok fazla ayrıntılı doküman okuma ve deney yapmak gerekti
    Bu yazıdaki içerikle benim anlayışımın doğru olup olmadığını doğrulamak isterim; ilk bakışta bile umut verici ve kapsamlı görünüyor

    • Merak ettim, hangi kullanım durumu için L3 tünel yeterli olmadı?
    • Kodu paylaşabiliyorsan görmek isterim. Böyle bir şeyi nasıl uyguladığını gerçekten çok merak ediyorum
  • Ayarlanabilir değer bu kadar fazlaysa, otomatik ayarlama yazılımı yapmaya değer olabilir diye düşünüyorum
    Beyaz listedeki parametrelerden rastgele seçip izin verilen aralıkta biraz artırıp azaltmak, bir süre performansı ölçmek, kötüleşirse geri almak, iyileşirse biraz daha ayarlamak gibi gradyan inişine benzer bir yaklaşım mümkün görünüyor

  • İlginç, ama bir yazılım mühendisi olarak yazıdaki komutları gerçekten çalıştırma fırsatım neredeyse hiç olmuyor
    Sistemler çoğunlukla Linux'un kırpılmış bir sürümünü kullanan container'larda çalışıyor, canlı sistemlere shell erişimi yok ve geliştirme ya da QA ortamları yük gibi açılardan canlıdan o kadar farklı ki hata yeniden üretimi çoğu zaman pek yardımcı olmuyor
    Sonuçta yazıdaki komutları deneme fırsatı daha çok kişisel sistemimle uğraşırken oluyor; platform mühendisi olarak çalışıyorsanız faydalı olabilir gibi görünüyor

    • Düşük seviyeli özelliklerin çoğu zaten ya çalışmayacak ya da pek işe yaramayacaktır. Container ağ arayüzü uygulamaları genelde sizi veth çifti ile uğraştırır ve kullanıcı alanında türlü tuhaf işlemler yapar
      Kubernetes'te çok sevmediğim şeylerden biri de ağ modeli. Tek bir ağ kartı varmış gibi varsayıyor ve uygulamaların bunun alt katmanları hakkında bilgiye ihtiyaç duymayacak kadar basit olduğunu kabul ediyor
      Tüm ağ modeli, basitleştirme ve iyileştirme açısından 2020'ler tarzında büyük bir elden geçirmeyi hak ediyor gibi görünüyor
    • Canlıya mümkün olduğunca benzeyen bir staging ortamı varsa, erişiminizin olduğu canlı benzeri bir ortamda deney ve analiz yapmak duruma göre faydalı olabilir
  • net.core.wmem_max TCP gönderim tamponu boyutunun üst sınırı olarak açıklanmış, bir de net.ipv4.tcp_wmem var; bu ikisiyle ilgili iki şey merak ediyorum

    1. Neden IPv6 karşılığı yok, 2. net.core.wmem_maxtan farkı ne?
    • net.core.wmem_max, adından da anlaşılacağı gibi azami değer
      net.ipv4.tcp_wmem ise minimum, varsayılan ve maksimum olmak üzere üç değerden oluşan bir üçlü; burada belirtilen maksimum değer, yukarıdaki net.core.wmem_max değerini aşamaz
      TCP, IPv4 üzerinden de IPv6 üzerinden de taşınsa aynı protokol olarak kalır
      Örnek: https://docs.redhat.com/en/documentation/red_hat_data_grid/7...
  • Burada biraz eksik kalan şey, 100Gbps üzeri throughput için hata ayıklama ve ayarlama konusu
    O ölçekte HTTP servis ediyorsanız ilk darboğaz çoğu zaman bellek bant genişliği olur; bu yüzden sıkça kTLS gerekir
    AMD μProf gibi araçlar hata ayıklamada çok faydalıdır ve çekirdek ile kullanıcı alanında tam olarak neler olduğunu anlamak için eBPF tabanlı sürekli profiling de yardımcı olur

  • Oldukça hoş görünüyor. Şimdiye kadarki kariyerimde performans gerektiğinde genelde işe kernel bypass ile başladım