[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250919140954.104920-4-gmonaco@redhat.com>
Date: Fri, 19 Sep 2025 16:09:37 +0200
From: Gabriele Monaco <gmonaco@...hat.com>
To: linux-kernel@...r.kernel.org,
Steven Rostedt <rostedt@...dmis.org>,
linux-trace-kernel@...r.kernel.org
Cc: Gabriele Monaco <gmonaco@...hat.com>,
Nam Cao <namcao@...utronix.de>,
Tomas Glozar <tglozar@...hat.com>,
Juri Lelli <jlelli@...hat.com>,
Clark Williams <williams@...hat.com>,
John Kacur <jkacur@...hat.com>
Subject: [PATCH v2 03/20] rv: Unify DA event handling functions across monitor types
The DA event handling functions are mostly duplicated because the
per-task monitors need to propagate the task to use the pid in the trace
events. This is a maintenance burden for a little advantage.
The task can be obtained with some pointer arithmetic from the da_mon,
hence only the function tracing events really need to differ.
Unify all code handling the events, create da_trace_event() and
da_trace_error() that only call the tracepoint function.
Propagate the monitor id through the calls, the do_trace_ functions use
the id (pid) in case of per-task monitors but ignore it for implicit
monitors.
Signed-off-by: Gabriele Monaco <gmonaco@...hat.com>
---
include/rv/da_monitor.h | 303 +++++++++++++++++++---------------------
1 file changed, 142 insertions(+), 161 deletions(-)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 7c3540d0f64e..05b216f90f93 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -23,6 +23,13 @@
#define RV_DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME)
static struct rv_monitor rv_this;
+/*
+ * Type for the target id, default to int but can be overridden.
+ */
+#ifndef da_id_type
+#define da_id_type int
+#endif
+
#ifdef CONFIG_RV_REACTORS
static void cond_react(enum states curr_state, enum events event)
@@ -99,90 +106,6 @@ static inline bool da_monitor_handling_event(struct da_monitor *da_mon)
return 1;
}
-#if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
-/*
- * Event handler for implicit monitors. Implicit monitor is the one which the
- * handler does not need to specify which da_monitor to manipulate. Examples
- * of implicit monitor are the per_cpu or the global ones.
- *
- * Retry in case there is a race between getting and setting the next state,
- * warn and reset the monitor if it runs out of retries. The monitor should be
- * able to handle various orders.
- */
-
-static inline bool da_event(struct da_monitor *da_mon, enum events event)
-{
- enum states curr_state, next_state;
-
- curr_state = READ_ONCE(da_mon->curr_state);
- for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) {
- next_state = model_get_next_state(curr_state, event);
- if (next_state == INVALID_STATE) {
- cond_react(curr_state, event);
- CONCATENATE(trace_error_, MONITOR_NAME)(
- model_get_state_name(curr_state),
- model_get_event_name(event));
- return false;
- }
- if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) {
- CONCATENATE(trace_event_, MONITOR_NAME)(
- model_get_state_name(curr_state),
- model_get_event_name(event),
- model_get_state_name(next_state),
- model_is_final_state(next_state));
- return true;
- }
- }
-
- trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event));
- pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS)
- " retries reached for event %s, resetting monitor %s",
- model_get_event_name(event), __stringify(MONITOR_NAME));
- return false;
-}
-
-#elif RV_MON_TYPE == RV_MON_PER_TASK
-/*
- * Event handler for per_task monitors.
- *
- * Retry in case there is a race between getting and setting the next state,
- * warn and reset the monitor if it runs out of retries. The monitor should be
- * able to handle various orders.
- */
-
-static inline bool da_event(struct da_monitor *da_mon, struct task_struct *tsk,
- enum events event)
-{
- enum states curr_state, next_state;
-
- curr_state = READ_ONCE(da_mon->curr_state);
- for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) {
- next_state = model_get_next_state(curr_state, event);
- if (next_state == INVALID_STATE) {
- cond_react(curr_state, event);
- CONCATENATE(trace_error_, MONITOR_NAME)(tsk->pid,
- model_get_state_name(curr_state),
- model_get_event_name(event));
- return false;
- }
- if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) {
- CONCATENATE(trace_event_, MONITOR_NAME)(tsk->pid,
- model_get_state_name(curr_state),
- model_get_event_name(event),
- model_get_state_name(next_state),
- model_is_final_state(next_state));
- return true;
- }
- }
-
- trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event));
- pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS)
- " retries reached for event %s, resetting monitor %s",
- model_get_event_name(event), __stringify(MONITOR_NAME));
- return false;
-}
-#endif /* RV_MON_TYPE */
-
#if RV_MON_TYPE == RV_MON_GLOBAL
/*
* Functions to define, init and get a global monitor.
@@ -288,6 +211,14 @@ static inline struct da_monitor *da_get_monitor(struct task_struct *tsk)
return &tsk->rv[task_mon_slot].da_mon;
}
+/*
+ * da_get_task - return the task associated to the monitor
+ */
+static inline struct task_struct *da_get_task(struct da_monitor *da_mon)
+{
+ return container_of(da_mon, struct task_struct, rv[task_mon_slot].da_mon);
+}
+
static void da_monitor_reset_all(void)
{
struct task_struct *g, *p;
@@ -337,33 +268,144 @@ static inline void da_monitor_destroy(void)
#if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
/*
- * Handle event for implicit monitor: da_get_monitor() will figure out
- * the monitor.
+ * Trace events for implicit monitors. Implicit monitor is the one which the
+ * handler does not need to specify which da_monitor to manipulate. Examples
+ * of implicit monitor are the per_cpu or the global ones.
*/
-static inline void __da_handle_event(struct da_monitor *da_mon,
- enum events event)
+static inline void da_trace_event(struct da_monitor *da_mon,
+ char *curr_state, char *event,
+ char *next_state, bool is_final,
+ da_id_type id)
+{
+ CONCATENATE(trace_event_, MONITOR_NAME)(curr_state, event, next_state,
+ is_final);
+}
+
+static inline void da_trace_error(struct da_monitor *da_mon,
+ char *curr_state, char *event,
+ da_id_type id)
+{
+ CONCATENATE(trace_error_, MONITOR_NAME)(curr_state, event);
+}
+
+#elif RV_MON_TYPE == RV_MON_PER_TASK
+/*
+ * Trace events for per_task monitors, report the PID of the task.
+ */
+
+static inline void da_trace_event(struct da_monitor *da_mon,
+ char *curr_state, char *event,
+ char *next_state, bool is_final,
+ da_id_type id)
+{
+ CONCATENATE(trace_event_, MONITOR_NAME)(id, curr_state, event,
+ next_state, is_final);
+}
+
+static inline void da_trace_error(struct da_monitor *da_mon,
+ char *curr_state, char *event,
+ da_id_type id)
+{
+ CONCATENATE(trace_error_, MONITOR_NAME)(id, curr_state, event);
+}
+#endif /* RV_MON_TYPE */
+
+/*
+ * da_event - handle an event for the da_mon
+ *
+ * This function is valid for both implicit and id monitors.
+ * Retry in case there is a race between getting and setting the next state,
+ * warn and reset the monitor if it runs out of retries. The monitor should be
+ * able to handle various orders.
+ */
+static inline bool da_event(struct da_monitor *da_mon, enum events event, da_id_type id)
+{
+ enum states curr_state, next_state;
+
+ curr_state = READ_ONCE(da_mon->curr_state);
+ for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) {
+ next_state = model_get_next_state(curr_state, event);
+ if (next_state == INVALID_STATE) {
+ cond_react(curr_state, event);
+ da_trace_error(da_mon, model_get_state_name(curr_state),
+ model_get_event_name(event), id);
+ return false;
+ }
+ if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) {
+ da_trace_event(da_mon, model_get_state_name(curr_state),
+ model_get_event_name(event),
+ model_get_state_name(next_state),
+ model_is_final_state(next_state), id);
+ return true;
+ }
+ }
+
+ trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event));
+ pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS)
+ " retries reached for event %s, resetting monitor %s",
+ model_get_event_name(event), __stringify(MONITOR_NAME));
+ return false;
+}
+
+static inline void __da_handle_event_common(struct da_monitor *da_mon,
+ enum events event, da_id_type id)
{
bool retval;
- retval = da_event(da_mon, event);
+ retval = da_event(da_mon, event, id);
if (!retval)
da_monitor_reset(da_mon);
}
-/*
- * da_handle_event - handle an event
- */
-static inline void da_handle_event(enum events event)
+static inline void __da_handle_event(struct da_monitor *da_mon,
+ enum events event, da_id_type id)
{
- struct da_monitor *da_mon = da_get_monitor();
bool retval;
retval = da_monitor_handling_event(da_mon);
if (!retval)
return;
- __da_handle_event(da_mon, event);
+ __da_handle_event_common(da_mon, event, id);
+}
+
+static inline bool __da_handle_start_event(struct da_monitor *da_mon,
+ enum events event, da_id_type id)
+{
+ if (unlikely(!da_monitoring(da_mon))) {
+ da_monitor_start(da_mon);
+ return 0;
+ }
+
+ __da_handle_event_common(da_mon, event, id);
+
+ return 1;
+}
+
+static inline bool __da_handle_start_run_event(struct da_monitor *da_mon,
+ enum events event, da_id_type id)
+{
+ if (unlikely(!da_monitoring(da_mon)))
+ da_monitor_start(da_mon);
+
+ __da_handle_event_common(da_mon, event, id);
+
+ return 1;
+}
+
+#if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
+/*
+ * Handle event for implicit monitor: da_get_monitor() will figure out
+ * the monitor.
+ */
+
+/*
+ * da_handle_event - handle an event
+ */
+static inline void da_handle_event(enum events event)
+{
+ __da_handle_event(da_get_monitor(), event, 0);
}
/*
@@ -378,21 +420,9 @@ static inline void da_handle_event(enum events event)
*/
static inline bool da_handle_start_event(enum events event)
{
- struct da_monitor *da_mon;
-
if (!da_monitor_enabled())
return 0;
-
- da_mon = da_get_monitor();
-
- if (unlikely(!da_monitoring(da_mon))) {
- da_monitor_start(da_mon);
- return 0;
- }
-
- __da_handle_event(da_mon, event);
-
- return 1;
+ return __da_handle_start_event(da_get_monitor(), event, 0);
}
/*
@@ -403,19 +433,9 @@ static inline bool da_handle_start_event(enum events event)
*/
static inline bool da_handle_start_run_event(enum events event)
{
- struct da_monitor *da_mon;
-
if (!da_monitor_enabled())
return 0;
-
- da_mon = da_get_monitor();
-
- if (unlikely(!da_monitoring(da_mon)))
- da_monitor_start(da_mon);
-
- __da_handle_event(da_mon, event);
-
- return 1;
+ return __da_handle_start_run_event(da_get_monitor(), event, 0);
}
#elif RV_MON_TYPE == RV_MON_PER_TASK
@@ -423,29 +443,12 @@ static inline bool da_handle_start_run_event(enum events event)
* Handle event for per task.
*/
-static inline void __da_handle_event(struct da_monitor *da_mon,
- struct task_struct *tsk, enum events event)
-{
- bool retval;
-
- retval = da_event(da_mon, tsk, event);
- if (!retval)
- da_monitor_reset(da_mon);
-}
-
/*
* da_handle_event - handle an event
*/
static inline void da_handle_event(struct task_struct *tsk, enum events event)
{
- struct da_monitor *da_mon = da_get_monitor(tsk);
- bool retval;
-
- retval = da_monitor_handling_event(da_mon);
- if (!retval)
- return;
-
- __da_handle_event(da_mon, tsk, event);
+ __da_handle_event(da_get_monitor(tsk), event, tsk->pid);
}
/*
@@ -461,21 +464,9 @@ static inline void da_handle_event(struct task_struct *tsk, enum events event)
static inline bool da_handle_start_event(struct task_struct *tsk,
enum events event)
{
- struct da_monitor *da_mon;
-
if (!da_monitor_enabled())
return 0;
-
- da_mon = da_get_monitor(tsk);
-
- if (unlikely(!da_monitoring(da_mon))) {
- da_monitor_start(da_mon);
- return 0;
- }
-
- __da_handle_event(da_mon, tsk, event);
-
- return 1;
+ return __da_handle_start_event(da_get_monitor(tsk), event, tsk->pid);
}
/*
@@ -487,19 +478,9 @@ static inline bool da_handle_start_event(struct task_struct *tsk,
static inline bool da_handle_start_run_event(struct task_struct *tsk,
enum events event)
{
- struct da_monitor *da_mon;
-
if (!da_monitor_enabled())
return 0;
-
- da_mon = da_get_monitor(tsk);
-
- if (unlikely(!da_monitoring(da_mon)))
- da_monitor_start(da_mon);
-
- __da_handle_event(da_mon, tsk, event);
-
- return 1;
+ return __da_handle_start_run_event(da_get_monitor(tsk), event, tsk->pid);
}
#endif /* RV_MON_TYPE */
--
2.51.0
Powered by blists - more mailing lists