[ovs-dev] [megaflow v4 1/2] datapath: Mega flow implementation

Jesse Gross jesse at nicira.com
Fri Jun 14 14:38:51 UTC 2013


On Thu, Jun 13, 2013 at 7:32 PM, Andy Zhou <azhou at nicira.com> wrote:
> Thanks for the review.  A few comments inline:
>
>> > +static void flow_key_mask(struct sw_flow_key *dst,
>> > +                         const struct sw_flow_key *src,
>> > +                         const struct sw_flow_mask *mfm)
>> > +{
>> > +       u8 *m = (u8 *)&mfm->key + mfm->range.start;
>> > +       u8 *s = (u8 *)src + mfm->range.start;
>> > +       u8 *d = (u8 *)dst + mfm->range.start;
>> > +       int i;
>> > +
>> > +       memset(dst, 0, sizeof(*dst));
>> > +       for (i = 0; i < ovs_sw_flow_mask_size_roundup(mfm); i++) {
>> > +               *d = *s & *m;
>> > +               d++, s++, m++;
>> > +       }
>> > +}
>>
>> What if we just did an in-place masking? This would avoid the need to
>> assume the hash algorithm's alignment requirements or do any roundup
>> at all.
>
>
> What do you mean by 'in-pace'?  It seems we will need to preserve the 'src'
> key value so that we can apply the next mask.

Hmm, I suppose this is true. Never mind then.

>> >  static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
>> > -                       int *key_lenp, int nh_len)
>> > +                       int nh_len)
>> [...]
>> >  out:
>> > -       *key_lenp = key_len;
>> >         return error;
>>
>> We can probably just remove the 'out' label altogether now.
>
> It does not seem to improve readability of removing this out.   Removing
> 'out' from ovs_flow_extract makes sense.

What's the difference here?

>> >  {
>> > +       if (!fp)
>> > +               return false;
>>
>> Does it make more logical sense for a NULL field to be considered
>> zero? I'm not sure that we can ever really hit this case anyways.
>
>
> When mask is not provided, we treat it as a wildcard fields, same as a all
> zero mask.

Doesn't returning false here signify that this is not a zero mask?

>> > +       for (i = 0; i < size; i++)
>> > +               if (*(fp + i))
>> > +                       return false;
>>
>> The nicest way of doing this to just OR everything together and check
>> at the end.
>
> This can be done for sure, but it may be less efficient. The same function
> in the user space OVS code also returns as soon as a non-zero value is
> detected.

Branching is usually very inefficient in cases where it is hard to predict.

>> > +               mfm->ref_count--;
>> > +
>> > +               if (!mfm->ref_count) {
>> > +                       list_del_rcu(&mfm->list);
>> > +                       call_rcu(&mfm->rcu, rcu_free_sw_flow_mask_cb);
>> > +               }
>> > +       }
>> > +}
>>
>> I'm not sure that it's actually necessary to use an RCU callback to
>> track the lifetime of masks - you could unlink them from the list when
>> the flow is deleted rather than from its RCU callback. Beyond
>> potentially simplifying things, it fixes a bug - we manipulate the
>> list and refcount from the flow RCU callback assuming that OVS lock is
>> held but it isn't at that point (incidentally, lockdep should have
>> flagged this so it might be worth running).
>
> Not sure if I understand this completely.  list_del_rcu is called on flow
> deletion,  The RCU callback is only for freeing memory, which should be safe
> without holding the OVS lock. Let's discuss further when we meet.

ovs_sw_flow_mask_del_ref() is called from the flow RCU callback. It
then manipulates the list without holding a lock.



More information about the dev mailing list