Open piotrjurkiewicz opened 6 years ago
Following the full-push idea, you would have to implement a push BandwidthRatedUnqueue. Maybe having the internals similar to a Pipeliner. However pull should still work.
All of those problems probably happen because of a leak. For the "no more netmap buffers", using NetmapInfo(EXTRA_BUFFER 65536) will confirm it. If they all disappear then they are lost somewhere. Could you look at the memory usage of your Click processes? Does it empty the RAM?
Also, if you use only the Queue but not rate limiters, does it work?
Also, if you use only the Queue but not rate limiters, does it work?
Segfaults also happen without rate limiters (i.e. when using Unqueue
after Queue
).
I also noticed that usage of Pipeliner
also results in segfaults. Due to direct traversal being on by default, in single thread scenarios it wasn't really storing packets. With Pipeliner(DIRECT_TRAVERSAL false)
segfaults happen, just like with Queue
. So it seems than any kind of packet storage results in segfaults in non-serially connected networks.
As for multihreaded scenarios and NetmapInfo(EXTRA_BUFFER 65536)
, sometimes it does help. But I still get:
[ 1008.189955] 314.688741 [1715] nm_rxsync_prologue eth1_fp RX0: fail 'cur < head || cur > kring->nr_hwtail' h 955 c 944 t 955 rh 955 rc 944 rt 955 hc 944 ht 958
[ 1008.192727] 314.691516 [1758] netmap_ring_reinit called for eth1_fp RX0
[ 1008.231922] 314.730710 [1715] nm_rxsync_prologue eth1_fp RX0: fail 'cur < head || cur > kring->nr_hwtail' h 767 c 753 t 767 rh 767 rc 753 rt 767 hc 753 ht 769
[ 1008.234532] 314.733323 [1758] netmap_ring_reinit called for eth1_fp RX0
[ 1008.343992] 314.842785 [1715] nm_rxsync_prologue eth1_fp RX0: fail 'cur < head || cur > kring->nr_hwtail' h 305 c 293 t 305 rh 305 rc 293 rt 305 hc 293 ht 308
I'm not sure who's using netmap anymore so I'm sadly applying wontfix to this...
I emulate a virtual network by connecting several Click processes with netmap native (patched) veth pairs and
From/ToNetmapDevice
.Now I want to rate limit
ToNetmapDevice
interfaces.My first attempt was to use
BandwidthRatedSplitter
in order to maintain full push path. However, TCP rate control algorithms go crazy with that. When I limit an interface to 1 Gbps, rate of a TCP flow varies between 0 and 1.5 Gbps and iperf reports average 200 Mbps.So I decided to use
Queue -> BandwidthRatedUnqueue
. This introduced a problem of empty runs and failed pulls because Click was repeatedly scheduling run_task. UsingQuickNoteQueue
insteadQueue
reduced this problem to an acceptable level. But what is more important, TCP rate was smooth and equal to limit, the same as I would limit interface bandwidth withtc
command.This was working fine as long as all Click processes were connected serially. When I emulated any non-linear network, I started to observe segfaults. They happen on packet allocation or freeing. Here are some examples:
Most of them happen in
KernelTun
, but they are not specific to this element. When I replace it withFrom/ToDevice
, the same happens inside it. These elements are the ones which allocate/deallocate packets mostly (sinceFrom/ToNetmapDevice
only forward them). I use these elements for connecting with routing daemons.With
Pipeliner
insteadQueue -> BandwidthRatedUnqueue
segfaults do not happen, but of course I can not rate limit it.All the above applies to single thread runs (
click -j 1
).With multiple threads, these same segfaults happen. In addition, Click crashes even in linear network after forwarding some number of packets with messages "No more netmap buffers" and "netmap_ring_reinit". This happen also with
Pipeliner
. So the only configurations working with multiple threads are full push paths withoutQueue
andPipeliner
.So there are at least two problems:
Queue
is used and processes are connected non-serially (happen both with single and multiple threads)Queue
orPipeliner
is used, no matter how routers are connected (happens only with multiple threads)Full push paths works fine, both with single and multi threads and any network topology.
So are these bugs? Or
Queue
elements are meant not to be used in netmap pool mode? If so, how rate limiting can be achieved? Should it be implemented inPipeliner
? But it still would only work with single thread.