lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ