Hi Ilya et al

I can do that, but it may take a few days to get to it. Thanks for the
detailed analysis, I'll try to get my head around that too and contribute
to a fix.

Tony

On Thu, Aug 12, 2021 at 10:51 AM Ilya Maximets <i.maxim...@ovn.org> wrote:

> Hi.
>
> It's been some time since the last email in this thread.  I spent more
> time debugging and analyzing the code and, I think, I got to the bottom
> of this.  First of all, I had a question why the set of actions in that
> particular unit test in OVN needs help for execution, so it hits the
> dpif_execute_with_help() path?  The answer is the action set that looks
> like this:
>
> actions:set(eth(dst=ff:ff:ff:ff:ff:ff)),set(arp(sip=172.16.1.1)),
>         clone(tnl_push(tnl_port(6081),...,out_port(1)),101)
>
> Here the 'set(arp())' action is always marked as SLOW_ACTION and leads
> to 'needs_help == true'.  Changes of arp fields is not supported by
> kernel.  We may argue that userspace datapath supports it and we should
> be able to execute these actions inside the datapath avoiding the
> slow path execution process, but there are other cases where slow path
> execution can be requested.  One of the most obvious is a direct request
> of OFPACT_DEBUG_SLOW.  So, it's hard to completely avoid slow path
> execution even for a userspace datapath.
>
> Anyway, dpif_execute_with_help() or, more precisely, the callback
> dpif_execute_helper_cb() seems to be the source of all issues.  The
> overall design of the actions execution seems to be flawed here.
> This function makes several opposite assumptions:
>
> 1. It assumes that dpif_execute() can't modify packets and that
>    there is no way to get result of the execution from the datapath.
>
> 2. It assumes that dpif_execute() can and will modify the packet.
>
> Assumption 1 leads to a workaround for 'meter' actions which are
> accumulated from several calls and pushed along with the first terminal
> action (output, userspace or ct).  This assumption is true for the
> kernel datapath, because the packet basically gets copied to the kernel.
>
> Assumption 2 at the same time allows to implement tunneling for the
> userpsace datapath.  dpif_execute_helper_cb() relies on the fact
> that dpif_execute(OVS_ACTION_ATTR_TUNNEL_PUSH) will modify the packet
> by pushing the tunnel header.
>
> So, this inconsistent behavior for different actions breaks the
> dpif abstraction and doesn't allow us to correctly implement the
> dpif_execute() interface consistently across different datapath
> interfaces.
>
> Even though I see what is going on here, I don't currently see a way
> to fix this architectural/design flaw.  Definitely packet reference
> counters will still help in correct tracking of dp_packets and we
> need that.  I know that Aaron started working on this, but it will
> take a while before we will have a working solution.  I'll try
> to think how to actually re-work the actions execution path so we
> will not have this kind of self-contradicting functions and APIs
> (these inconsistencies are really the main thing that complicates
> the code and doesn't allow to understand it without a deep dive).
> If someone has ideas on that front, I'd like to hear.
>
> Meanwhile, I still think that we need to get the "bandaid" workaround
> (clone + data copy) in, so we can fix the actual crash.  As far as
> I understand now, change like this should not have any unexpected
> side effect.
>
> Tony, do you want to sent the workaround patch?  Or else I can do that.
>
> Bets regards, Ilya Maximets.
>
> On 6/21/21 10:58 PM, Ilya Maximets wrote:
> > On 6/19/21 4:11 AM, Tony van der Peet wrote:
> >> Hi all
> >>
> >> I am in favour of a better fix, bandaids tend to come back and bite you
> in the end anyway. So, will be happy to help with this effort, though I am
> probably going to have to defer to the rest of you when it comes to
> actually knowing what to do in this area.
> >>
> >
> > It's great to have a full correct solution, but unfortunately, I don't
> > think that we can come up with something like a full and correct
> > reference counting in a short period of time.  But we still need to fix
> > a crash that is pretty easy to trigger.  I'm also nervous that OVN is
> > using meters more and more (e.g. control plane protection patch set)
> > and they might actually hit this issue at the high load.  Another point
> > is that we need a fix that we can backport to LTS, and I don't think that
> > reference counting would be a small change that we can easily backport
> > without worrying about breaking something else.
> >
> > All in all, I think that we need to come up with a "bandaid" solution
> > and work further on correct reference counting after that.
> >
> > And we also need to create a unit test that will mimic packet-out that
> > I encountered in OVN tests, so we can test this kind of behavior in OVS.
> >
> > For the reference, the packet-out generated by OVN controller had a few
> > set() actions and the resubmit() to a different table. And this
> > table had rules leading to packet output to a tunnel port, resulting
> > in a tunnel push + output datapath actions.
> >
> >> Cheers
> >> Tony
> >> ________________________________________
> >> From: Aaron Conole <acon...@redhat.com>
> >> Sent: Saturday, 19 June 2021 2:50 a.m.
> >> To: Ilya Maximets
> >> Cc: Ben Pfaff; Tony van der Peet; d...@openvswitch.org; Tony van der
> Peet
> >> Subject: Re: [ovs-dev] [PATCH] dpif-netdev: Fix crash when PACKET_OUT
> is metered
> >>
> >> Ilya Maximets <i.maxim...@ovn.org> writes:
> >>
> >>> On 6/17/21 11:59 PM, Ben Pfaff wrote:
> >>>> All these flags for stealing, allowing stealing, blah blah, are just
> >>>> ways to do some kind of dumb reference counting without actually have
> a
> >>>> reference count.  When it gets super complex like this, maybe
> >>>> introducing a reference count is the way to go.  It would be a bigger
> >>>> change, but perhaps more maintainable over time.
> >>>>
> >>>
> >>> Yes, I absolutely agree.  We just removed one of these hacky flags from
> >>> the struct dp_packet_batch and we need to get rid of the rest of them.
> >>
> >> +1 from me - it's a bigger scoped change, but over-all, I think it's a
> >> better one, and makes the most sense.
> >>
> >>> One thing that bothers me is that some parts of the code treats
> >>> 'should_steal=false' as "do not modify".  For example, I don't really
> >>> understand why these functions are carrying cutlen around and clones
> >>> the packet before truncating if 'should_steal=false'.
> >>>
> >>> Some action executors also have optimizations that allows to not clone
> >>> the packet before the fatal action if this action is the last one.
> >>>
> >>> So, in general, yes, we need to get rid of these flags and accurately
> >>> re-work all the packet paths.  And yes, this would be not a small
> >>> change.
> >>>
> >>> For now, I think, we need to find a less ugly as possible solution for
> >>> existing crash (maybe the one that I suggested), so we will be able to
> >>> backport it and continue working on correct reference counting.
> >>>
> >>> What do you think?  Tony?  Aaron?
> >>
> >> That makes sense to me, and I hope we will actually work on the
> >> ref-count stuff.  I had started taking a look a few weeks back, but the
> >> idea of 'steal' is pretty ingrained throughout the code, so getting a
> >> ref-count semantic correct is a big effort.  As an example, the
> >> odp-execute area expects that each sub-action will have its own copy to
> >> modify (and this is documented with the 'should_steal' semantics).
> >> Taking that out will be a big rework in that area.  I think it makes
> >> the most sense, and we probably could implement something like COW to
> >> cover those cases where we really need to modify a packet without
> >> propagating those changes back up.
> >>
> >>> Best regards, Ilya Maximets.
> >>
> >
>
>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to