From: Wen Yang <[email protected]>

da_monitor_destroy() frees each per-object storage, but a monitor
whose target is allocated separately has no point to free it: the
target is still reachable from the storage until hash_del_rcu().

Add an optional da_extra_cleanup() hook, called for each storage after
da_monitor_free_hook() has disarmed its timer and before the storage is
unlinked.  It defaults to a no-op.  tlob, added later in this series,
uses it to retire and free its per-window record.

Suggested-by: Gabriele Monaco <[email protected]>
Signed-off-by: Wen Yang <[email protected]>
---
 include/rv/da_monitor.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index f9af56304c9f..97d9e876c891 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -116,6 +116,16 @@ static struct rv_monitor rv_this;
 #define da_monitor_free_hook(da_mon)
 #endif
 
+/*
+ * Per-object teardown hook, called for each entry after
+ * da_monitor_reset_all() + da_monitor_sync_hook() and before hash_del_rcu().
+ * Runs after da_monitor_free_hook(), so it may free the storage's target.
+ * Default: no-op.
+ */
+#ifndef da_extra_cleanup
+#define da_extra_cleanup(da_mon)
+#endif
+
 /*
  * Type for the target id, default to int but can be overridden.
  * A long type can work as hash table key (PER_OBJ) but will be downgraded to
@@ -715,7 +725,9 @@ static inline void da_monitor_destroy(void)
         * pending, we can safely assume no concurrent user.
         */
        hash_for_each_safe(da_monitor_ht, bkt, tmp, mon_storage, node) {
+               /* Before da_extra_cleanup(): it frees what the timer reads. */
                da_monitor_free_hook(&mon_storage->rv.da_mon);
+               da_extra_cleanup(&mon_storage->rv.da_mon);
                hash_del_rcu(&mon_storage->node);
                if (DA_MON_ALLOCATION_STRATEGY == DA_ALLOC_POOL)
                        mempool_free(mon_storage, &da_monitor_pool);
-- 
2.25.1


Reply via email to