Add a new OVS external-id, "ovn-limit-lflow-cache", through which users can specify the maximum size of the ovn-controller logical flow cache.
To maintain backwards compatibility the default behavior is to not enforce any limit on the size of the cache. Signed-off-by: Dumitru Ceara <[email protected]> --- NEWS | 3 +++ controller/chassis.c | 23 ++++++++++++++++++++++- controller/lflow-cache.c | 25 +++++++++++++++++++++++-- controller/lflow-cache.h | 2 +- controller/ovn-controller.8.xml | 16 ++++++++++++++++ controller/ovn-controller.c | 8 +++++++- 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index d4619dd..68c9a8e 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,9 @@ Post-v20.12.0 - ovn-ctl: Added new command line argument '--ovsdb-disable-file-column-diff' to support ovsdb-server upgrades from version 2.14 and earlier to 2.15 and later. See ovsdb(7) for more details. + - ovn-controller: Add a configuration knob, through OVS external-id + "ovn-limit-lflow-cache", to allow enforcing a limit for the size of the + logical flow cache. OVN v20.12.0 - 18 Dec 2020 -------------------------- diff --git a/controller/chassis.c b/controller/chassis.c index b4d4b0e..c66837a 100644 --- a/controller/chassis.c +++ b/controller/chassis.c @@ -49,6 +49,7 @@ struct ovs_chassis_cfg { const char *monitor_all; const char *chassis_macs; const char *enable_lflow_cache; + const char *limit_lflow_cache; /* Set of encap types parsed from the 'ovn-encap-type' external-id. */ struct sset encap_type_set; @@ -135,6 +136,12 @@ get_enable_lflow_cache(const struct smap *ext_ids) } static const char * +get_limit_lflow_cache(const struct smap *ext_ids) +{ + return smap_get_def(ext_ids, "ovn-limit-lflow-cache", ""); +} + +static const char * get_encap_csum(const struct smap *ext_ids) { return smap_get_def(ext_ids, "ovn-encap-csum", "true"); @@ -256,6 +263,7 @@ chassis_parse_ovs_config(const struct ovsrec_open_vswitch_table *ovs_table, ovs_cfg->monitor_all = get_monitor_all(&cfg->external_ids); ovs_cfg->chassis_macs = get_chassis_mac_mappings(&cfg->external_ids); ovs_cfg->enable_lflow_cache = get_enable_lflow_cache(&cfg->external_ids); + ovs_cfg->limit_lflow_cache = get_limit_lflow_cache(&cfg->external_ids); if (!chassis_parse_ovs_encap_type(encap_type, &ovs_cfg->encap_type_set)) { return false; @@ -283,13 +291,16 @@ chassis_build_other_config(struct smap *config, const char *bridge_mappings, const char *datapath_type, const char *cms_options, const char *monitor_all, const char *chassis_macs, const char *iface_types, - const char *enable_lflow_cache, bool is_interconn) + const char *enable_lflow_cache, + const char *limit_lflow_cache, + bool is_interconn) { smap_replace(config, "ovn-bridge-mappings", bridge_mappings); smap_replace(config, "datapath-type", datapath_type); smap_replace(config, "ovn-cms-options", cms_options); smap_replace(config, "ovn-monitor-all", monitor_all); smap_replace(config, "ovn-enable-lflow-cache", enable_lflow_cache); + smap_replace(config, "ovn-limit-lflow-cache", limit_lflow_cache); smap_replace(config, "iface-types", iface_types); smap_replace(config, "ovn-chassis-mac-mappings", chassis_macs); smap_replace(config, "is-interconn", is_interconn ? "true" : "false"); @@ -305,6 +316,7 @@ chassis_other_config_changed(const char *bridge_mappings, const char *monitor_all, const char *chassis_macs, const char *enable_lflow_cache, + const char *limit_lflow_cache, const struct ds *iface_types, bool is_interconn, const struct sbrec_chassis *chassis_rec) @@ -344,6 +356,13 @@ chassis_other_config_changed(const char *bridge_mappings, return true; } + const char *chassis_limit_lflow_cache = + get_limit_lflow_cache(&chassis_rec->other_config); + + if (strcmp(limit_lflow_cache, chassis_limit_lflow_cache)) { + return true; + } + const char *chassis_mac_mappings = get_chassis_mac_mappings(&chassis_rec->other_config); if (strcmp(chassis_macs, chassis_mac_mappings)) { @@ -523,6 +542,7 @@ chassis_update(const struct sbrec_chassis *chassis_rec, ovs_cfg->monitor_all, ovs_cfg->chassis_macs, ovs_cfg->enable_lflow_cache, + ovs_cfg->limit_lflow_cache, &ovs_cfg->iface_types, ovs_cfg->is_interconn, chassis_rec)) { @@ -536,6 +556,7 @@ chassis_update(const struct sbrec_chassis *chassis_rec, ovs_cfg->chassis_macs, ds_cstr_ro(&ovs_cfg->iface_types), ovs_cfg->enable_lflow_cache, + ovs_cfg->limit_lflow_cache, ovs_cfg->is_interconn); sbrec_chassis_verify_other_config(chassis_rec); sbrec_chassis_set_other_config(chassis_rec, &other_config); diff --git a/controller/lflow-cache.c b/controller/lflow-cache.c index 4fd7bf4..ee7ea9b 100644 --- a/controller/lflow-cache.c +++ b/controller/lflow-cache.c @@ -37,9 +37,11 @@ COVERAGE_DEFINE(lflow_cache_add); COVERAGE_DEFINE(lflow_cache_hit); COVERAGE_DEFINE(lflow_cache_miss); COVERAGE_DEFINE(lflow_cache_delete); +COVERAGE_DEFINE(lflow_cache_full); struct lflow_cache { struct hmap entries; + uint32_t capacity; bool enabled; }; @@ -99,12 +101,14 @@ lflow_cache_destroy(struct lflow_cache *lc) } void -lflow_cache_enable(struct lflow_cache *lc, bool enabled) +lflow_cache_enable(struct lflow_cache *lc, bool enabled, uint32_t capacity) { - if (lc->enabled && !enabled) { + if ((lc->enabled && !enabled) || capacity < hmap_count(&lc->entries)) { lflow_cache_flush(lc); } + lc->enabled = enabled; + lc->capacity = capacity; } bool @@ -121,6 +125,10 @@ lflow_cache_add_conj_id(struct lflow_cache *lc, struct lflow_cache_value *lcv = lflow_cache_add__(lc, lflow, LCACHE_T_CONJ_ID); + if (!lcv) { + return; + } + COVERAGE_INC(lflow_cache_add_conj_id); lcv->conj_id_ofs = conj_id_ofs; } @@ -134,6 +142,10 @@ lflow_cache_add_expr(struct lflow_cache *lc, struct lflow_cache_value *lcv = lflow_cache_add__(lc, lflow, LCACHE_T_EXPR); + if (!lcv) { + return; + } + COVERAGE_INC(lflow_cache_add_expr); lcv->conj_id_ofs = conj_id_ofs; lcv->expr = expr; @@ -147,6 +159,10 @@ lflow_cache_add_matches(struct lflow_cache *lc, struct lflow_cache_value *lcv = lflow_cache_add__(lc, lflow, LCACHE_T_MATCHES); + if (!lcv) { + return; + } + COVERAGE_INC(lflow_cache_add_matches); lcv->expr_matches = matches; } @@ -192,6 +208,11 @@ lflow_cache_add__(struct lflow_cache *lc, const struct sbrec_logical_flow *lflow, enum lflow_cache_type type) { + if (hmap_count(&lc->entries) == lc->capacity) { + COVERAGE_INC(lflow_cache_full); + return NULL; + } + struct lflow_cache_entry *lce = xzalloc(sizeof *lce); COVERAGE_INC(lflow_cache_add); diff --git a/controller/lflow-cache.h b/controller/lflow-cache.h index 5c622d5..6d3ea05 100644 --- a/controller/lflow-cache.h +++ b/controller/lflow-cache.h @@ -53,7 +53,7 @@ struct lflow_cache_value { struct lflow_cache *lflow_cache_create(void); void lflow_cache_flush(struct lflow_cache *); void lflow_cache_destroy(struct lflow_cache *); -void lflow_cache_enable(struct lflow_cache *, bool enabled); +void lflow_cache_enable(struct lflow_cache *, bool enabled, uint32_t capacity); bool lflow_cache_is_enabled(struct lflow_cache *); void lflow_cache_add_conj_id(struct lflow_cache *, diff --git a/controller/ovn-controller.8.xml b/controller/ovn-controller.8.xml index 29833c7..e92db6d 100644 --- a/controller/ovn-controller.8.xml +++ b/controller/ovn-controller.8.xml @@ -249,6 +249,22 @@ processing the southbound and local Open vSwitch database changes. The default value is considered false if this option is not defined. </dd> + + <dt><code>external_ids:ovn-enable-lflow-cache</code></dt> + <dd> + The boolean flag indicates if <code>ovn-controller</code> should + enable/disable the logical flow in-memory cache it uses when + processing Southbound database logical flow changes. By default + caching is enabled. + </dd> + + <dt><code>external_ids:ovn-limit-lflow-cache</code></dt> + <dd> + When used, this configuration value determines the maximum number of + logical flow cache entries <code>ovn-controller</code> may create + when the logical flow cache is enabled. By default the size of the + cache is unlimited. + </dd> </dl> <p> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index c0737a8..f551142 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -95,6 +95,9 @@ static unixctl_cb_func debug_delay_nb_cfg_report; static char *parse_options(int argc, char *argv[]); OVS_NO_RETURN static void usage(void); +/* By default don't set an upper bound for the lflow cache. */ +#define DEFAULT_LFLOW_CACHE_MAX_ENTRIES UINT32_MAX + struct controller_engine_ctx { struct lflow_cache *lflow_cache; }; @@ -581,7 +584,10 @@ update_sb_db(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, lflow_cache_enable(ctx->lflow_cache, smap_get_bool(&cfg->external_ids, "ovn-enable-lflow-cache", - true)); + true), + smap_get_uint(&cfg->external_ids, + "ovn-limit-lflow-cache", + DEFAULT_LFLOW_CACHE_MAX_ENTRIES)); } } _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
