From: wen.yang@linux.dev
To: Gabriele Monaco <gmonaco@redhat.com>
Cc: Nam Cao <namcao@linutronix.de>,
linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org,
Wen Yang <wen.yang@linux.dev>
Subject: [PATCH v8 08/14] rv: Support embedded target types in per-object DA storage
Date: Fri, 6 Nov 2026 01:49:08 +0800 [thread overview]
Message-ID: <49fd8e0482d2cf1f9c690031ab0cf9cc1eb1c5ad.1793900349.git.wen.yang@linux.dev> (raw)
In-Reply-To: <cover.1793900349.git.wen.yang@linux.dev>
From: Wen Yang <wen.yang@linux.dev>
A PER_OBJ monitor usually typedefs monitor_target itself, as a pointer to
the monitored object (borrowed: the object exists independently of the
monitor and outlives the storage).
A monitor whose target is monitor-owned data can instead define
DA_OBJ_EMBEDDED_TYPE with a complete struct type: the framework then
derives monitor_target as a pointer to it, embeds one instance in each
per-object storage, and allocates and frees it together with the storage.
On storage creation the caller-supplied target is shallow-copied into
the storage before it is published, so it may be a fully initialised
stack object.
This allows per-object monitors to manage custom per-instance data without
maintaining private mempools, complex multi-stage reference counting, or
out-of-band teardown state machines.
Suggested-by: Gabriele Monaco <gmonaco@redhat.com>
Signed-off-by: Wen Yang <wen.yang@linux.dev>
---
include/rv/da_monitor.h | 82 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 76 insertions(+), 6 deletions(-)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 76169e41d4e5..ed9e7e740d80 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -61,6 +61,10 @@
#include <linux/slab.h>
#include <linux/hashtable.h>
+#if defined(DA_OBJ_EMBEDDED_TYPE) && RV_MON_TYPE != RV_MON_PER_OBJ
+#error "DA_OBJ_EMBEDDED_TYPE is only supported by RV_MON_PER_OBJ monitors"
+#endif
+
/*
* Per-cpu variables require a unique name although static in some
* configurations (e.g. CONFIG_DEBUG_FORCE_WEAK_PER_CPU or alpha modules).
@@ -453,9 +457,24 @@ static inline void da_monitor_destroy(void)
* Functions to define, init and get a per-object monitor.
*/
+#ifdef DA_OBJ_EMBEDDED_TYPE
+/*
+ * Framework-owned target: one instance is embedded in each storage and
+ * allocated/freed with it. monitor_target keeps pointer semantics, but
+ * da_get_target() points into the storage rather than to a borrowed object.
+ * The header derives the typedef: do not define monitor_target by hand.
+ */
+typedef DA_OBJ_EMBEDDED_TYPE * monitor_target;
+#endif
+
struct da_monitor_storage {
da_id_type id;
+#ifdef DA_OBJ_EMBEDDED_TYPE
+ DA_OBJ_EMBEDDED_TYPE target;
+ bool filled;
+#else
monitor_target target;
+#endif
union rv_task_monitor rv;
struct hlist_node node;
struct rcu_head rcu;
@@ -466,6 +485,40 @@ struct da_monitor_storage {
#endif
static DEFINE_HASHTABLE(da_monitor_ht, DA_MONITOR_HT_BITS);
+#ifdef DA_OBJ_EMBEDDED_TYPE
+
+#define TARGET_PTR(storage) (&(storage)->target)
+
+static inline bool da_storage_is_empty(struct da_monitor_storage *mon_storage)
+{
+ /* Pairs with smp_store_release in da_storage_set_target(). */
+ return !smp_load_acquire(&mon_storage->filled);
+}
+static inline void da_storage_set_target(struct da_monitor_storage *mon_storage,
+ monitor_target target)
+{
+ if (WARN_ON_ONCE(!target))
+ return;
+
+ memcpy(&mon_storage->target, target, sizeof(mon_storage->target));
+ /* Pairs with smp_load_acquire in da_storage_is_empty(). */
+ smp_store_release(&mon_storage->filled, true);
+}
+#else
+
+#define TARGET_PTR(storage) storage->target
+
+static inline bool da_storage_is_empty(struct da_monitor_storage *mon_storage)
+{
+ return !TARGET_PTR(mon_storage);
+}
+static inline void da_storage_set_target(struct da_monitor_storage *mon_storage,
+ monitor_target target)
+{
+ mon_storage->target = target;
+}
+#endif
+
/*
* da_create_empty_storage - pre-allocate an empty storage
*/
@@ -503,7 +556,7 @@ static inline struct da_monitor *da_create_storage(da_id_type id,
if (!mon_storage)
return NULL;
- mon_storage->target = target;
+ da_storage_set_target(mon_storage, target);
return &mon_storage->rv.da_mon;
}
@@ -536,10 +589,20 @@ static struct da_monitor *da_get_monitor(da_id_type id, monitor_target target)
/*
* da_get_target - return the object associated to the monitor
+ *
+ * NULL for an embedded target whose storage was pre-allocated but not filled
+ * yet: a manual-allocation monitor publishes its storage before it has one.
*/
static inline monitor_target da_get_target(struct da_monitor *da_mon)
{
- return container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target;
+ struct da_monitor_storage *mon_storage =
+ container_of(da_mon, struct da_monitor_storage, rv.da_mon);
+
+#ifdef DA_OBJ_EMBEDDED_TYPE
+ if (unlikely(da_storage_is_empty(mon_storage)))
+ return NULL;
+#endif
+ return TARGET_PTR(mon_storage);
}
/*
@@ -572,8 +635,11 @@ static inline struct da_monitor *da_fill_empty_storage(da_id_type id,
monitor_target target,
struct da_monitor *da_mon)
{
- if (unlikely(da_mon && !da_get_target(da_mon)))
- container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target = target;
+ struct da_monitor_storage *mon_storage =
+ container_of(da_mon, struct da_monitor_storage, rv.da_mon);
+
+ if (unlikely(da_mon && da_storage_is_empty(mon_storage)))
+ da_storage_set_target(mon_storage, target);
return da_mon;
}
@@ -589,7 +655,11 @@ static inline monitor_target da_get_target_by_id(da_id_type id)
if (unlikely(!mon_storage))
return NULL;
- return mon_storage->target;
+#ifdef DA_OBJ_EMBEDDED_TYPE
+ if (unlikely(da_storage_is_empty(mon_storage)))
+ return NULL;
+#endif
+ return TARGET_PTR(mon_storage);
}
static void da_kfree_cb(struct rcu_head *head)
@@ -635,7 +705,7 @@ da_create_pool_storage(da_id_type id, monitor_target target,
memset(mon_storage, 0, sizeof(*mon_storage));
mon_storage->id = id;
- mon_storage->target = target;
+ da_storage_set_target(mon_storage, target);
hash_add_rcu(da_monitor_ht, &mon_storage->node, id);
return &mon_storage->rv.da_mon;
--
2.25.1
next prev parent reply other threads:[~2026-11-05 17:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 17:49 [PATCH v8 00/14] rv: Add task latency over budget RV monitor wen.yang
2026-11-05 17:49 ` [PATCH v8 01/14] rv: Force environment reset action on HA monitor start wen.yang
2026-11-05 17:49 ` [PATCH v8 02/14] rv: Fix ha_monitor timer and invariant underflow wen.yang
2026-11-05 17:49 ` [PATCH v8 03/14] rv: Add a KUnit test for the HA timer underflow wen.yang
2026-11-05 17:49 ` [PATCH v8 04/14] rv: Disarm HA timers on the storage free path wen.yang
2026-11-05 17:49 ` [PATCH v8 05/14] rv: Add a KUnit test for " wen.yang
2026-11-05 17:49 ` [PATCH v8 06/14] rv: Make da_monitor_reset_hook, sync_hook and EVENT_NONE_LBL overridable wen.yang
2026-11-05 17:49 ` [PATCH v8 07/14] rv: Introduce DA_MON_ALLOCATION_STRATEGY wen.yang
2026-11-05 17:49 ` wen.yang [this message]
2026-11-05 17:49 ` [PATCH v8 09/14] rv: Add generic uprobe infrastructure for RV monitors wen.yang
2026-11-05 17:49 ` [PATCH v8 10/14] rv: Add tlob model DOT file wen.yang
2026-11-05 17:49 ` [PATCH v8 11/14] rv: Add tlob hybrid automaton monitor wen.yang
2026-11-05 17:49 ` [PATCH v8 12/14] rv: Add KUnit tests for the tlob monitor wen.yang
2026-11-05 17:49 ` [PATCH v8 13/14] selftests/verification: Add tlob selftests wen.yang
2026-11-05 17:49 ` [PATCH v8 14/14] selftests/ftrace: Walk up parent dirs to find test.d/functions wen.yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49fd8e0482d2cf1f9c690031ab0cf9cc1eb1c5ad.1793900349.git.wen.yang@linux.dev \
--to=wen.yang@linux.dev \
--cc=gmonaco@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=namcao@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®