[ovs-dev] [PATCH] ovn.at: A "peer" is only for interconnected routers.
Ben Pfaff
blp at ovn.org
Mon Jul 18 20:11:08 UTC 2016
On Mon, Jul 18, 2016 at 11:34:54AM -0700, Guru Shetty wrote:
> On 18 July 2016 at 10:35, Ben Pfaff <blp at ovn.org> wrote:
>
> > On Mon, Jul 18, 2016 at 12:00:30AM -0700, Gurucharan Shetty wrote:
> > > We should not use "peer" while connecting a router to a switch.
> > > (Doing so, will cause ovn-northd to constantly create and destroy
> > > port_binding records which causes CPU utilization of ovn-controller to
> > > spike up.)
> > >
> > > Fixes: 31114af758c7e6 ("ovn-nbctl: Update logical router port commands.")
> > > Signed-off-by: Gurucharan Shetty <guru at ovn.org>
> >
> > I updated the commit message to correctly say:
> We should not use "peer" while connecting a router to a switch.
> (Doing so, will cause ovn-northd to constantly create and destroy
> logical_flow records which causes CPU utilization of ovn-controller to
> spike up.)
>
>
> > This seems like a bug in ovn-northd. Did you investigate why it
> > happens?
> >
> I think I know ( I haven't put a debugger to confirm). We create a logical
> flow incorrectly and add it via ovn_lflow_add() with a switch's datapath
> and a router's pipeline stage (S_ROUTER_IN_ARP_RESOLVE) here (This is when
> we incorrectly set router's peer as a switch):
> https://github.com/openvswitch/ovs/blob/master/ovn/northd/ovn-northd.c#L2614
Oh, good spotting, can we fix it something like this?
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 7ce509d..97e3271 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -715,7 +736,10 @@ join_logical_ports(struct northd_context *ctx,
sizeof *op->od->router_ports * (op->od->n_router_ports + 1));
op->od->router_ports[op->od->n_router_ports++] = op;
} else if (op->nbr && op->nbr->peer) {
- op->peer = ovn_port_find(ports, op->nbr->peer);
+ struct ovn_port *peer = ovn_port_find(ports, op->nbr->peer);
+ if (peer && peer->nbr) {
+ op->peer = peer;
+ }
}
}
}
> In build_lflows, we go through each record of SB database's logical flows
> and then do a ovn_lflow_find() which returns a negative if the data was
> wrongly inserted, so it goes ahead and deleted the record from SB database.
>
> In the next block, it will insert it back into the SB database. I will send
> one additional fix. But, I think we should also assert in ovn_lflow_add if
> we add a datapath with a different datapath's pipeline - not sure what is a
> nice way to do that.
Here's an idea (it compiles but I didn't test it):
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 7ce509d..905f6a7 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -175,6 +175,20 @@ ovn_stage_to_str(enum ovn_stage stage)
default: return "<unknown>";
}
}
+
+/* Returns the type of the datapath to which a flow with the given 'stage' may
+ * be added. */
+static enum ovn_datapath_type
+ovn_stage_to_datapath_type(enum ovn_stage stage)
+{
+ switch (stage) {
+#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \
+ case S_##DP_TYPE##_##PIPELINE##_##STAGE: return DP_##DP_TYPE;
+ PIPELINE_STAGES
+#undef PIPELINE_STAGE
+ default: OVS_NOT_REACHED();
+ }
+}
static void
usage(void)
@@ -303,6 +317,13 @@ ovn_datapath_destroy(struct hmap *datapaths, struct ovn_datapath *od)
}
}
+/* Returns 'od''s datapath type. */
+static enum ovn_datapath_type
+ovn_datapath_get_type(const struct ovn_datapath *od)
+{
+ return od->nbs ? DP_SWITCH : DP_ROUTER;
+}
+
static struct ovn_datapath *
ovn_datapath_find(struct hmap *datapaths, const struct uuid *uuid)
{
@@ -985,6 +1006,8 @@ ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od,
enum ovn_stage stage, uint16_t priority,
const char *match, const char *actions)
{
+ ovs_assert(ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od));
+
struct ovn_lflow *lflow = xmalloc(sizeof *lflow);
ovn_lflow_init(lflow, od, stage, priority,
xstrdup(match), xstrdup(actions));
Thanks,
Ben.
More information about the dev
mailing list