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 click@amsterdam.lcs.mit.edu https://amsterdam.lcs.mit.edu/mailman/listinfo/click