Reported-at: https://issues.redhat.com/browse/FDP-1522 Reported-at: https://issues.redhat.com/browse/FDP-1523
Signed-off-by: Mark Michelson <mmich...@redhat.com> --- northd/en-datapath-logical-router.c | 127 +++++++++++++++++++++++++-- northd/en-datapath-logical-router.h | 16 +++- northd/en-datapath-logical-switch.c | 128 ++++++++++++++++++++++++++-- northd/en-datapath-logical-switch.h | 14 +++ northd/inc-proc-northd.c | 8 +- tests/ovn-northd.at | 53 ++++++++++++ 6 files changed, 329 insertions(+), 17 deletions(-) diff --git a/northd/en-datapath-logical-router.c b/northd/en-datapath-logical-router.c index ec974ec53..1b23a5b7b 100644 --- a/northd/en-datapath-logical-router.c +++ b/northd/en-datapath-logical-router.c @@ -202,12 +202,30 @@ en_datapath_logical_router_cleanup(void *data) ovn_unsynced_datapath_map_destroy(map); } +struct ovn_synced_logical_router * +ovn_synced_logical_router_find(const struct ovn_synced_logical_router_map *map, + const struct uuid *nb_uuid) +{ + struct ovn_synced_logical_router *lr; + HMAP_FOR_EACH_WITH_HASH (lr, hmap_node, uuid_hash(nb_uuid), + &map->synced_routers) { + if (uuid_equals(&lr->nb->header_.uuid, nb_uuid)) { + return lr; + } + } + + return NULL; +} + static void synced_logical_router_map_init( struct ovn_synced_logical_router_map *router_map) { *router_map = (struct ovn_synced_logical_router_map) { .synced_routers = HMAP_INITIALIZER(&router_map->synced_routers), + .new = HMAPX_INITIALIZER(&router_map->new), + .updated = HMAPX_INITIALIZER(&router_map->updated), + .deleted = HMAPX_INITIALIZER(&router_map->deleted), }; } @@ -215,7 +233,17 @@ static void synced_logical_router_map_destroy( struct ovn_synced_logical_router_map *router_map) { + hmapx_destroy(&router_map->new); + hmapx_destroy(&router_map->updated); + + struct hmapx_node *node; struct ovn_synced_logical_router *lr; + HMAPX_FOR_EACH_SAFE (node, &router_map->deleted) { + lr = node->data; + free(lr); + hmapx_delete(&router_map->deleted, node); + } + hmapx_destroy(&router_map->deleted); HMAP_FOR_EACH_POP (lr, hmap_node, &router_map->synced_routers) { free(lr); } @@ -233,6 +261,18 @@ en_datapath_synced_logical_router_init(struct engine_node *node OVS_UNUSED, return router_map; } +static struct ovn_synced_logical_router * +synced_logical_router_alloc(const struct ovn_synced_datapath *sdp) +{ + struct ovn_synced_logical_router *lr = xmalloc(sizeof *lr); + *lr = (struct ovn_synced_logical_router) { + .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_router, + header_), + .sdp = sdp, + }; + return lr; +} + enum engine_node_state en_datapath_synced_logical_router_run(struct engine_node *node , void *data) { @@ -248,12 +288,8 @@ en_datapath_synced_logical_router_run(struct engine_node *node , void *data) if (sdp->nb_row->table->class_ != &nbrec_table_logical_router) { continue; } - struct ovn_synced_logical_router *lr = xmalloc(sizeof *lr); - *lr = (struct ovn_synced_logical_router) { - .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_router, - header_), - .sdp = sdp, - }; + struct ovn_synced_logical_router *lr = + synced_logical_router_alloc(sdp); hmap_insert(&router_map->synced_routers, &lr->hmap_node, uuid_hash(&lr->nb->header_.uuid)); } @@ -261,6 +297,85 @@ en_datapath_synced_logical_router_run(struct engine_node *node , void *data) return EN_UPDATED; } +void +en_datapath_synced_logical_router_clear_tracked_data(void *data) +{ + struct ovn_synced_logical_router_map *router_map = data; + + hmapx_clear(&router_map->new); + hmapx_clear(&router_map->updated); + + struct hmapx_node *node; + HMAPX_FOR_EACH_SAFE (node, &router_map->deleted) { + struct ovn_synced_logical_router *lr = node->data; + free(lr); + hmapx_delete(&router_map->deleted, node); + } +} + +enum engine_input_handler_result +en_datapath_synced_logical_router_datapath_sync_handler( + struct engine_node *node, void *data) +{ + const struct ovn_synced_datapaths *dps = + engine_get_input_data("datapath_sync", node); + struct ovn_synced_logical_router_map *router_map = data; + + if (hmapx_is_empty(&dps->deleted) && + hmapx_is_empty(&dps->new) && + hmapx_is_empty(&dps->updated)) { + return EN_UNHANDLED; + } + + struct hmapx_node *hmapx_node; + struct ovn_synced_datapath *sdp; + struct ovn_synced_logical_router *lr; + HMAPX_FOR_EACH (hmapx_node, &dps->new) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_router) { + continue; + } + lr = synced_logical_router_alloc(sdp); + hmap_insert(&router_map->synced_routers, &lr->hmap_node, + uuid_hash(&lr->nb->header_.uuid)); + hmapx_add(&router_map->new, lr); + } + HMAPX_FOR_EACH (hmapx_node, &dps->deleted) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_router) { + continue; + } + lr = ovn_synced_logical_router_find(router_map, &sdp->nb_row->uuid); + if (!lr) { + return EN_UNHANDLED; + } + hmap_remove(&router_map->synced_routers, &lr->hmap_node); + hmapx_add(&router_map->deleted, lr); + } + HMAPX_FOR_EACH (hmapx_node, &dps->updated) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_router) { + continue; + } + lr = ovn_synced_logical_router_find(router_map, &sdp->nb_row->uuid); + if (!lr) { + return EN_UNHANDLED; + } + lr->nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_router, + header_); + lr->sdp = sdp; + hmapx_add(&router_map->updated, lr); + } + + if (hmapx_is_empty(&router_map->new) && + hmapx_is_empty(&router_map->updated) && + hmapx_is_empty(&router_map->deleted)) { + return EN_HANDLED_UNCHANGED; + } + + return EN_HANDLED_UPDATED; +} + void en_datapath_synced_logical_router_cleanup(void *data) { struct ovn_synced_logical_router_map *router_map = data; diff --git a/northd/en-datapath-logical-router.h b/northd/en-datapath-logical-router.h index de405dc36..291dbf706 100644 --- a/northd/en-datapath-logical-router.h +++ b/northd/en-datapath-logical-router.h @@ -19,6 +19,7 @@ #include "lib/inc-proc-eng.h" #include "openvswitch/hmap.h" +#include "lib/hmapx.h" void *en_datapath_logical_router_init(struct engine_node *, struct engine_arg *); @@ -36,14 +37,27 @@ struct ovn_synced_logical_router { struct ovn_synced_logical_router_map { struct hmap synced_routers; + + bool has_tracked_data; + struct hmapx new; + struct hmapx updated; + struct hmapx deleted; }; +struct uuid; +struct ovn_synced_logical_router * +ovn_synced_logical_router_find(const struct ovn_synced_logical_router_map *map, + const struct uuid *nb_uuid); + void *en_datapath_synced_logical_router_init(struct engine_node *, struct engine_arg *); enum engine_node_state en_datapath_synced_logical_router_run( struct engine_node *, void *data); - +void en_datapath_synced_logical_router_clear_tracked_data(void *data); +enum engine_input_handler_result +en_datapath_synced_logical_router_datapath_sync_handler( + struct engine_node *node, void *data); void en_datapath_synced_logical_router_cleanup(void *data); enum engine_input_handler_result diff --git a/northd/en-datapath-logical-switch.c b/northd/en-datapath-logical-switch.c index 29a64ed43..1c401030e 100644 --- a/northd/en-datapath-logical-switch.c +++ b/northd/en-datapath-logical-switch.c @@ -200,12 +200,30 @@ en_datapath_logical_switch_cleanup(void *data) ovn_unsynced_datapath_map_destroy(map); } +struct ovn_synced_logical_switch * +ovn_synced_logical_switch_find(const struct ovn_synced_logical_switch_map *map, + const struct uuid *nb_uuid) +{ + struct ovn_synced_logical_switch *lsw; + HMAP_FOR_EACH_WITH_HASH (lsw, hmap_node, uuid_hash(nb_uuid), + &map->synced_switches) { + if (uuid_equals(&lsw->nb->header_.uuid, nb_uuid)) { + return lsw; + } + } + + return NULL; +} + static void synced_logical_switch_map_init( struct ovn_synced_logical_switch_map *switch_map) { *switch_map = (struct ovn_synced_logical_switch_map) { .synced_switches = HMAP_INITIALIZER(&switch_map->synced_switches), + .new = HMAPX_INITIALIZER(&switch_map->new), + .updated = HMAPX_INITIALIZER(&switch_map->updated), + .deleted = HMAPX_INITIALIZER(&switch_map->deleted), }; } @@ -213,7 +231,17 @@ static void synced_logical_switch_map_destroy( struct ovn_synced_logical_switch_map *switch_map) { + hmapx_destroy(&switch_map->new); + hmapx_destroy(&switch_map->updated); + + struct hmapx_node *node; struct ovn_synced_logical_switch *ls; + HMAPX_FOR_EACH_SAFE (node, &switch_map->deleted) { + ls = node->data; + free(ls); + hmapx_delete(&switch_map->deleted, node); + } + hmapx_destroy(&switch_map->deleted); HMAP_FOR_EACH_POP (ls, hmap_node, &switch_map->synced_switches) { free(ls); } @@ -231,6 +259,18 @@ en_datapath_synced_logical_switch_init(struct engine_node *node OVS_UNUSED, return switch_map; } +static struct ovn_synced_logical_switch * +synced_logical_switch_alloc(const struct ovn_synced_datapath *sdp) +{ + struct ovn_synced_logical_switch *lsw = xmalloc(sizeof *lsw); + *lsw = (struct ovn_synced_logical_switch) { + .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_switch, + header_), + .sdp = sdp, + }; + return lsw; +} + enum engine_node_state en_datapath_synced_logical_switch_run(struct engine_node *node , void *data) { @@ -246,12 +286,8 @@ en_datapath_synced_logical_switch_run(struct engine_node *node , void *data) if (sdp->nb_row->table->class_ != &nbrec_table_logical_switch) { continue; } - struct ovn_synced_logical_switch *lsw = xmalloc(sizeof *lsw); - *lsw = (struct ovn_synced_logical_switch) { - .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_switch, - header_), - .sdp = sdp, - }; + struct ovn_synced_logical_switch *lsw = + synced_logical_switch_alloc(sdp); hmap_insert(&switch_map->synced_switches, &lsw->hmap_node, uuid_hash(&lsw->nb->header_.uuid)); } @@ -259,6 +295,86 @@ en_datapath_synced_logical_switch_run(struct engine_node *node , void *data) return EN_UPDATED; } +void +en_datapath_synced_logical_switch_clear_tracked_data(void *data) +{ + struct ovn_synced_logical_switch_map *switch_map = data; + + hmapx_clear(&switch_map->new); + hmapx_clear(&switch_map->updated); + + struct hmapx_node *node; + HMAPX_FOR_EACH_SAFE (node, &switch_map->deleted) { + struct ovn_synced_logical_router *lr = node->data; + free(lr); + hmapx_delete(&switch_map->deleted, node); + } +} + + +enum engine_input_handler_result +en_datapath_synced_logical_switch_datapath_sync_handler( + struct engine_node *node, void *data) +{ + const struct ovn_synced_datapaths *dps = + engine_get_input_data("datapath_sync", node); + struct ovn_synced_logical_switch_map *switch_map = data; + + if (hmapx_is_empty(&dps->deleted) && + hmapx_is_empty(&dps->new) && + hmapx_is_empty(&dps->updated)) { + return EN_UNHANDLED; + } + + struct hmapx_node *hmapx_node; + struct ovn_synced_datapath *sdp; + struct ovn_synced_logical_switch *lsw; + HMAPX_FOR_EACH (hmapx_node, &dps->new) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_switch) { + continue; + } + lsw = synced_logical_switch_alloc(sdp); + hmap_insert(&switch_map->synced_switches, &lsw->hmap_node, + uuid_hash(&lsw->nb->header_.uuid)); + hmapx_add(&switch_map->new, lsw); + } + HMAPX_FOR_EACH (hmapx_node, &dps->deleted) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_switch) { + continue; + } + lsw = ovn_synced_logical_switch_find(switch_map, &sdp->nb_row->uuid); + if (!lsw) { + return EN_UNHANDLED; + } + hmap_remove(&switch_map->synced_switches, &lsw->hmap_node); + hmapx_add(&switch_map->deleted, lsw); + } + HMAPX_FOR_EACH (hmapx_node, &dps->updated) { + sdp = hmapx_node->data; + if (sdp->nb_row->table->class_ != &nbrec_table_logical_switch) { + continue; + } + lsw = ovn_synced_logical_switch_find(switch_map, &sdp->nb_row->uuid); + if (!lsw) { + return EN_UNHANDLED; + } + lsw->nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_switch, + header_); + lsw->sdp = sdp; + hmapx_add(&switch_map->updated, lsw); + } + + if (hmapx_is_empty(&switch_map->new) && + hmapx_is_empty(&switch_map->updated) && + hmapx_is_empty(&switch_map->deleted)) { + return EN_HANDLED_UNCHANGED; + } + + return EN_HANDLED_UPDATED; +} + void en_datapath_synced_logical_switch_cleanup(void *data) { struct ovn_synced_logical_switch_map *switch_map = data; diff --git a/northd/en-datapath-logical-switch.h b/northd/en-datapath-logical-switch.h index 6abedbd30..db596cdee 100644 --- a/northd/en-datapath-logical-switch.h +++ b/northd/en-datapath-logical-switch.h @@ -19,6 +19,7 @@ #include "lib/inc-proc-eng.h" #include "openvswitch/hmap.h" +#include "lib/hmapx.h" void *en_datapath_logical_switch_init(struct engine_node *, struct engine_arg *); @@ -38,13 +39,26 @@ struct ovn_synced_logical_switch { struct ovn_synced_logical_switch_map { struct hmap synced_switches; + + struct hmapx new; + struct hmapx updated; + struct hmapx deleted; }; +struct uuid; +struct ovn_synced_logical_switch * +ovn_synced_logical_switch_find(const struct ovn_synced_logical_switch_map *map, + const struct uuid *nb_uuid); + void *en_datapath_synced_logical_switch_init(struct engine_node *, struct engine_arg *); enum engine_node_state en_datapath_synced_logical_switch_run( struct engine_node *, void *data); +void en_datapath_synced_logical_switch_clear_tracked_data(void *data); +enum engine_input_handler_result +en_datapath_synced_logical_switch_datapath_sync_handler( + struct engine_node *node, void *data); void en_datapath_synced_logical_switch_cleanup(void *data); #endif /* EN_DATAPATH_LOGICAL_SWITCH_H */ diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index c43c35118..c0f1d067a 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -185,8 +185,8 @@ static ENGINE_NODE(group_ecmp_route, CLEAR_TRACKED_DATA); static ENGINE_NODE(datapath_logical_router, CLEAR_TRACKED_DATA); static ENGINE_NODE(datapath_logical_switch, CLEAR_TRACKED_DATA); static ENGINE_NODE(datapath_sync, CLEAR_TRACKED_DATA); -static ENGINE_NODE(datapath_synced_logical_router); -static ENGINE_NODE(datapath_synced_logical_switch); +static ENGINE_NODE(datapath_synced_logical_router, CLEAR_TRACKED_DATA); +static ENGINE_NODE(datapath_synced_logical_switch, CLEAR_TRACKED_DATA); void inc_proc_northd_init(struct ovsdb_idl_loop *nb, struct ovsdb_idl_loop *sb) @@ -235,9 +235,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, datapath_sync_logical_router_handler); engine_add_input(&en_datapath_synced_logical_router, &en_datapath_sync, - NULL); + en_datapath_synced_logical_router_datapath_sync_handler); engine_add_input(&en_datapath_synced_logical_switch, &en_datapath_sync, - NULL); + en_datapath_synced_logical_switch_datapath_sync_handler); engine_add_input(&en_northd, &en_nb_mirror, NULL); engine_add_input(&en_northd, &en_nb_mirror_rule, NULL); diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 1013333fd..c5892bc5b 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -17750,3 +17750,56 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([Synced logical switch and router incremental procesesing]) +ovn_start + +# datapath_synced_logical_switch and datapath_synced_logical_router +# should only recompute if datapath_sync has to recompute. Therefore, +# andy situation where datapath_sync can run incrementally, the +# synced datapath nodes should also run incrementally. + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb ls-add sw0 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set logical_switch sw0 other_config:fdb_age_threshold=5 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set logical_switch sw0 other_config:requested-tnl-key=123 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb ls-del sw0 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb lr-add lr0 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set Logical_Router lr0 options:ct-zone-limit=10 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb lr-del lr0 +check_engine_stats datapath_synced_logical_switch norecompute compute +check_engine_stats datapath_synced_logical_router norecompute compute +CHECK_NO_CHANGE_AFTER_RECOMPUTE + +AT_CLEANUP +]) -- 2.49.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev