Hi all.
Eddie, I already mailed this patch to you. For the sake of completeness, I also
post
this to the list, sorry for the duplication.
There seems to be a problem with the Click timers, which leads to 100% CPU
utilization. It can be reproduced as follows (tested on three x86 machines):
(1) Compile Click with the attached timerdebug element included. I'm not using
any
special configure flags, just --enable-local and --disable-linuxmodule.
(2) Start Click with timerdebug.click (also attached).
(3) Start netcat (i.e. 'nc -u 10.0.0.2 5000'), send some data and monitor CPU
utilization (I used 'top'). For me, 10 to 20 UDP packets were always enough
to
trigger this problem.
I'm not sure whether the problem lies in my timerdebug element, but what seems
to fix it, is the attached patch. The incident that triggers the problem begins
in master.cc, at the end of timer_reheapify_from:
_timer_expiry = Timestamp();
This sets _timer_expiry to zero. Later, in
master.hh::next_timer_expiry_adjusted(),
if _timer_stride < 8, the value of _timer_expiry is taken, Timer::adjustment()
is subtracted from it and returned, which then has the value:
e.sec = -1, e.subsec = 999500
Which leads to unintended behavior after the calls to
next_timer_expiry_adjusted() in master.cc, see the if-clauses there. A
timeout/wait value of zero is given to poll/select/kevent, where no timeout
should be used instead.
Nadi
diff --git a/include/click/master.hh b/include/click/master.hh
index 2dcedcf..64e629c 100644
--- a/include/click/master.hh
+++ b/include/click/master.hh
@@ -255,6 +255,8 @@ Master::next_timer_expiry_adjusted() const
if (_timer_stride >= 8)
return _timer_expiry;
Timestamp e = _timer_expiry;
+ if (e.sec() == 0)
+ return e;
if (_timer_stride >= 4)
e -= Timer::adjustment();
else
#include <click/config.h>
#include "timerdebug.hh"
CLICK_DECLS
int Timerdebug::initialize (ErrorHandler*)
{
timer.initialize(this);
return 0;
}
void Timerdebug::push (int, Packet* p)
{
if (!timer.scheduled()) {
click_chatter("starting timer");
timer.schedule_after_msec(100);
}
p->kill();
}
void Timerdebug::run_timer (Timer*)
{
click_chatter("timer callback");
}
CLICK_ENDDECLS
EXPORT_ELEMENT(Timerdebug)
tun0 :: KernelTun(10.0.0.1/24)
-> Timerdebug
#ifndef CLICK_TIMERDEBUG_HH
#define CLICK_TIMERDEBUG_HH
#include <click/element.hh>
#include <click/timer.hh>
CLICK_DECLS
class Timerdebug : public Element
{
public:
Timerdebug (void)
: Element(), timer(this)
{};
const char* class_name (void) const { return "Timerdebug"; }
const char* port_count (void) const { return PORTS_1_0; }
const char* processing (void) const { return PUSH; }
int configure (Vector<String> &, ErrorHandler*) { return 0; };
int initialize (ErrorHandler* errh);
void push (int, Packet* p);
Timer timer;
void run_timer (Timer* timer);
};
CLICK_ENDDECLS
#endif
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click