[ovs-dev] [PATCH v2 ovn 1/2] northd: refactor unreachable IPs lb flows

Lorenzo Bianconi lorenzo.bianconi at redhat.com
Thu Aug 26 12:25:35 UTC 2021


[...]
> > +
> > +    uint32_t hash = ovn_logical_flow_hash(
> > +            ovn_stage_get_table(S_SWITCH_IN_L2_LKUP),
> > +            ovn_stage_get_pipeline_name(S_SWITCH_IN_L2_LKUP), 90,
> > +            ds_cstr(match), action);
> > +
> > +    for (size_t i = 0; i < lb->n_nb_lr; i++) {
> > +        struct ovn_datapath *od = lb->nb_lr[i];
> 
> Let's establish here that od is a logical router. This will be the basis for
> my comments for the rest of this review.

right

> 
> > +        if (!od->is_gw_router && !od->n_l3dgw_ports) {
> > +            continue;
> > +        }
> > +
> > +        for (size_t j = 0; j < od->n_router_ports; j++) {
> 
> od->router_ports and od->n_router_ports are only used by logical switches.
> Each logical switch port of type "router" is included in this array. In
> other words, od->router_ports is a list of logical switch ports that are
> connected to logical routers. So I think this means that this for loop is a
> no-op.
> 
> I think the appropriate change is to use od->nbr->n_ports here...
> 
> > +            struct ovn_port *op = ovn_port_get_peer(ports,
> > +                                                    od->router_ports[j]);
> 
> ... and use od->nbr->ports[j] here.

you are right, I fixed the issue before and for some reason I reintroduced it
:(.
we should use instead:
- od->nbr->n_ports
- struct ovn_port *op = ovn_port_find(ports, od->nbr->ports[j]->name);

unfortunatelly doing so we will reintroduce a hash_string() that grubs the
adavantage we have "caching" hash and lflow_ref pointer :(. Below it is the
perf report I collected during testing development:

    10.00%  -001  ovn-northd  ovn-northd [.] hash_bytes
            |          
             --9.99%--hash_bytes
                       |          
                       |--6.07%--ovn_logical_flow_hash
                       |          |          
                       |           --6.02%--ovn_lflow_add_at
                       |                     |          
                       |                     |--2.93%--build_lrouter_nat_flows_for_lb
                       |                     |          build_lrouter_flows_for_lb
                       |                     |          build_lswitch_and_lrouter_flows
                       |                     |          build_lflows
                       |                     |          ovnnb_db_run
                       |                     |          ovn_db_run
                       |                     |          main
                       |                     |          0x7f58f1cc01e2
                       |                     |          0x495641000deecb3d
                       |                     |          
                       |                     |--1.55%--build_lb_rules
                       |                     |          build_lswitch_flows_for_lb
                       |                     |          build_lswitch_and_lrouter_flows
                       |                     |          build_lflows
                       |                     |          ovnnb_db_run
                       |                     |          ovn_db_run
                       |                     |          main
                       |                     |          0x7f58f1cc01e2
                       |                     |          0x495641000deecb3d
                       |                     |          
                       |                      --1.31%--build_lrouter_defrag_flows_for_lb
                       |                                build_lswitch_and_lrouter_flows
                       |                                build_lflows
                       |                                ovnnb_db_run
                       |                                ovn_db_run
                       |                                main
                       |                                0x7f58f1cc01e2
                       |                                0x495641000deecb3d
                       |          
                        --1.84%--ovn_port_find__
                                  |          
                                   --1.84%--ovn_port_find
                                             |          
                                              --1.44%--build_lflows_for_unreachable_vips
                                                        build_lrouter_flows_for_lb
                                                        build_lswitch_and_lrouter_flows
                                                        build_lflows
                                                        ovnnb_db_run
                                                        ovn_db_run
                                                        main
                                                        0x7f58f1cc01e2
                                                        0x495641000deecb3d

     4.31%  -001  ovn-northd  ovn-northd          [.] hmap_next_with_hash__
            |          
             --4.29%--hmap_next_with_hash__
                       |          
                        --4.29%--hmap_first_with_hash
                                  |          
                                  |--2.68%--ovn_port_find__
                                  |          |          
                                  |           --2.67%--ovn_port_find
                                  |                     |          
                                  |                      --2.59%--build_lflows_for_unreachable_vips
                                  |                                build_lrouter_flows_for_lb
                                  |                                build_lswitch_and_lrouter_flows
                                  |                                build_lflows
                                  |                                ovnnb_db_run
                                  |                                ovn_db_run
                                  |                                main
                                  |                                0x7f58f1cc01e2
                                  |                                0x495641000deecb3d
                                  |          
                                  |--0.84%--ovn_datapath_find
                                  |          |          
                                  |           --0.84%--ovn_datapath_from_sbrec
                                  |                     build_lflows
                                  |                     ovnnb_db_run
                                  |                     ovn_db_run
                                  |                     main
                                  |                     0x7f58f1cc01e2
                                  |                     0x495641000deecb3d
                                  |          
                                   --0.77%--ovn_lflow_find

     3.79%  -001  ovn-northd  ovn-northd          [.] hmapx_add
            |          
             --3.73%--hmapx_add
                       |          
                        --1.90%--0

     3.01%  -001  ovn-northd  libc-2.32.so        [.] 0x000000000015d42e
            |
            ---0x7f58f1df5432
               |          
               |--1.28%--ovn_port_find
               |          |          
               |           --1.26%--build_lflows_for_unreachable_vips
               |                     build_lrouter_flows_for_lb
               |                     build_lswitch_and_lrouter_flows
               |                     build_lflows
               |                     ovnnb_db_run
               |                     ovn_db_run
               |                     main
               |                     0x7f58f1cc01e2
               |                     0x495641000deecb3d
               |          
                --0.73%--build_lflows_for_unreachable_vips
                          build_lrouter_flows_for_lb
                          build_lswitch_and_lrouter_flows
                          build_lflows
                          ovnnb_db_run
                          ovn_db_run
                          main
                          0x7f58f1cc01e2
                          0x495641000deecb3d

Am I missing something?
Anyway I spotted a couple of other routine we can optimize :)

Regards,
Lorenzo

> 
> Also, ovn_port_get_peer() only works for logical switch ports (it should
> probably be renamed), so this will return NULL every time if a logical
> router port is passed in.
> 
> > +            if (!op) {
> > +                continue;
> > +            }
> > +
> > +            if (!od->is_gw_router  && !is_l3dgw_port(op)) {
> 
> You already checked od->is_gw_router outside this loop, so you can remove
> the redundant check here.
> 
> Also, this code is hurting my brain a bit. In the outer loop, "od" is a
> logical router. We then iterate over od's ports and set "op" to the *peer*
> of the current port. So "op" should presumably be a logical switch port. So
> testing is_l3dgw_port(op) should always return false, right?
> 
> > +                continue;
> > +            }
> > +
> > +            struct ovn_port *peer = op->peer;
> > +            if (!peer || !peer->nbsp || lsp_is_external(peer->nbsp)) {
> > +                continue;
> > +            }
> 
> Now we set peer to op->peer. Since we already know that op is the peer of
> the logical router port, then op->peer should just be the logical router
> port again. Checks for peer->nbsp and lsp_is_external(peer->nbsp) will
> always be false.
> 
> > +
> > +            if ((ipv4 && lrouter_port_ipv4_reachable(op, ipv4_addr)) ||
> > +                (!ipv4 && lrouter_port_ipv6_reachable(op, &lb_vip->vip))) {
> > +                continue;
> > +            }
> > +            ovn_lflow_add_at_with_hash(lflows, peer->od,
> > +                                       S_SWITCH_IN_L2_LKUP, 90,
> 
> And then finally here, since peer is a logical router port, adding the lflow
> to S_SWITCH_IN_L2_LKUP table doesn't work.
> 
> I think the issue here is that "op" shouldn't be set to the peer of the
> logical router port. Instead, I think it should be set directly to the
> logical router port. If you do this, then the rest of the logic in this loop
> should work correctly.
> 
> > +                                       ds_cstr(match), action,
> > +                                       NULL, NULL, &peer->nbsp->header_,
> > +                                       OVS_SOURCE_LOCATOR, hash);
> > +        }
> > +    }
> > +}
> > +
> >   static void
> >   build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
> > -                           struct shash *meter_groups,
> > +                           struct hmap *ports, struct shash *meter_groups,
> >                              struct ds *match, struct ds *action)
> >   {
> >       if (!lb->n_nb_lr) {
> > @@ -9453,6 +9516,8 @@ build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
> >       for (size_t i = 0; i < lb->n_vips; i++) {
> >           struct ovn_lb_vip *lb_vip = &lb->vips[i];
> > +        build_lflows_for_unreachable_vips(lb, lb_vip, lflows, ports, match);
> > +
> >           build_lrouter_nat_flows_for_lb(lb_vip, lb, &lb->vips_nb[i],
> >                                          lflows, match, action,
> >                                          meter_groups);
> > @@ -12778,7 +12843,7 @@ build_lflows_thread(void *arg)
> >                       build_lrouter_defrag_flows_for_lb(lb, lsi->lflows,
> >                                                         &lsi->match);
> >                       build_lrouter_flows_for_lb(lb, lsi->lflows,
> > -                                               lsi->meter_groups,
> > +                                               lsi->ports, lsi->meter_groups,
> >                                                  &lsi->match, &lsi->actions);
> >                       build_lswitch_flows_for_lb(lb, lsi->lflows,
> >                                                  lsi->meter_groups,
> > @@ -12947,8 +13012,9 @@ build_lswitch_and_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
> >                                                    &lsi.actions,
> >                                                    &lsi.match);
> >               build_lrouter_defrag_flows_for_lb(lb, lsi.lflows, &lsi.match);
> > -            build_lrouter_flows_for_lb(lb, lsi.lflows, lsi.meter_groups,
> > -                                       &lsi.match, &lsi.actions);
> > +            build_lrouter_flows_for_lb(lb, lsi.lflows, lsi.ports,
> > +                                       lsi.meter_groups, &lsi.match,
> > +                                       &lsi.actions);
> >               build_lswitch_flows_for_lb(lb, lsi.lflows, lsi.meter_groups,
> >                                          &lsi.match, &lsi.actions);
> >           }
> > 
> 


More information about the dev mailing list