Share
Embed
Transcript
68 slides
-
ࠓͷτϐοΫ 1. ׂΓࠐΈ͕ଟ͗͢Δ 2. ϓϩτίϧॲཧ͕ॏ͍ 3. ෳͷCPUͰύέοτॲཧ͍ͨ͠ 4. σʔλҠಈʹ͏ϨΠςϯγͷݮ 5.
ϓϩτίϧελοΫΛܦ༝͠ͳ͍ωοτϫʔ ΫIO -
1. ׂΓࠐΈ͕ଟ͗͢Δ Process(User) Process(Kernel) HW Intr Handler SW Intr Handler
ύέοτड৴ ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS input queue socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ -
چདྷͷύέοτड৴ॲཧ Process(User) Process(Kernel) HW Intr Handler SW Intr Handler ύέοτड৴
ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS input queue socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ϋʔυΣΞׂΓࠐΈ ˣ ड৴ΩϡʔʹΩϡʔ Πϯά ˣ ιϑτΣΞׂΓࠐ Έεέδϡʔϧ -
ׂΓࠐΈΛແޮʹ͢Δʁ • ϙʔϦϯάํࣜ • NICͷׂΓࠐΈΛېࢭ͠ɺΘΓʹΫϩοΫׂΓࠐΈΛ༻ ͍ͯఆظతʹड৴ΩϡʔΛνΣοΫ • σϝϦοτɿϨΠςϯγ্͕͕ΔɾఆظతʹCPUΛى͜͢ ඞཁ͕͋Δ •
ϋΠϒϦουํࣜ • ௨৴ྔ͕ଟ͘࿈ଓͯ͠ύέοτॲཧΛߦ͍ͬͯΔ࣌ͷΈׂ ΓࠐΈΛແޮԽͯ͠ϙʔϦϯάͰಈ࡞ -
NAPIʢϋΠϒϦουํ ࣜʣ Process(User) Process(Kernel) HW Intr Handler SW Intr Handler
ׂΓࠐΈແޮԽ ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ύέοτड৴ ύέοτ͕ແ͘ͳΔ ·Ͱ܁Γฦ͠ ϋʔυΣΞׂΓࠐΈ ˣ ׂΓࠐΈແޮԽˍ ϙʔϦϯά։࢝ ↓ ύέοτ͕ແ͘ͳͬ ͨΒׂΓࠐΈ༗ޮԽ -
Interrupt CoalescingͷޮՌ • Intel 82599(ixgbe)ͰInterrupt Coalescingແޮɺ ༗ޮʢׂΓࠐΈසࣗಈௐʣͰൺֱ • MultiQueue, GRO,
LROແޮԽ • iperfͷTCPϞʔυͰܭଌ interrupts throughput packets CPU%(sy+si) ແޮ 46687 int/s 7.82 Gbps 660386 pkt/s 97.6% ༗ޮ 7994 int/s 8.24 Gbps 711132 pkt/s 79.6% -
Process(User) Process(Kernel) HW Intr Handler SW Intr Handler ׂΓࠐΈແޮԽ ϓϩτίϧॲཧ
ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ύέοτड৴ ύέοτ͕ແ͘ͳΔ ·Ͱ܁Γฦ͠ 2.ϓϩτίϧॲཧ͕ॏ͍ -
TOE (TCP Offload Engine) • OSͰϓϩτίϧॲཧ͢ΔͷΛΊͯɺNICͰॲཧ͢Δ • σϝϦοτ • ηΩϡϦςΟɿTOEʹηΩϡϦςΟϗʔϧ͕ੜͯ͡ɺOS
ଆ͔Βରॲ͕ग़དྷͳ͍ • ෳࡶੑɿOSͷωοτϫʔΫελοΫΛTOEͰஔ͖͑Δʹ ͔ͳΓൣғͷมߋ͕ඞཁ ϝʔΧʹΑͬͯTOEͷ࣮͕ҟͳΓڞ௨ΠϯλϑΣʔεఆ ͕ٛࠔ • Linuxɿαϙʔτ༧ఆແ͠ -
Checksum Offloading ͷޮՌ • Intel 82599(ixgbe)Ͱൺֱ • iperfͷTCPϞʔυͰܭଌ • MultiQueueແޮԽ
• ethtool -K ix0 rx off throughput CPU%(sy+si) ແޮ 8.27 Gbps 86 ༗ޮ 8.27 Gbps 85.2 -
LRO (Large Receive Offload) • NIC͕ड৴ͨ͠TCPύέοτΛ݁߹͠ɺ େ͖ͳύέοτʹ͔ͯ͠ΒOS͢ • ϓϩτίϧελοΫͷݺͼग़͠ճΛ ݮ
• LinuxͰιϑτΣΞʹΑΔLRO͕࣮ ͞Ε͍ͯΔʢGROʣ -
LRO͕ແ͍߹ • ύέοτຖʹωοτϫʔΫελοΫΛ ࣮ߦ seq 10000 seq 10001 seq 10002
seq 10003 ←1500bytes→ To network stack -
LRO͕༗Δ߹ • ύέοτΛ݁߹͔ͯ͠ΒωοτϫʔΫελοΫΛ ࣮ߦɺωοτϫʔΫελοΫͷ࣮ߦճΛݮ seq 10000 seq 10001 seq 10002
seq 10003 ←1500bytes→ To network stack big one packet -
GROͷޮՌ • Intel 82599(ixgbe)Ͱൺֱ • MultiQueueແޮԽ • iperfͷTCPϞʔυͰܭଌ • ethtool
-K ix0 gro off packets network stack called count throughput CPU%(sy+si) ແޮ 632139 pkt/s 632139 call/s 7.30 Gbps 97.6% ༗ޮ 712387 pkt/s 47957 call/s 8.25 Gbps 79.6% -
TSO (TCP Segmentation Offload) • LROͷٯ • ύέοτΛϑϥάϝϯτԽͤͣʹૹ৴ NIC͕ύέοτΛMTUαΠζʹׂ •
OSύέοτׂॲཧΛলུग़དྷΔ • LinuxͰιϑτΣΞʹΑΔGSOɺ ϋʔυΣΞʹΑΔTSOʗUFOΛαϙʔτ -
TSOͷޮՌ • Intel 82599(ixgbe)Ͱൺֱ • MultiQueueແޮԽ • iperfͷTCPϞʔυͰܭଌ • ethtool
-K ix0 gso off tso off packets throughput CPU%(sy+si) ແޮ 247794 pkt/s 2.87 Gbps 53.5% ༗ޮ 713127 pkt/s 8.16 Gbps 26.8% -
3.ෳͷCPUͰύέοτॲཧ͍ͨ͠ cpu0 Process(User) Process(Kernel) HW Intr Handler SW Intr Handler
ׂΓࠐΈແޮԽ ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ύέοτड৴ ύέοτ͕ແ͘ͳΔ ·Ͱ܁Γฦ͠ cpu1 Process(User) Process(Kernel) HW Intr Handler SW Intr Handler ׂΓࠐΈແޮԽ ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ύέοτड৴ ύέοτ͕ແ͘ͳΔ ·Ͱ܁Γฦ͠ -
ιϑτׂΓࠐΈͱʁ Process(User) Process(Kernel) HW Intr Handler SW Intr Handler ׂΓࠐΈແޮԽ
ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ύέοτड৴ ύέοτ͕ແ͘ͳΔ ·Ͱ܁Γฦ͠ ϙʔϦϯά͔Β ϓϩτίϧॲཧ·Ͱ →ωοτϫʔΫIOͷ େ෦ -
TCP Reordering • γʔέϯεφϯόʔ௨ΓͷॱংͰύέο τ͕ண৴͍ͯ͠ΕॱʹόοϑΝίϐʔ ͍͚ͯͩ͘͠ͰΑ͍͕… ̍
̍ protocol processing user buffer -
TCP Reordering ̍ ̍
protocol processing user buffer SFPSEFS RVFVF • ॱং͕ཚΕ͍ͯΔͱύέοτͷฒ ͠ʢϦΦʔμʣ࡞ۀ͕ඞཁʹͳΔ -
RSS ʢReceive Side Scalingʣ • CPU͝ͱʹผʑͷड৴ΩϡʔΛ࣋ͭNIC ʢMultiQueue NICͱݺΕΔʣ • ड৴Ωϡʔ͝ͱʹಠׂཱͨ͠ΓࠐΈΛ࣋ͭ
• ಉ͡ϑϩʔʹଐ͢Δύέοτಉ͡Ωϡʔɺ ҟͳΔϑϩʔʹଐ͢ΔύέοτͳΔ͘ผͷ Ωϡʔࢄ ˠύέοτϔομͷϋογϡΛܭࢉ͢ΔࣄʹΑ ΓѼઌΩϡʔΛܾఆ -
RSSʹΑΔ ύέοτৼΓ͚ NIC ύέοτ ύέοτ ύέοτ ϋογϡܭࢉ ύέοτண৴ hash queue
σΟεύον ࢀর RX Queue #0 RX Queue #1 RX Queue #2 RX Queue #3 cpu0 cpu1 cpu2 cpu3 ड৴ॲཧ ׂΓࠐΈ ड৴ॲཧ ▪ ▪ 0 1 -
Ωϡʔબͷखॱ indirection_table[64] = initial_value input[12] = {src_addr, dst_addr, src_port,
dst_port} key = toeplitz_hash(input, 12) index = key & 0x3f queue = indirection_table[index] -
RPS • RSSඇରԠͷΦϯϘʔυNICΛ͏·͔ͭͬͯ͘αʔ όͷੑೳΛ্͍ͤͨ͞ • ιϑτͰRSSΛ࣮ͯ͠͠·͓͏ • ιϑτׂΓࠐΈͷஈ֊ͰύέοτΛ֤CPUΒ ·͘ •
CPUׂؒΓࠐΈΛͬͯଞͷCPUΛՔಈͤ͞Δ • RSSͷιϑτΤΞʹΑΔΤϛϡϨʔγϣϯ -
cpu3 cpu2 cpu1 cpu0 ׂΓࠐΈແޮԽ ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ
VTFS CV⒎FS socket queue ύέοτ γεςϜ ίʔϧ ϓϩηεىচ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ ύέοτ ύέοτ ιϑτΣΞׂΓࠐΈ ύέοτड৴ ϋογϡܭࢉ σΟεύον ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS socket queue backlog #1 hash queue ࢀর ▪ ▪ 0 1 $16ؒ ׂΓࠐΈ backlog #2 backlog #3 -
RPSͷ͍ํ # echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus # echo 4096 >
/sys/class/net/eth0/queues/rx-0/ rps_flow_cnt -
RPS netperf result netperf benchmark result on lwn.net: e1000e on
8 core Intel Without RPS: 90K tps at 33% CPU With RPS: 239K tps at 60% CPU ! foredeth on 16 core AMD Without RPS: 103K tps at 15% CPU With RPS: 285K tps at 49% CPU -
RFSͷ͍ํ # echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus # echo 4096 >
/sys/class/net/eth0/queues/rx-0/rps_flow_cnt # echo 32768 > /proc/sys/net/core/rps_sock_flow_entries -
RFS netperf result netperf benchmark result on lwn.net: e1000e on
8 core Intel No RFS or RPS 104K tps at 30% CPU No RFS (best RPS config): 290K tps at 63% CPU RFS 303K tps at 61% CPU ! RPC test tps CPU% 50/90/99% usec latency StdDev No RFS or RPS 103K 48% 757/900/3185 4472.35 RPS only: 174K 73% 415/993/2468 491.66 RFS 223K 73% 379/651/1382 315.61 -
Accelerated RFS • RFSΛMultiQueue NICͰ࣮ݱ͢ΔͨΊ ͷNICυϥΠό֦ு • Linux kernelϓϩηεͷ࣮ߦதCPUΛ NICυϥΠόʹ௨
• NICυϥΠό௨Λड͚ͯϑϩʔͷ ΩϡʔׂΓͯΛߋ৽ -
Flow Steering • ϑϩʔͱΩϡʔͷରԠใΛهԱ 4tupleɿΩϡʔ൪߸ͷΑ͏ͳܗࣜͰઃఆ • RSSͷΑ͏ͳ໌֬ͳڞ௨༷ແ͍͕ɺ ֤ࣾͷ10GbEʹ࣮͞Ε͍ͯΔ • Accelerated
RFSFlow SteeringΛલఏͱ ͍ͯ͠Δ -
Flow SteeringͰ खಈϑΟϧλઃఆ # ethtool --config-nfc ix00 flow-type tcp4 src-ip
10.0.0.1 dst-ip 10.0.0.2 src-port 10000 dst-port 10001 action 6 Added rule with ID 2045 -
XPSͷ͍ํ # echo 1 > /sys/class/net/eth0/queues/tx-0/xps_cpus # echo 2 >
/sys/class/net/eth0/queues/tx-1/xps_cpus # echo 4 > /sys/class/net/eth0/queues/tx-2/xps_cpus # echo 8 > /sys/class/net/eth0/queues/tx-3/xps_cpus -
Intel Data Direct I/O Technology • NIC͕DMAͨ͠ύέοτͷσʔλɺ࠷ॳʹCPU ͕ΞΫηεͨ࣌͠ʹඞͣΩϟογϡώοτϛεΛ ى͜͢ ɹɹɹɹɹɹɹɹɹˣ
• CPUͷLLCʢࡾ࣍ΩϟογϡʣʹDMAͯ͠͠·͑ʂ • ৽͍͠XeonͱIntel 10GbEͰαϙʔτ • OSରԠෆཁʢHW͕ಁաతʹఏڙ͢Δػೳʣ -
ίϐʔ͕ॏ͍ Process(User) Process(Kernel) HW Intr Handler SW Intr Handler ύέοτड৴
ϓϩτίϧॲཧ ιέοτ ड৴ॲཧ Ϣʔβ ϓϩάϥϜ VTFS CV⒎FS input queue socket queue ύέοτ γεςϜίʔϧ ϓϩηεىচ ιϑτΣΞׂΓࠐΈεέδϡʔϧ ϋʔυΣΞׂΓࠐΈ Ϣʔβۭؒίϐʔ -
ίϐʔ͕ॏ͍͕ θϩίϐʔԽࠔ • NICͷDMAόοϑΝΩϡʔຖʹઃఆͰ͖Δ͕ϑ ϩʔຖͰͳ͍ ˠͦͦΩϡʔΛҰͭͷΞϓϦͰઐ༗ग़དྷΔલ ఏͰͳ͍ͱແཧ • όοϑΝ͕ϖʔδαΠζʹΞϥΠϯɾΞϩέʔτ ͞Εͯͳ͍ͱແཧ
• ύέοτϔομͱϖΠϩʔυ͕͞Εͯͳ͍ͱ όοϑΝʹύέοτϔομ·Ͱॻ͔Εͯ͠·͏ -
• ʢIntel I/O ATͱݺΕΔʣ • NICͷόοϑΝˠΞϓϦέʔγϣϯͷόο ϑΝDMAసૹ • CPUෛՙΛݮ •
νοϓηοτʹ࣮ • CONFIG_NET_DMA=y in Linux Intel QuickData Technology -
ϓϩτίϧελοΫΛ ܦ༝͠ͳ͍ωοτϫʔΫIO • ϓϩτίϧॲཧΛ͢ΔඞཁSocket APIͰ͋Δඞཁ ແ͍ͳΒɺωοτϫʔΫIOͬͱ͘ग़དྷΔ • ಛఆ༻్͚ • ϓϩτίϧॲཧΛඞཁͱ͠ͳ͍ΞϓϦέʔγϣϯ
ˠsnortɺOpenvSwitchͳͲ • ϓϩτίϧॲཧΛࣗલͰߦͳͬͯͰੑೳΛ্͛ ͍ͨΞϓϦέʔγϣϯ -
جຊతͳΈ • ઐ༻NICυϥΠόͱઐ༻ ϥΠϒϥϦΛ༻͍ͯɺ NICͷड৴όοϑΝΛ MMAP • ύέοτΛϙʔϦϯά • ΞϓϦݻ༗ͷύέοτ
ʹର͢ΔॲཧΛ࣮ߦ NIC RX1 RX2 RX3 Kernel Driver App RX1 RX2 RX3 MMAP 1BD LFUT Polling Do some work -
Intel DPDK • ׂΓࠐΈΛΊͯϙʔϦϯάΛ༻͠Φʔόϔουݮ • ड৴όοϑΝʹHugePageΛ͏ࣄʹΑΓTLB missΛݮ • 64 byte
packetͷL3ϑΥϫʔσΟϯάੑೳʢIntelࢿྉΑΓʣ • Linux network stackɿXeon E5645 x 2 → 12.2Mpps • DPDKɿXeon E5645 x 1 → 35.2Mpps • DPDK : Next generation Intel Processor x 1 → 80Mpps • OpenvSwitchରԠ • ରԠNICɿIntel -
ྨࣅͷ࣮ • PF_RING DNA ntopͷ࣮ɺLinux͚ libpcapαϙʔτ ରԠNICɿIntel • Netmap FreeBSD͚ͷ࣮ɺҰԠLinux൛͋Γ
libpcap, OpenvSwitchαϙʔτ ରԠNICɿIntel, Realtek... -
·ͱΊ • ߴͳωοτϫʔΫIOΛࡹͨ͘Ίʹ༷ʑͳվળ͕ ߦΘΕ͍ͯΔࣄΛհ • ϋʔυΣΞɾιϑτΣΞͷ྆໘Ͱ࣮ͷݟ ͕͠ཁٻ͞Ε͓ͯΓɺͦͷൣғωοτϫʔΫʹ ؔͳ͍Α͏ͳॴʹ·ͰٴͿ • औΓ͑ͣ໌͔Βग़དྷΔ͜ͱɿ
·ͣαʔόʹऔΓ͚ΔNICΛ ʮϚϧνΩϡʔNICʯʮRSSରԠʯʹ͠Α͏