<div dir="ltr">
<p dir="auto">After heavy testing and resolving a few issues under heavy load, <a href="https://github.com/thebracket/cpumap-pping">cpumap-pping</a> has tagged release <code class="gmail-notranslate">1.0.0 RC1</code>. It should be ready for the v1.3 release of LibreQoS.</p>
<h2 dir="auto">What does it do?</h2>
<p dir="auto"><code class="gmail-notranslate">cpumap-pping</code> merges two projects:</p>
<ul dir="auto"><li>
<p dir="auto"><a href="https://github.com/xdp-project/xdp-cpumap-tc">xdp-cpumap-tc</a> provides some of the heavy lifting behind LibreQoS. It maps IP addresses to Linux <code class="gmail-notranslate">tc</code> classifiers/qdiscs. I recently added IPv6 and IPv4 subnet (e.g. match on <a href="http://192.168.0.0/24">192.168.0.0/24</a>), which is included in <code class="gmail-notranslate">cpumap-pping</code>. By mapping directly to filters, the <code class="gmail-notranslate">cpumap</code>
 is able to shift traffic shaping processing to individual CPUs - 
bypassing the performance limits of the default Linux traffic shaper. 
Because BPF programs run in kernel space (in a sandbox), it is able to 
sustain very high performance.</p>
</li><li>
<p dir="auto"><a href="https://github.com/xdp-project/bpf-examples/tree/master/pping">xdp-pping</a> is an in-kernel BPF version of the excellent <a href="https://github.com/pollere/pping">Polere Pping</a> by Kathie Nichols. Previous versions of LibreQoS ran the original <code class="gmail-notranslate">pping</code>
 to gather TCP round-trip time data, providing accurate Quality of 
Experience (QoE) metric to help optimize your ISP and monitor the 
benefits of the Cake shaper. <code class="gmail-notranslate">pping</code> is a great tool, but tended to consume too much CPU time (on a single core) under heavy load. <code class="gmail-notranslate">xdp-pping</code> could sustain very high loads, and still provide accurate RTT information.</p>
</li></ul>
<p dir="auto">Combining the two to run separately was troublesome, and 
duplicated a lot of work: both programs would individually parse 
Ethernet headers (<code class="gmail-notranslate">cpumap</code> also parses VLAN headers, <code class="gmail-notranslate">pping</code> did not), TCP headers, extract addresses, etc. For LibreQoS, it just made sense to combine them.</p>
<p dir="auto"><code class="gmail-notranslate">cpumap-pping</code> is a drop-in replacement (fully compatible) for <code class="gmail-notranslate">xdp-cpumap-tc</code> in LibreQoS. Once in place, instead of running <code class="gmail-notranslate">pping</code> and reading the results, you periodically run <code class="gmail-notranslate">xdp_pping</code>
 and retrieve the current snapshot of performance data - ready 
classified to match the queues that LibreQoS is already setting up. The 
results are handed out in a convenient JSON format:</p>
<div class="gmail-highlight gmail-highlight-source-json gmail-notranslate gmail-position-relative gmail-overflow-auto" dir="auto"><pre>[
{<span class="gmail-pl-ent">"tc"</span>:<span class="gmail-pl-s"><span class="gmail-pl-pds">"</span>3:54<span class="gmail-pl-pds">"</span></span>, <span class="gmail-pl-ent">"avg"</span>: <span class="gmail-pl-c1">35.39</span>, <span class="gmail-pl-ent">"min"</span>: <span class="gmail-pl-c1">15.95</span>, <span class="gmail-pl-ent">"max"</span>: <span class="gmail-pl-c1">60.03</span>, <span class="gmail-pl-ent">"median"</span>: <span class="gmail-pl-c1">33.67</span>, <span class="gmail-pl-ent">"samples"</span>: <span class="gmail-pl-c1">58</span>},
]</pre></div>
<p dir="auto">Only a subset of TCP data is sampled. Rather than process 
every packet, the first 58 "ack" sequences are timed for each tc handle.
 This has two advantages:</p>
<ul dir="auto"><li>It greatly lowers system resource usage (once the sample buffer is full the sampler doesn't do <em>any</em> additional work).</li><li>It ensures fairness in sampling; otherwise, there's a tendency to 
over-sample busy queues and possibly miss relatively quiet ones.</li></ul>
<h2 dir="auto">Performance</h2>
<ul dir="auto"><li>Testing in Hyper-V (4 VMs, one shaper, one iperf server, two iperf 
clients) shows that individual flow throughput maxes out around 4.2 
gbit/s per-core, with full Cake shaping. Without the <code class="gmail-notranslate">pping</code> component, performance is around 4.21 gbit/s per-core. In other words, it's very fast.</li><li>Testing in the real-world shows that on an under-powered 10 CPU VM 
(in Proxmox, on an older server) never exceeds 40% CPU usage on a single
 core while shaping approximately 1.8 gbit/s of traffic. This is with 
approximately 1,200 IP address entries in the cpu map, and 600 queues.</li><li>Profiling shows that the BPF programs (one on XDP ingress, one on TC
 egress) consume a maximum of 4,000 nanoseconds in the current release. 
That's adding a ceiling of <code class="gmail-notranslate">0.004 ms</code> to customer ping times.</li></ul><div>Robert 
has been working hard on connecting this to the graphing system. You can see some great examples of progress in <a href="https://github.com/thebracket/cpumap-pping/issues/2">this - now closed - issue</a>. For example: <br></div><div><img src="cid:ii_la3xmtla0" alt="image.png" width="558" height="223"><br><br></div></div>