From nobody Mon Feb 9 15:26:55 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 760F5218580 for ; Fri, 16 Jan 2026 12:39:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768567179; cv=none; b=dW6H2h/SmIwvCVGdOcpuOthH5Ns0b2KOdIz1jotrKlpxcsvq4j/ac4KV6/Fe8LCsqExVu4sy29DRA2WPuNFmzrzQ0Gp3/AvW+2Rsk/sdmL4KZGQ+oUVNc2xttnINInmI67Vqq/QySzWR8Ky/LvPu8YUhO3R5UhgwR/HwmodmXuo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768567179; c=relaxed/simple; bh=s3ADJtY0+yGWnX7tpu+Kt1x8FPfpJO5oWp5MsYQGCG4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R8UG8r9Yp/kqunmHBB+cE6Ceysdfr46yPN3gAWQ4g3gTf8IpCJZxszt0uFMcvjrDPSEabUWUp3H+W1Ogri9fsm0KvfZdr2dF5dc6U4T+fMN6rb2y+HRIX+ydJFr75zD9zVG5tBUHd1Ceubfrklo0GM93A+brO+NOAMbq9GcUYDs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=gX+zr1xY; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="gX+zr1xY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768567176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D+LjyiQb9hCJJQqNBdbvANbfbGtWkhWvx0xT/kBtlCM=; b=gX+zr1xYCDSOW+9CdoVON9DXMsIOQ/LXQ9tkfIx1Ar/R8+nwKRNU+lGzR9E0Uv29itBR2Z l//trZeWqq2cgKCsn4BsBLGuof5hdw4rU2u6WWyWUTxkWTSX/MbfZk/LCDzE82P4UIm4Cd lXQ3yyuHWF/0Ebt9gITIDVhdd8dfNus= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-eJNmYfLxMz6pKZ9z-Ok6oQ-1; Fri, 16 Jan 2026 07:39:32 -0500 X-MC-Unique: eJNmYfLxMz6pKZ9z-Ok6oQ-1 X-Mimecast-MFC-AGG-ID: eJNmYfLxMz6pKZ9z-Ok6oQ_1768567171 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 558E1195609F; Fri, 16 Jan 2026 12:39:31 +0000 (UTC) Received: from gmonaco-thinkpadt14gen3.rmtit.csb (unknown [10.45.224.42]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CF3F11955F22; Fri, 16 Jan 2026 12:39:27 +0000 (UTC) From: Gabriele Monaco To: linux-kernel@vger.kernel.org, Steven Rostedt , Nam Cao , Juri Lelli , Gabriele Monaco , linux-trace-kernel@vger.kernel.org Cc: Tomas Glozar , Clark Williams , John Kacur Subject: [PATCH v4 01/15] rv: Unify DA event handling functions across monitor types Date: Fri, 16 Jan 2026 13:38:57 +0100 Message-ID: <20260116123911.130300-2-gmonaco@redhat.com> In-Reply-To: <20260116123911.130300-1-gmonaco@redhat.com> References: <20260116123911.130300-1-gmonaco@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" The DA event handling functions are mostly duplicated because the per-task monitors need to propagate the task struct while others do not. Unify the functions, handle the difference by always passing an identifier which is the task's pid for per-task monitors but is ignored for the other types. Only keep the actual tracepoint calling separated. Reviewed-by: Nam Cao Signed-off-by: Gabriele Monaco --- Notes: V3: * Rearrange start/handle helpers to share more code include/rv/da_monitor.h | 303 +++++++++++++++++----------------------- 1 file changed, 132 insertions(+), 171 deletions(-) diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h index 7b28ef9f73bd..6b564fad8c4d 100644 --- a/include/rv/da_monitor.h +++ b/include/rv/da_monitor.h @@ -22,6 +22,13 @@ =20 static struct rv_monitor rv_this; =20 +/* + * Type for the target id, default to int but can be overridden. + */ +#ifndef da_id_type +#define da_id_type int +#endif + static void react(enum states curr_state, enum events event) { rv_react(&rv_this, @@ -91,90 +98,6 @@ static inline bool da_monitor_handling_event(struct da_m= onitor *da_mon) return 1; } =20 -#if RV_MON_TYPE =3D=3D RV_MON_GLOBAL || RV_MON_TYPE =3D=3D 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. Exampl= es - * of implicit monitor are the per_cpu or the global ones. - * - * Retry in case there is a race between getting and setting the next stat= e, - * warn and reset the monitor if it runs out of retries. The monitor shoul= d 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 =3D READ_ONCE(da_mon->curr_state); - for (int i =3D 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { - next_state =3D model_get_next_state(curr_state, event); - if (next_state =3D=3D INVALID_STATE) { - 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(ev= ent)); - 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 =3D=3D RV_MON_PER_TASK -/* - * Event handler for per_task monitors. - * - * Retry in case there is a race between getting and setting the next stat= e, - * warn and reset the monitor if it runs out of retries. The monitor shoul= d 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 =3D READ_ONCE(da_mon->curr_state); - for (int i =3D 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { - next_state =3D model_get_next_state(curr_state, event); - if (next_state =3D=3D INVALID_STATE) { - 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(ev= ent)); - 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 =3D=3D RV_MON_GLOBAL /* * Functions to define, init and get a global monitor. @@ -329,115 +252,179 @@ static inline void da_monitor_destroy(void) =20 #if RV_MON_TYPE =3D=3D RV_MON_GLOBAL || RV_MON_TYPE =3D=3D 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 t= he + * handler does not need to specify which da_monitor to manipulate. Exampl= es + * of implicit monitor are the per_cpu or the global ones. */ =20 -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) { - bool retval; + CONCATENATE(trace_event_, MONITOR_NAME)(curr_state, event, next_state, + is_final); +} =20 - retval =3D da_event(da_mon, event); - if (!retval) - da_monitor_reset(da_mon); +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); } =20 +#elif RV_MON_TYPE =3D=3D RV_MON_PER_TASK /* - * da_handle_event - handle an event + * Trace events for per_task monitors, report the PID of the task. */ -static inline void da_handle_event(enum events event) -{ - struct da_monitor *da_mon =3D da_get_monitor(); - bool retval; =20 - retval =3D da_monitor_handling_event(da_mon); - if (!retval) - return; +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); +} =20 - __da_handle_event(da_mon, event); +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 */ =20 /* - * da_handle_start_event - start monitoring or handle event - * - * This function is used to notify the monitor that the system is returning - * to the initial state, so the monitor can start monitoring in the next e= vent. - * Thus: + * da_event - handle an event for the da_mon * - * If the monitor already started, handle the event. - * If the monitor did not start yet, start the monitor but skip the event. + * This function is valid for both implicit and id monitors. + * Retry in case there is a race between getting and setting the next stat= e, + * warn and reset the monitor if it runs out of retries. The monitor shoul= d be + * able to handle various orders. */ -static inline bool da_handle_start_event(enum events event) +static inline bool da_event(struct da_monitor *da_mon, enum events event, = da_id_type id) { - struct da_monitor *da_mon; + enum states curr_state, next_state; =20 - if (!da_monitor_enabled()) - return 0; + curr_state =3D READ_ONCE(da_mon->curr_state); + for (int i =3D 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { + next_state =3D model_get_next_state(curr_state, event); + if (next_state =3D=3D INVALID_STATE) { + 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(ev= ent)); + 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; +} =20 - da_mon =3D da_get_monitor(); +static inline void __da_handle_event_common(struct da_monitor *da_mon, + enum events event, da_id_type id) +{ + if (!da_event(da_mon, event, id)) + da_monitor_reset(da_mon); +} =20 +static inline void __da_handle_event(struct da_monitor *da_mon, + enum events event, da_id_type id) +{ + if (da_monitor_handling_event(da_mon)) + __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 (!da_monitor_enabled()) + return 0; if (unlikely(!da_monitoring(da_mon))) { da_monitor_start(da_mon); return 0; } =20 - __da_handle_event(da_mon, event); + __da_handle_event_common(da_mon, event, id); =20 return 1; } =20 -/* - * da_handle_start_run_event - start monitoring and handle event - * - * This function is used to notify the monitor that the system is in the - * initial state, so the monitor can start monitoring and handling event. - */ -static inline bool da_handle_start_run_event(enum events event) +static inline bool __da_handle_start_run_event(struct da_monitor *da_mon, + enum events event, da_id_type id) { - struct da_monitor *da_mon; - if (!da_monitor_enabled()) return 0; - - da_mon =3D da_get_monitor(); - if (unlikely(!da_monitoring(da_mon))) da_monitor_start(da_mon); =20 - __da_handle_event(da_mon, event); + __da_handle_event_common(da_mon, event, id); =20 return 1; } =20 -#elif RV_MON_TYPE =3D=3D RV_MON_PER_TASK +#if RV_MON_TYPE =3D=3D RV_MON_GLOBAL || RV_MON_TYPE =3D=3D RV_MON_PER_CPU /* - * Handle event for per task. + * Handle event for implicit monitor: da_get_monitor() will figure out + * the monitor. */ =20 -static inline void __da_handle_event(struct da_monitor *da_mon, - struct task_struct *tsk, enum events event) +/* + * da_handle_event - handle an event + */ +static inline void da_handle_event(enum events event) { - bool retval; + __da_handle_event(da_get_monitor(), event, 0); +} =20 - retval =3D da_event(da_mon, tsk, event); - if (!retval) - da_monitor_reset(da_mon); +/* + * da_handle_start_event - start monitoring or handle event + * + * This function is used to notify the monitor that the system is returning + * to the initial state, so the monitor can start monitoring in the next e= vent. + * Thus: + * + * If the monitor already started, handle the event. + * If the monitor did not start yet, start the monitor but skip the event. + */ +static inline bool da_handle_start_event(enum events event) +{ + return __da_handle_start_event(da_get_monitor(), event, 0); } =20 /* - * da_handle_event - handle an event + * da_handle_start_run_event - start monitoring and handle event + * + * This function is used to notify the monitor that the system is in the + * initial state, so the monitor can start monitoring and handling event. */ -static inline void da_handle_event(struct task_struct *tsk, enum events ev= ent) +static inline bool da_handle_start_run_event(enum events event) { - struct da_monitor *da_mon =3D da_get_monitor(tsk); - bool retval; + return __da_handle_start_run_event(da_get_monitor(), event, 0); +} =20 - retval =3D da_monitor_handling_event(da_mon); - if (!retval) - return; +#elif RV_MON_TYPE =3D=3D RV_MON_PER_TASK +/* + * Handle event for per task. + */ =20 - __da_handle_event(da_mon, tsk, event); +/* + * da_handle_event - handle an event + */ +static inline void da_handle_event(struct task_struct *tsk, enum events ev= ent) +{ + __da_handle_event(da_get_monitor(tsk), event, tsk->pid); } =20 /* @@ -453,21 +440,7 @@ 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 =3D 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); } =20 /* @@ -479,19 +452,7 @@ static inline bool da_handle_start_event(struct task_s= truct *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 =3D 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 */ =20 --=20 2.52.0