From: Pete Heist <pete@heistp.net>
To: Dave Taht <dave.taht@gmail.com>
Cc: Make-Wifi-fast <make-wifi-fast@lists.bufferbloat.net>
Subject: Re: [Make-wifi-fast] emulating wifi better - coupling qdiscs in netem?
Date: Sun, 17 Jun 2018 00:53:03 +0200 [thread overview]
Message-ID: <150ABF21-FAFC-48E2-9E55-CAA609EAE449@heistp.net> (raw)
In-Reply-To: <CAA93jw4iDjdd0zgywZi8aSEWx4_QO-VpYtKojb4kn-Duy79Low@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7043 bytes --]
> On Jun 16, 2018, at 12:30 AM, Dave Taht <dave.taht@gmail.com> wrote:
>
> Eric just suggested using the iptables NFQUEUE ability to toss
> packets to userspace.
>
> https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/ <https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/>
> For wifi, at least, timings are not hugely critical, a few hundred
> usec is something userspace can handle reasonably accurately. I like
> very much being able to separate out mcast and treat that correctly in
> userspace, also. I did want to be below 10usec (wifi "bus"
> arbitration), which I am dubious about....
>
> Now as for an implementation language? C++ C? Go? Python? The
> condition of the wrapper library for go leaves a bit to be desired
> ( https://github.com/chifflier/nfqueue-go <https://github.com/chifflier/nfqueue-go> ) and given a choice I'd
> MUCH rather use a go than a C.
This sounds cool... So for fun, I compared ping and iperf3 with no-op nfqueue callbacks in both C and Go. As for the hardware setup, I used two lxc containers (effectively just veth) on an APU2.
For the Go program, I used test_nfqueue from the wrapper above (which yes, does need some work) and removed debugging / logging.
For the C program I used this:
https://github.com/irontec/netfilter-nfqueue-samples/blob/master/sample-helloworld.c
I removed any per-packet printf calls and compiled with "gcc sample-helloworld.c -o nfq -lnfnetlink -lnetfilter_queue”.
Ping results:
ping without nfqueue:
root@lsrv:~# iptables -F OUTPUT
root@lsrv:~# ping -c 500 -i 0.01 -q 10.182.122.11
500 packets transmitted, 500 received, 0% packet loss, time 7985ms
rtt min/avg/max/mdev = 0.056/0.058/0.185/0.011 ms
ping with no-op nfqueue callback in C:
root@lsrv:~# iptables -A OUTPUT -d 10.182.122.11/32 -j NFQUEUE --queue-num 0
root@lsrv:~/nfqueue# ping -c 500 -i 0.01 -q 10.182.122.11
500 packets transmitted, 500 received, 0% packet loss, time 7981ms
rtt min/avg/max/mdev = 0.117/0.123/0.384/0.020 ms
ping with no-op nfqueue callback in Go:
root@lsrv:~# iptables -A OUTPUT -d 10.182.122.11/32 -j NFQUEUE --queue-num 0
root@lsrv:~# ping -c 500 -i 0.01 -q 10.182.122.11
500 packets transmitted, 500 received, 0% packet loss, time 7982ms
rtt min/avg/max/mdev = 0.095/0.172/0.532/0.042 ms
The mean induced latency of 65us for C or 114us for Go might be within your parameters, except you mentioned 10us for WiFi bus arbitration, which does indeed look impossible with this setup, even in C.
Iperf3 results:
iperf3 without nfqueue:
root@lsrv:~# iptables -F OUTPUT
root@lsrv:~# iperf3 -t 5 -c 10.182.122.11
Connecting to host 10.182.122.11, port 5201
[ 4] local 10.182.122.1 port 55810 connected to 10.182.122.11 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 452 MBytes 3.79 Gbits/sec 0 178 KBytes
[ 4] 1.00-2.00 sec 454 MBytes 3.82 Gbits/sec 0 320 KBytes
[ 4] 2.00-3.00 sec 450 MBytes 3.77 Gbits/sec 0 320 KBytes
[ 4] 3.00-4.00 sec 451 MBytes 3.79 Gbits/sec 0 352 KBytes
[ 4] 4.00-5.00 sec 451 MBytes 3.79 Gbits/sec 0 352 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 2.21 GBytes 3.79 Gbits/sec 0 sender
[ 4] 0.00-5.00 sec 2.21 GBytes 3.79 Gbits/sec receiver
iperf Done.
iperf3 with no-op nfqueue callback in C:
root@lsrv:~# iptables -A OUTPUT -d 10.182.122.11/32 -j NFQUEUE --queue-num 0
root@lsrv:~/nfqueue# iperf3 -t 5 -c 10.182.122.11
Connecting to host 10.182.122.11, port 5201
[ 4] local 10.182.122.1 port 55868 connected to 10.182.122.11 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 17.4 MBytes 146 Mbits/sec 0 107 KBytes
[ 4] 1.00-2.00 sec 16.9 MBytes 142 Mbits/sec 0 107 KBytes
[ 4] 2.00-3.00 sec 17.0 MBytes 142 Mbits/sec 0 107 KBytes
[ 4] 3.00-4.00 sec 17.0 MBytes 142 Mbits/sec 0 107 KBytes
[ 4] 4.00-5.00 sec 17.0 MBytes 143 Mbits/sec 0 115 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 85.3 MBytes 143 Mbits/sec 0 sender
[ 4] 0.00-5.00 sec 84.7 MBytes 142 Mbits/sec receiver
iperf3 with no-op nfqueue callback in Go:
root@lsrv:~# iptables -A OUTPUT -d 10.182.122.11/32 -j NFQUEUE --queue-num 0
root@lsrv:~# iperf3 -t 5 -c 10.182.122.11
Connecting to host 10.182.122.11, port 5201
[ 4] local 10.182.122.1 port 55864 connected to 10.182.122.11 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 14.6 MBytes 122 Mbits/sec 0 96.2 KBytes
[ 4] 1.00-2.00 sec 14.1 MBytes 118 Mbits/sec 0 96.2 KBytes
[ 4] 2.00-3.00 sec 14.0 MBytes 118 Mbits/sec 0 102 KBytes
[ 4] 3.00-4.00 sec 14.0 MBytes 117 Mbits/sec 0 102 KBytes
[ 4] 4.00-5.00 sec 13.7 MBytes 115 Mbits/sec 0 107 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 70.5 MBytes 118 Mbits/sec 0 sender
[ 4] 0.00-5.00 sec 69.9 MBytes 117 Mbits/sec receiver
iperf Done.
So rats, throughput gets brutalized for both C and Go. For Go, a rate of 117 Mbit with a 1500 byte MTU is 9750 packets/sec, which is 103us / packet. Mean induced latency measured by ping is 114us, which is not far off 103us, so the rate slowdown looks to be mostly caused by the per-packet nfqueue calls. The core running test_nfqueue is pinned at 100% during the test. "nice -n -20" does nothing.
Presumably you’ll sometimes be releasing more than one packet at a time(?) so I guess whether or not this is workable depends on how many you release at once, what hardware you’re on and what rates you need to test at. But when you’re trying to test a qdisc, I guess you’d want to minimize the burden you add to the CPU, or else move it to a core the qdisc isn’t running on, or something, so the qdisc itself isn’t affected by the test rig.
> There is of course a hideous amount of complexity moved to the daemon,
I can only imagine.
> as a pure fifo ap queue forms aggregregates much differently
> than a fq_codeled one. But, yea! userspace....
This would be awesome if it works out! After that iperf3 test though, I think I may have smashed my dreams of writing a libnetfilter_queue userspace qdisc in Go, or C for that matter.
If this does somehow turn out to be good enough performance-wise, I think you’d have a lot more fun and spend a lot less time on it in Go than C, but that’s just an opinion... :)
[-- Attachment #2: Type: text/html, Size: 21499 bytes --]
next prev parent reply other threads:[~2018-06-16 22:53 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-30 17:28 Dave Taht
2018-05-30 18:32 ` Bob McMahon
2018-05-30 18:54 ` Dave Taht
2018-05-30 18:58 ` Jonathan Morton
2018-05-30 19:19 ` Bob McMahon
2018-05-30 23:26 ` Dave Taht
2018-05-30 22:57 ` dpreed
2018-06-15 22:30 ` Dave Taht
2018-06-16 22:53 ` Pete Heist [this message]
2018-06-17 11:19 ` Jesper Dangaard Brouer
2018-06-17 15:16 ` Pete Heist
2018-06-17 16:09 ` Dave Taht
2018-06-17 18:38 ` Pete Heist
2018-06-17 18:47 ` Jonathan Morton
2018-06-18 9:24 ` Pete Heist
2018-06-18 16:08 ` Eric Dumazet
2018-06-18 19:33 ` Pete Heist
2018-06-18 19:44 ` Dave Taht
2018-06-18 21:54 ` Pete Heist
2018-06-18 22:27 ` Eric Dumazet
2018-06-17 20:42 ` Dave Taht
2018-06-18 1:02 ` Eric Dumazet
2018-06-18 0:59 ` Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.bufferbloat.net/postorius/lists/make-wifi-fast.lists.bufferbloat.net/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=150ABF21-FAFC-48E2-9E55-CAA609EAE449@heistp.net \
--to=pete@heistp.net \
--cc=dave.taht@gmail.com \
--cc=make-wifi-fast@lists.bufferbloat.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox