On Fri, Apr 3, 2015 at 4:21 PM, Joe Stringer <joestrin...@nicira.com> wrote:

> Missed this the first time around for some reason. Minor comments inline.
>
> On 1 April 2015 at 22:14, Neil McKee <neil.mc...@inmon.com> wrote:
> > 1)  We can use the concurrent hash-map of flows that the revalidator
> > threads are sharing.  The upcall knows the 128-bit ufid for the flow,  so
> > we can get directly to the compiled actions like this:
> >
> > struct udpif_key *ukey = ukey_lookup(updif, upcall->ufid);
> > if(ukey) {
> >     struct nladdr *actions = ofpbuf_data(ukey->actions);
> >     ....
> >  }
> >
> > This seems to work most of the time,  but the way the revalidator threads
> > are spinning and flushing seems to make ukey_lookup() fail sometimes and
> > return NULL.  Is there a different way to query that would avoid this
> > problem?   If this method was reliable we could probably eliminate all
> the
> > code that builds and stores the sFlow userdata-cookie,  and we would
> have a
> > mechanism that would work not just for tunnels,  but for MPLS and other
> > actions too.
>
> You could turn up the 'dpif' debug level and ensure that you are
> actually seeing the UFIDs you expect (and log an error with the UFID
> when lookup fails).
>


When I get a match it is the right flow.  It's just that the lookup fails
about 5% of the time.  Is that just because of the way the revalidator
threads work?   What sort of hit-rate would you expect?  Should I get all
the busier flows,  and miss when the flow has been idle a few seconds?

Also,  I'm not quite sure if I am looking it up with the right lock / rcu
protections.   Can I really just call ukey_lookup(updif, upcall->ufid)
there without taking any other lock first?  And when I get a ukey pointer
back from the lookup, presumably I have to then take the lock on
ukey->mutex before I look at the actions.   Once I have that lock then I
can see that everything will be stable,  but it seems like there might be a
race:  what if the ukey is freed under my feed before I get the ukey->mutex
lock?

struct udpif_key *ukey = ukey_lookup(updif, upcall->ufid);
if(ukey) {
    /* race here? */
    ovs_mutex_lock(ukey->mutex);
    struct nladdr *actions = ofpbuf_data(ukey->actions);
    ....
    ovs_mutex_unlock(ukey->mutex);
}

Do I need to indicate that this is an RCU critical region somehow?


>
> I'm not sure that you can guarantee the UFID is 'correct' (ie, same as
> the installed flow) for the action upcall case currently. The UFID
> doesn't originate in the kernel, so for all upcalls the dpif generates
> it based on the flow key and passes it up to ofproto-dpif. If the flow
> mangles the packet before performing sample(userspace()), then won't
> the flow key be different from the original flow?
>

The sFlow sample action is always the first action.  Does that increase
your confidence?

I don't really mind if I get the actions straight from the kernel datapath
or looked up some other way in userspace.  It just needs to be fairly
reliable.  From what I can tell so far it works well enough (kind of) to do
the lookup in user-space.   Well enough to proceed with the sFlow tunnel
export,  anyway.   Perhaps later we'll hit on a better way to do the
lookup,  or modify the kernel to pass up the actions,  but from there on
the treatment will be the same.

Neil
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to