numan On Thu, Sep 25, 2025, 2:47 PM Ales Musil <amu...@redhat.com> wrote:
> > > On Thu, Sep 25, 2025 at 7:27 PM Mark Michelson <mmich...@redhat.com> > wrote: > >> On Thu, Sep 25, 2025 at 1:23 PM Mark Michelson <mmich...@redhat.com> >> wrote: >> > >> > On Thu, Sep 25, 2025 at 1:21 PM Mark Michelson <mmich...@redhat.com> >> wrote: >> > > >> > > On Thu, Sep 25, 2025 at 1:13 PM Mark Michelson <mmich...@redhat.com> >> wrote: >> > > > >> > > > I can see the reasoning behind the current code. If the port is >> > > > definitely not associated with a router at all, then don't bother >> > > > trying to look in lr_ports for it. It saves a lookup into lr_ports. >> > > > However, I wonder in practice how much computation this actually >> > > > saves. get_lport_type() is an if-else ladder that performs strcmp() >> > > > operations. ovn_port_find() does a hashed lookup of the port and a >> > > > strcmp() to verify that the hashed port is the one we want. If the >> > > > port does not exist in lr_ports at all, there is a decent chance >> that >> > > > HMAP_FOR_EACH_WITH_HASH () will calculate the hash, provide no >> > > > matches, and end the loop after zero iterations. >> > > > >> > > > Without having measured this at all (IMPORTANT!!), I would reason >> that >> > > > doing two ovn_port_find() operations in lr_ports and then ls_ports >> > > > might be cheaper than calling get_lport_type() and then calling >> > > > ovn_port_find() in ls_ports. And it certainly is cheaper than >> calling >> > > > get_lport_type(), and then calling ovn_port_find() two times. >> > > > >> > > > If we really need to measure this, then we can, but I currently am >> in >> > > > support of the change proposed by Ales. There is a chance this >> > > > actually improves performance compared to the current code, and it >> > > > eliminates a function whose name can be misleading. >> > > >> > > And one final note: If the goal is simply to tell if a port_binding is >> > > associated with a switch or router, then keep in mind that in 25.09+, >> > > the datapath_binding table has a "type" field on it. An alternate idea >> > > would be to redefine is_pb_router_type() in the following way: >> > > >> > > bool >> > > is_pb_router_type(const struct port_binding *pb) >> > > { >> > > if (!pb->datapath) { >> > > return false; >> > > } >> > > if (!strcmp(pb->datapath->type, "logical-router")) { >> > > return true; >> > > } >> > > return false; >> > > } >> > >> > And of course immediately after I sent this I realized this can be a >> one-liner: >> > >> > return pb->datapath && !stcmp(pb->datapath->type, "logical_router"); >> > >> >> Last message from me :) >> >> Instead of looking directly into pb->datapath->type, it is safer to do: >> >> return pb->datapath && !strcmp(datapath_get_nb_type(pb->datapath), >> "logical-router"); >> > > Thank you Mark, that is a better check indeed. > Looking at the schema the pb->datapath cannot be null: > > [SBREC_PORT_BINDING_COL_DATAPATH] = { > .name = "datapath", > .type = { > .key = { > .type = OVSDB_TYPE_UUID, > .uuid = { .refTableName = "Datapath_Binding", .refType = > OVSDB_REF_STRONG }, > }, > .value = OVSDB_BASE_VOID_INIT, > .n_min = 1, > .n_max = 1, > }, > .is_mutable = true, > .is_synthetic = false, > .parse = sbrec_port_binding_parse_datapath, > .unparse = sbrec_port_binding_unparse_datapath, > }, > > So I have removed the pb->datapath check from the suggestion in v2. > > >> >> > > >> > > Then you have a relatively cheap function that can take a port binding >> > > and determine for certain whether it is associated with a logical >> > > router. This would allow for us to always perform a single strcmp() >> > > and a single ovn_port_find() call. >> > > >> > > > >> > > > On Thu, Sep 25, 2025 at 10:48 AM Numan Siddique <num...@ovn.org> >> wrote: >> > > > > >> > > > > On Thu, Sep 25, 2025 at 8:21 AM Ales Musil via dev >> > > > > <ovs-dev@openvswitch.org> wrote: >> > > > > > >> > > > > > That function is misleading as the type isn't guaranteed to be >> > > > > > always LRP. The only place where this function was used knew >> about >> > > > > > this hidden logic and did a lookup the lookup twice anyway. >> Let's >> > > > > > skip this micro optimization whatsoever and do the lookup twice >> > > > > > when needed. >> > > > > > >> > > > > > Signed-off-by: Ales Musil <amu...@redhat.com> >> > > > > >> > > > > I agree with the function name not being very intuitive. When I >> added >> > > > > this function, I meant a port binding >> > > > > which is of type router. If you see, we have a logical switch >> port of >> > > > > type "router". This function doesn't >> > > > > say if the corresponding logical port of the "port_binding" in >> the NB >> > > > > DB is a _logical_router_port_ or not, but it indicates >> > > > > if it is a router port (which can belong to a logical switch or >> router). >> > > > > >> > > > > With this patch, whenever a port binding (irrespective of type) >> gets >> > > > > updated we will lookup the lr_map first and then ls_map >> > > > > and we are introducing an extra cost of look up. Which is not the >> > > > > case without this patch. For VIF port bindings we will only >> lookup in >> > > > > the ls_map. >> > > > > >> > > > > If we don't want to use this function, my suggestion would be for >> > > > > northd to write "datapath=router" or "datapath=switch" in the >> > > > > external_ids of port bindings. >> > > > > This way we can do a lookup in the proper map when handling port >> > > > > binding changes. >> > > > I personally think that the double lookup will not cost us any > performance whatsoever. To be on the safe side I have slightly > adjusted the suggestion from Mark. We should be able to tell > from the datapath right away if it's LSP or LRP. So we will never > do double lookup even for overlapping types (peer, remote etc.). > I'll send v2 with this change. > Sounds good to me. Thanks > >> > > > > >> > > > > Thanks >> > > > > Numan >> > > > > >> > > > > >> > > > > > --- >> > > > > > lib/ovn-util.c | 28 ---------------------------- >> > > > > > lib/ovn-util.h | 1 - >> > > > > > northd/northd.c | 24 +++++++++--------------- >> > > > > > 3 files changed, 9 insertions(+), 44 deletions(-) >> > > > > > >> > > > > > diff --git a/lib/ovn-util.c b/lib/ovn-util.c >> > > > > > index 6c7629e6d..7b77f838f 100644 >> > > > > > --- a/lib/ovn-util.c >> > > > > > +++ b/lib/ovn-util.c >> > > > > > @@ -1283,34 +1283,6 @@ get_lport_type_str(enum en_lport_type >> lport_type) >> > > > > > OVS_NOT_REACHED(); >> > > > > > } >> > > > > > >> > > > > > -bool >> > > > > > -is_pb_router_type(const struct sbrec_port_binding *pb) >> > > > > > -{ >> > > > > > - enum en_lport_type lport_type = get_lport_type(pb); >> > > > > > - >> > > > > > - switch (lport_type) { >> > > > > > - case LP_PATCH: >> > > > > > - case LP_CHASSISREDIRECT: >> > > > > > - case LP_L3GATEWAY: >> > > > > > - case LP_L2GATEWAY: >> > > > > > - case LP_REMOTE: >> > > > > > - return true; >> > > > > > - >> > > > > > - case LP_VIF: >> > > > > > - case LP_CONTAINER: >> > > > > > - case LP_MIRROR: >> > > > > > - case LP_VIRTUAL: >> > > > > > - case LP_LOCALNET: >> > > > > > - case LP_LOCALPORT: >> > > > > > - case LP_VTEP: >> > > > > > - case LP_EXTERNAL: >> > > > > > - case LP_UNKNOWN: >> > > > > > - return false; >> > > > > > - } >> > > > > > - >> > > > > > - return false; >> > > > > > -} >> > > > > > - >> > > > > > void >> > > > > > sorted_array_apply_diff(const struct sorted_array *a1, >> > > > > > const struct sorted_array *a2, >> > > > > > diff --git a/lib/ovn-util.h b/lib/ovn-util.h >> > > > > > index 67fc3882d..4c686aac9 100644 >> > > > > > --- a/lib/ovn-util.h >> > > > > > +++ b/lib/ovn-util.h >> > > > > > @@ -433,7 +433,6 @@ enum en_lport_type { >> > > > > > >> > > > > > enum en_lport_type get_lport_type(const struct >> sbrec_port_binding *); >> > > > > > char *get_lport_type_str(enum en_lport_type lport_type); >> > > > > > -bool is_pb_router_type(const struct sbrec_port_binding *); >> > > > > > >> > > > > > /* A wrapper that holds sorted arrays of strings. */ >> > > > > > struct sorted_array { >> > > > > > diff --git a/northd/northd.c b/northd/northd.c >> > > > > > index fe5199a86..e1d01df50 100644 >> > > > > > --- a/northd/northd.c >> > > > > > +++ b/northd/northd.c >> > > > > > @@ -4982,23 +4982,17 @@ northd_handle_sb_port_binding_changes( >> > > > > > const struct sbrec_port_binding *pb; >> > > > > > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, >> 5); >> > > > > > SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (pb, >> sbrec_port_binding_table) { >> > > > > > - bool is_router_port = is_pb_router_type(pb); >> > > > > > - struct ovn_port *op = NULL; >> > > > > > - >> > > > > > - if (is_router_port) { >> > > > > > - /* A router port binding 'pb' can belong to >> > > > > > - * - a logical switch port of type router or >> > > > > > - * - a logical router port. >> > > > > > - * >> > > > > > - * So, first search in lr_ports hmap. If not >> found, search in >> > > > > > - * ls_ports hmap. >> > > > > > - * */ >> > > > > > - op = ovn_port_find(lr_ports, pb->logical_port); >> > > > > > - } >> > > > > > - >> > > > > > + bool is_router_port = true; >> > > > > > + /* A router port binding 'pb' can belong to >> > > > > > + * - a logical switch port of type router or >> > > > > > + * - a logical router port. >> > > > > > + * >> > > > > > + * So, first search in lr_ports hmap. If not found, >> search in >> > > > > > + * ls_ports hmap. >> > > > > > + * */ >> > > > > > + struct ovn_port *op = ovn_port_find(lr_ports, >> pb->logical_port); >> > > > > > if (!op) { >> > > > > > op = ovn_port_find(ls_ports, pb->logical_port); >> > > > > > - >> > > > > > if (op) { >> > > > > > is_router_port = false; >> > > > > > } >> > > > > > -- >> > > > > > 2.51.0 >> > > > > > >> > > > > > _______________________________________________ >> > > > > > dev mailing list >> > > > > > d...@openvswitch.org >> > > > > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >> > > > > _______________________________________________ >> > > > > dev mailing list >> > > > > d...@openvswitch.org >> > > > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > Thanks, > Ales > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev