[Click] Queues and notifications

Eddie Kohler kohler at cs.ucla.edu
Thu Jan 25 21:02:37 EST 2007


I did go ahead and fix this a different way, which will be a little less 
error prone for people programming elements like ToDevice.

Now in a situation like this:

       ... -> q::Queue -> d::DelayShaper(10s) -> x::ToDevice

the Queue will activate d's signal before waking x.  Thus:

       ... -> q::Queue -> d::DelayShaper(10s) -> x::ToDevice;
              INACTIVE         INACTIVE          UNSCHEDULED
                |  |             ^  ^                |   ^
                |  +--activates--+  +-----signal-----+   |
                |                                        |
                +--------------wakes up------------------+

Thus, when x wakes up, it sees that d's signal is active.

This will also have some benefits in situations like this:

   ... -> q::Queue -> d::DelayShaper(10s) -> rr::RoundRobinSched -> ...

Previously, rr would have had to poll d for 10 seconds per packet 
whenever there were packets in q.

Let me know if you see any problems.

Eddie



Eddie Kohler wrote:
> Hi guys,
> 
> Thanks for continuing to report this problem.  I did manage to reproduce 
> it and, hopefully, fix it.  But I wonder whether we could fix it in a 
> better way.
> 
> Mike, RawSocket did use notifiers.  This is all about notifiers.
> 
> Here's the deal.  Consider this configuration containing DelayShaper.
> 
>         ... -> q::Queue -> d::DelayShaper(10s) -> x::ToDevice;
> 
> Say that "q" has a packet in it.  Then q's notifier is active.  Should 
> "x" poll to get that packet?  NO!  Because it will poll for 10 solid 
> seconds before "d" will release the first packet!
> 
> Instead, Click introduces another notifier, in the DelayShaper d.  This 
> notifier turns on **only when d is ready to release a packet**.  In our 
> config above, then, x has d's notifier, not q's notifier.
> 
> Initially we have this status
> 
>         ... -> q::Queue -> d::DelayShaper(10s) -> x::ToDevice;
>                INACTIVE         INACTIVE          UNSCHEDULED
> 
> What happens when q gets a packet??  We want q to wake up x; since d is 
> a shaper, it should be passive, and x is the eventual packet consumer. 
> But x points at d's notifier!!  No problem; the 
> upstream_empty_notifier() process actually searches the graph TWICE, 
> once to develop a signal and once for registering wakeups.  That creates 
> this situation:
> 
>         ... -> q::Queue -> d::DelayShaper(10s) -> x::ToDevice;
>                INACTIVE         INACTIVE          UNSCHEDULED
>                    |               ^                  |   ^
>                    |               +-------signal-----+   |
>                    +-------------wakes up-----------------+
> 
> q will wake up x, which will then poll d.  Right?
> 
> Except that at the time x wakes up, **d's signal is still inactive.**
> 
> Most Click elements, including Discard, handled this case correctly. 
> When the task was rescheduled, they would pull upstream *before* 
> checking the signal.  But some Click elements did NOT handle this case 
> correctly.  They checked the signal *before* pulling upstream, which 
> meant (since d's signal is inactive here) that they never worked with 
> DelayShaper.  The elements: LinkUnqueue, RawSocket, Socket, and 
> userlevel ToDevice.
> 
> A related problem afflicted schedulers; a scheduler element, such as 
> RoundRobinSched, that had DelayUnqueues upstream would NEVER work 
> correctly since it looked at the wrong notifier.
> 
> I've fixed this in one way, namely by changing code like RawSocket to 
> pull before checking notifiers.  But now I think it would be better for 
> q to update d's signal when it wakes up x.  Not completely sure how to 
> implement this.... But Mike, Geoffrey, others using CVS, could you 
> update and see if you are still having scheduling problems?
> 
> Eddie
> 
> 
> 
> 
> 
> 
> 
> Mike Wilson wrote:
>> I've got a large, complex click config where I read from UDP sockets and 
>> write to a raw socket, routing packets from UDP tunnels.  Unfortunately, I 
>> can't seem to get notifications working in the Queues.
>>
>> I've stripped the config down to a fairly simple case that replicates the 
>> problem, at least on my system.  If I use Queue or NotifierQueue 
>> components for the queues, I either get nothing out the interface, or I 
>> get 1-2 packets and then nothing.  If I use a SimpleQueue, everything 
>> works just fine.
>>
>> My limited understanding is that the SimpleQueue doesn't do notifiers, so 
>> the pull components downstream must use polling.  In other words, it's a 
>> massive CPU hog - I get 99% utilization to click with a SimpleQueue.  With 
>> Queue, I don't even see click in my top(1) list.
>>
>> Am I mis-using the queue components somehow, or is this a bug?  Do 
>> RawSockets use notifiers?
>>
>> -Mike Wilson
>>
>> ---replication example---
>>
>> // Warning, this config will send bogus UDP packets to 172.16.46.20.
>> // Unfortunately, the problem doesn't manifest with a Discard at the end.
>>
>> AddressInfo(myip  128.252.160.209,
>>              NetRtr 172.16.46.12,
>>              HostRtr 172.16.46.20,
>>              NetRoute 172.16.46.0/24);
>>
>> PortInfo(NetTun 0xA121,
>>           HostTun 0xA122);
>>
>> out :: RawSocket("UDP");
>> rt :: RangeIPLookup(NetRoute  0, HostRtr 1);
>> sched :: DRRSched();
>>
>> TimedSource -> UDPIPEncap(HostRtr, 5005, HostRtr, 5005) -> 
>> IPPrint("Injecting Packet") -> check :: CheckIPHeader;
>> Idle -> rt;
>>
>> check[1] -> Print("Injected Bad packet") -> Discard;
>> check[0] -> IPPrint("Injected Valid Packet") -> GetIPAddress(16) -> rt;
>>
>> rt[0] -> UDPIPEncap(myip, NetTun, NetRtr, NetTun) -> IPPrint("Net Route") 
>> -> SimpleQueue -> [0]sched;
>> rt[1] -> UDPIPEncap(myip, HostTun, HostRtr, HostTun) -> IPPrint("Host 
>> Route") -> SimpleQueue -> [1]sched;
>>
>> sched -> IPPrint("Sending") -> out;
>>
>> _______________________________________________
>> click mailing list
>> click at amsterdam.lcs.mit.edu
>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
> _______________________________________________
> click mailing list
> click at amsterdam.lcs.mit.edu
> https://amsterdam.lcs.mit.edu/mailman/listinfo/click


More information about the click mailing list