[Click] Race condition behavior with single thread Click Linux module

Eddie Kohler kohler at cs.ucla.edu
Tue Sep 13 02:16:31 EDT 2005


Hi Thomas,

You have exactly hit on the Click situation: a handler can execute in parallel 
with packet forwarding.  This is because handlers are called from the context 
of *the process that wrote the handler*, not the Click thread.

You may need to implement your own thread safety here.  Alternatively, you can 
try some experimental code in the current anonymous CVS.  If you set a handler 
flag to contain Handler::EXCLUSIVE, Click will ensure that that handler is 
called exclusively of any tasks.  This is experimental; let us know if it 
works for you.

Eddie



Paine, Thomas Asa wrote:
> 	I was under the assumption that click running in kernel time, by
> default, ran under a single thread.  We have run into an issue when we
> have a read/write handler on an element clearing a hashmap that is a
> member of that element.  If the map is cleared through a function called
> from the static handler (hashmap.clear()), we kernel panic (the map is
> updated with every packet passing through the element and at high packet
> rates).  
> 	If the handler calls a helper function that uses a timer within
> the element (timer.schedule_now()), this does not happen.  This suggests
> to me there is a race condition on the element's state and that there is
> actually more than one thread running.  Am I correct here, and if so
> should I assume locks are needed for thread safety with regards to
> proc's view into an element and its static handlers?
> 
> 
> In write_handler() below I have commented what causes the panic and what
> does not.
> 
> 
> 
> int FilterTables::initialize(ErrorHandler *errh){
>   timer.initialize(this);
>   timer.schedule_now();
> }
> 
> Packet* FilterTables::simple_action(Packet *p){ .
> .
>   _byteMap->insert(ip, _byteMap->find(ip)+len); .
> .
> }
> 
> void FilterTables::add_handlers(){
> .
> .
>   // Write Handlers
>   add_write_handler("reset", write_handler, (void *)H_RESET); .
> .
> }
> 
> 
> int FilterTables::write_handler(const String &in_str, Element *e, void
> *thunk, ErrorHandler *errh){
>   FilterTables *c = (FilterTables *)e;
> .
> .
>   switch ((intptr_t)thunk) {
>    case H_RESET:
>     // this will cause a panic, but not always the first time called
> (which again acts like a race condition)
>     c->reset();
>     // but this will not cause a panic and clears the map
>     timer.schedule_now();	
>     return 0;
> .
> .
> }
> 
> void FilterTables::reset(){
>   _byteMap->clear();
> }
> 
> 
> void FilterTables::run_timer(){
>   reset();
> }
> 
> 
> 
> Thanks,
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
>    Thomas Paine (paineta at uwec.edu) 
>    University of Wisconsin - Eau Claire 
>    garbage foo(garbage g){return(g);}
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> 
> _______________________________________________
> click mailing list
> click at amsterdam.lcs.mit.edu
> https://amsterdam.lcs.mit.edu/mailman/listinfo/click


More information about the click mailing list