[Xorp-hackers] Crash due to stale cached xrl sender pointer.

Bruce Simpson bms at incunabulum.net
Mon Nov 9 09:13:17 PST 2009


Bruce Simpson wrote:
> It would be good to know if changing the Xrl allocation in this way 
> helps the situation with the race you saw...
>   

A bit more on the 'static Xrl*' mechanism.

This is a lazy allocation mechanism, which amortizes the cost of 
instantiating class Xrl. The change I posted yesterday just moves the 
pointer to this allocation into the XrlFooClient itself, where we can 
manage its lifecycle; the semantics of its use don't change.

Some data points:
 * There is only one instance of cached 'class Xrl*' for each 
XrlFooClient method.
 * Each method's wrapper lazy-allocates it once per runtime, when the 
method wrapper is called.
    * Without my change, this lazy allocation is non-reentrant, and 
happens once per runtime.
    * With my change, it happens once per method call, for each 
XrlFooClient instance, which is reentrant (but still not thread-safe).
 * It sets up the Xrl::args() field. That's it. No additional 
amortization of up-front costs of sending an XRL.
 * If the consumer of XrlFooClient::send_foo(target, arg) changes its 
'target' argument, the resolved XrlSender is very likely to change, 
forcing a FinderDBEntry lookup in XrlRouter::send() anyway.
 * No upfront resolution is performed when the target changes.

In practice, this optimization probably doesn't offer much, but it's 
better than nothing. class Xrl is still an intermediate representation, 
and until the Xrl is actually sent on the wire, it doesn't get 'packed' 
into its on-wire representation.

There is a lost optimization opportunity here. XRL clients which use the 
C++ client stubs never need to tunnel XRLs through the Finder, so they 
can always use binary representation. However, there is nowhere to put 
it, until we actually hit the output buffers for the destination 
transport.  [1]

I haven't measured cycle-for-cycle yet the costs of sending an XRL. I 
probably will do this when profiling the Thrift run; I'm still in 
analysis, trying to come up with the least invasive change to avoid 
rewriting code I don't/won't need to.

Thread safety hasn't really been a consideration to date. I'm making 
notes, but I'm not going to substantially change the behaviour towards 
making existing code thread-safe.

cheers,
BMS

[1] We can probably leverage this opportunity using Thrift, as we can 
then render the binary representation upfront. We can also use a mixin 
with TTransport to do scatter/gather I/O with multiple TMemoryBuffers, 
so we only hit writev() or send() to keep syscall count minimal. XRL 
will currently try to do this, but it's tied to stream semantics.



More information about the Xorp-hackers mailing list