On 1/12/23 20:26, Mark Michelson wrote: > Thanks for this Dumitru, > > Acked-by: Mark Michelson <mmichel...@redhat.com> > > I have one note down below, however I don't think it's critical enough > not to ack the patch. > > On 12/15/22 16:25, Dumitru Ceara wrote: >> To do this we factor the memory trimming code out into its own module, >> memory-trim. We use this now for both the lflow cache (in >> ovn-controller) and for ovn-northd. >> >> Signed-off-by: Dumitru Ceara <dce...@redhat.com> >> --- >> controller/lflow-cache.c | 68 +++++--------------------- >> lib/automake.mk | 2 + >> lib/memory-trim.c | 120 >> ++++++++++++++++++++++++++++++++++++++++++++++ >> lib/memory-trim.h | 33 +++++++++++++ >> northd/inc-proc-northd.c | 4 +- >> northd/inc-proc-northd.h | 2 - >> northd/ovn-northd.c | 33 ++++++++++++- >> ovn-nb.xml | 9 +++ >> 8 files changed, 212 insertions(+), 59 deletions(-) >> create mode 100644 lib/memory-trim.c >> create mode 100644 lib/memory-trim.h >> >> diff --git a/controller/lflow-cache.c b/controller/lflow-cache.c >> index 9fca2d7441..9d0e9cd10b 100644 >> --- a/controller/lflow-cache.c >> +++ b/controller/lflow-cache.c >> @@ -24,10 +24,9 @@ >> #include "coverage.h" >> #include "lflow-cache.h" >> #include "lib/uuid.h" >> -#include "openvswitch/poll-loop.h" >> +#include "memory-trim.h" >> #include "openvswitch/vlog.h" >> #include "ovn/expr.h" >> -#include "timeval.h" >> VLOG_DEFINE_THIS_MODULE(lflow_cache); >> @@ -54,6 +53,7 @@ static struct vlog_rate_limit rl = >> VLOG_RATE_LIMIT_INIT(5, 1); >> struct lflow_cache { >> struct hmap entries[LCACHE_T_MAX]; >> + struct memory_trimmer *mt; >> uint32_t n_entries; >> uint32_t high_watermark; >> uint32_t capacity; >> @@ -61,10 +61,7 @@ struct lflow_cache { >> uint64_t max_mem_usage; >> uint32_t trim_limit; >> uint32_t trim_wmark_perc; >> - uint32_t trim_timeout_ms; >> uint64_t trim_count; >> - long long int last_active_ms; >> - bool recently_active; >> bool enabled; >> }; >> @@ -84,7 +81,6 @@ static struct lflow_cache_value *lflow_cache_add__( >> static void lflow_cache_delete__(struct lflow_cache *lc, >> struct lflow_cache_entry *lce); >> static void lflow_cache_trim__(struct lflow_cache *lc, bool force); >> -static void lflow_cache_record_activity__(struct lflow_cache *lc); >> struct lflow_cache * >> lflow_cache_create(void) >> @@ -94,6 +90,7 @@ lflow_cache_create(void) >> for (size_t i = 0; i < LCACHE_T_MAX; i++) { >> hmap_init(&lc->entries[i]); >> } >> + lc->mt = memory_trimmer_create(); >> return lc; >> } >> @@ -127,6 +124,7 @@ lflow_cache_destroy(struct lflow_cache *lc) >> for (size_t i = 0; i < LCACHE_T_MAX; i++) { >> hmap_destroy(&lc->entries[i]); >> } >> + memory_trimmer_destroy(lc->mt); >> free(lc); >> } >> @@ -146,13 +144,6 @@ lflow_cache_enable(struct lflow_cache *lc, bool >> enabled, uint32_t capacity, >> trim_wmark_perc = 100; >> } >> - if (trim_timeout_ms < 1000) { >> - VLOG_WARN_RL(&rl, "Invalid requested trim timeout: " >> - "requested %"PRIu32" ms, using 1000 ms instead", >> - trim_timeout_ms); >> - trim_timeout_ms = 1000; >> - } >> - >> uint64_t max_mem_usage = max_mem_usage_kb * 1024; >> bool need_flush = false; >> bool need_trim = false; >> @@ -172,13 +163,13 @@ lflow_cache_enable(struct lflow_cache *lc, bool >> enabled, uint32_t capacity, >> lc->max_mem_usage = max_mem_usage; >> lc->trim_limit = lflow_trim_limit; >> lc->trim_wmark_perc = trim_wmark_perc; >> - lc->trim_timeout_ms = trim_timeout_ms; >> + memory_trimmer_set(lc->mt, trim_timeout_ms); >> if (need_flush) { >> - lflow_cache_record_activity__(lc); >> + memory_trimmer_record_activity(lc->mt); >> lflow_cache_flush(lc); >> } else if (need_trim) { >> - lflow_cache_record_activity__(lc); >> + memory_trimmer_record_activity(lc->mt); >> lflow_cache_trim__(lc, false); >> } >> } >> @@ -286,7 +277,7 @@ lflow_cache_delete(struct lflow_cache *lc, const >> struct uuid *lflow_uuid) >> lflow_cache_delete__(lc, CONTAINER_OF(lcv, struct >> lflow_cache_entry, >> value)); >> lflow_cache_trim__(lc, false); >> - lflow_cache_record_activity__(lc); >> + memory_trimmer_record_activity(lc->mt); >> } >> } >> @@ -327,41 +318,15 @@ lflow_cache_get_memory_usage(const struct >> lflow_cache *lc, struct simap *usage) >> void >> lflow_cache_run(struct lflow_cache *lc) >> { >> - if (!lc->recently_active) { >> - return; >> - } >> - >> - long long int now = time_msec(); >> - if (now < lc->last_active_ms || now < lc->trim_timeout_ms) { >> - VLOG_WARN_RL(&rl, "Detected cache last active timestamp >> overflow"); >> - lc->recently_active = false; >> - lflow_cache_trim__(lc, true); >> - return; >> - } >> - >> - if (now < lc->trim_timeout_ms) { >> - VLOG_WARN_RL(&rl, "Detected very large trim timeout: " >> - "now %lld ms timeout %"PRIu32" ms", >> - now, lc->trim_timeout_ms); >> - return; >> - } >> - >> - if (now - lc->trim_timeout_ms >= lc->last_active_ms) { >> - VLOG_INFO_RL(&rl, "Detected cache inactivity " >> - "(last active %lld ms ago): trimming cache", >> - now - lc->last_active_ms); >> + if (memory_trimmer_run(lc->mt)) { >> lflow_cache_trim__(lc, true); >> - lc->recently_active = false; >> } >> } >> void >> lflow_cache_wait(struct lflow_cache *lc) >> { >> - if (!lc->recently_active) { >> - return; >> - } >> - poll_timer_wait_until(lc->last_active_ms + lc->trim_timeout_ms); >> + memory_trimmer_wait(lc->mt); >> } >> static struct lflow_cache_value * >> @@ -388,7 +353,7 @@ lflow_cache_add__(struct lflow_cache *lc, const >> struct uuid *lflow_uuid, >> } >> } >> - lflow_cache_record_activity__(lc); >> + memory_trimmer_record_activity(lc->mt); >> lc->mem_usage += size; >> COVERAGE_INC(lflow_cache_add); >> @@ -447,17 +412,8 @@ lflow_cache_trim__(struct lflow_cache *lc, bool >> force) >> hmap_shrink(&lc->entries[i]); >> } >> -#if HAVE_DECL_MALLOC_TRIM >> - malloc_trim(0); >> -#endif >> + memory_trimmer_trim(lc->mt); >> lc->high_watermark = lc->n_entries; >> lc->trim_count++; >> } >> - >> -static void >> -lflow_cache_record_activity__(struct lflow_cache *lc) >> -{ >> - lc->last_active_ms = time_msec(); >> - lc->recently_active = true; >> -} >> diff --git a/lib/automake.mk b/lib/automake.mk >> index 15d4f84bbb..b69e854b0b 100644 >> --- a/lib/automake.mk >> +++ b/lib/automake.mk >> @@ -30,6 +30,8 @@ lib_libovn_la_SOURCES = \ >> lib/mac-binding-index.h \ >> lib/mcast-group-index.c \ >> lib/mcast-group-index.h \ >> + lib/memory-trim.c \ >> + lib/memory-trim.h \ >> lib/lex.c \ >> lib/objdep.c \ >> lib/objdep.h \ >> diff --git a/lib/memory-trim.c b/lib/memory-trim.c >> new file mode 100644 >> index 0000000000..a6791073ee >> --- /dev/null >> +++ b/lib/memory-trim.c >> @@ -0,0 +1,120 @@ >> +/* >> + * Copyright (c) 2022, Red Hat, Inc. >> + * >> + * Licensed under the Apache License, Version 2.0 (the "License"); >> + * you may not use this file except in compliance with the License. >> + * You may obtain a copy of the License at: >> + * >> + * http://www.apache.org/licenses/LICENSE-2.0 >> + * >> + * Unless required by applicable law or agreed to in writing, software >> + * distributed under the License is distributed on an "AS IS" BASIS, >> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >> implied. >> + * See the License for the specific language governing permissions and >> + * limitations under the License. >> + */ >> + >> + >> +#include <config.h> >> + >> +#if HAVE_DECL_MALLOC_TRIM >> +#include <malloc.h> >> +#endif >> + >> +#include "memory-trim.h" >> + >> +#include "openvswitch/poll-loop.h" >> +#include "openvswitch/vlog.h" >> +#include "timeval.h" >> + >> +VLOG_DEFINE_THIS_MODULE(memory_trim); >> + >> +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); >> + >> +struct memory_trimmer { >> + uint32_t trim_timeout_ms; >> + long long int last_active_ms; >> + bool recently_active; >> +}; >> + >> +struct memory_trimmer * >> +memory_trimmer_create(void) >> +{ >> + struct memory_trimmer *mt = xzalloc(sizeof *mt); >> + return mt; >> +} >> + >> +void >> +memory_trimmer_destroy(struct memory_trimmer *mt) >> +{ >> + free(mt); >> +} >> + >> +void >> +memory_trimmer_set(struct memory_trimmer *mt, uint32_t trim_timeout_ms) >> +{ >> + if (trim_timeout_ms < 1000) { >> + VLOG_WARN_RL(&rl, "Invalid requested trim timeout: " >> + "requested %"PRIu32" ms, using 1000 ms instead", >> + trim_timeout_ms); >> + trim_timeout_ms = 1000; >> + } >> + mt->trim_timeout_ms = trim_timeout_ms; >> +} >> + >> +/* Returns true if trimming due to inactivity should happen. */ >> +bool >> +memory_trimmer_run(struct memory_trimmer *mt) >> +{ >> + if (!mt->recently_active) { >> + return false; >> + } >> + >> + long long int now = time_msec(); >> + if (now < mt->last_active_ms || now < mt->trim_timeout_ms) { >> + VLOG_WARN_RL(&rl, "Detected last active timestamp overflow"); >> + mt->recently_active = false; >> + return true; >> + } >> + >> + if (now < mt->trim_timeout_ms) { >> + VLOG_WARN_RL(&rl, "Detected very large trim timeout: " >> + "now %lld ms timeout %"PRIu32" ms", >> + now, mt->trim_timeout_ms); >> + return false; >> + } > > I realize this was copied directly and the code is unchanged. However, I > think it's impossible for the block above to run. The reason is that if > now < mt->trim_timeout_ms, then the previous block (if (now < > mt->last_active_ms || now < mt->trim_timeout_ms)) will handle it. >
You're right, I removed this block and applied the patch to main branch, thanks! Regards, Dumitru _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev