From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 F09A123FC52; Wed, 9 Jul 2025 19:21:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; cv=none; b=Zqu7lMOmxO2+xjI5STOBWCCyLRuNJO9GqH7+KUqPcGeTaJ00ifaHRk7tcWbwuFh37aLfCWwpboPjsK7SGFHk+ah8Du6PbYr3zlgZ+3A/mTLe4IKVpHstf+Ut1mbADc7AK+Rgjl31IXf0j+IGoKBCuGwpeSgXsoPIPNV+2oCDL0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; c=relaxed/simple; bh=9REGFnfyFOEyIjAE1cjJKsPFnrPKw4O7e9wg4waN3vU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jIpZfubw726fzwaEDQ6jByatfHUvfaKgz8xprgOqv4V71DTGOsq91h1XQfzffJHhJ+CCiw3/UkH9DxSe7LImqHksh5dTjRv2LQ4uurJm3ManAOmXUvQKfGjm19ind4KPw9qDc1HYLhp7EMKYH/WL0+j+c1jAyGK4achVx/B1xG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=I+/yQgGg; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=tHOrg51K; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="I+/yQgGg"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="tHOrg51K" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088902; 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=9REGFnfyFOEyIjAE1cjJKsPFnrPKw4O7e9wg4waN3vU=; b=I+/yQgGg1309dec53ELluYJGR5+YoopHs8xy0tOk1zG0IlqoQKw8GZ5nCOm1FEqYAItv+A pWJeCNrxLG/ptFIywqJan0Ux7EFl23v37w8QQEc7PIa8p5O0mRJnG9GADchH9tJ1rUQcm6 wiJvWqHhMf/tGLzfAUfFRO9gOffPXig/QqtkmQe24XeNfbdYPGRXAvGCoCUzovJF4tAcSl loS5DM2creW//2pasbwQG1C2rvNaO6BsHay3Fk01w7K8maf9ecnkgOHZwu1ep+v98V2n1m Xpujz1L2lz/PMa9QqeQAGzaKEnoe1CmabRqVeag6mIE+A9OQojvqtZaoUAXbDw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088902; 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=9REGFnfyFOEyIjAE1cjJKsPFnrPKw4O7e9wg4waN3vU=; b=tHOrg51KJSU1Nq/NXlHoWyPwoHpEGRk3fRHYoGcCBeYmivIVJasWx8PtAk/J14yV2rAnlv QwFuIbYNOU+raMBw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 01/12] rv: Add #undef TRACE_INCLUDE_FILE Date: Wed, 9 Jul 2025 21:21:12 +0200 Message-Id: In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Without "#undef TRACE_INCLUDE_FILE", there could be a build error due to TRACE_INCLUDE_FILE being redefined. Therefore add it. Also fix a typo while at it. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- kernel/trace/rv/rv_trace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/rv/rv_trace.h b/kernel/trace/rv/rv_trace.h index 422b75f58891..99c3801616d4 100644 --- a/kernel/trace/rv/rv_trace.h +++ b/kernel/trace/rv/rv_trace.h @@ -129,8 +129,9 @@ DECLARE_EVENT_CLASS(error_da_monitor_id, #endif /* CONFIG_DA_MON_EVENTS_ID */ #endif /* _TRACE_RV_H */ =20 -/* This part ust be outside protection */ +/* This part must be outside protection */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE rv_trace #include --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 F09F823FC66; Wed, 9 Jul 2025 19:21:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; cv=none; b=PJ86eo6WEUohf8p8j6m99mKbz3bA3PYQnwcej9otycDHAs+Fp5BFlJcgJ+he+RGqyLMNL3PAcRZ6CwSWYjziUKUXwQoHVTt/aA4yKmF1zsmkCAU/x6LkwDmPywvqIrIA095OWsfHJLJybSIJo7qp2VoY4pmY0naNSQDRt0BYafk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; c=relaxed/simple; bh=uUCFxmo45gH4FNKoJkFKyvfUrVp0TDpC9KtK9KK+nbQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=X/3NFZLTkbbJkAebcLS4qD8s/BsPObr6Q+3onxCPl1DxKzrwlY/UNoykmJm1fB7lYAUQVf21BUI0bpEYk/scJ9ySgA6uCgGol04PmpM3jPjVeZ5nosVIqfqrLeLNj9GdIUL6C/4MHALlaWFG7f2Y+VTFnuuI9hcRm6RjLi2SR2w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=KkafzTSe; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=DKX/Ih0l; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="KkafzTSe"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="DKX/Ih0l" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088902; 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=Cz7kLMF6V+pL7G20nftlZK+3bi9npXI9tcPWSQmYOx4=; b=KkafzTSeatKZVOSg4UCMmksRfod0BCo8vmKjqYJAcVX9bvjSH6MxHI1JsB5KXlczHTCGfW U7EbfclaH8fjhNXLA76EEp4pQjcKCbU8r7WxpTcQuD9tR9W8sYZO+TettXd2mGCn/Dz5qy fw4pq+ycWIinM8htp20gKVuAH98tbkyZYO9m69BBa5vCpn5igyE1WXMbo0Qk+MUaJo2WC2 cjkTDMAqGf5zAH93xPbl7Rz8QlnwFQJ6UxYjIpfk0jEdn3SjqP3QeYL4V/j/SV9dqLvzmy yA7ZZ3iRSXwAtB1FvdFyXXnGeaLILFSzxz7H680RlkywBQinYX7diGquKaCdow== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088902; 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=Cz7kLMF6V+pL7G20nftlZK+3bi9npXI9tcPWSQmYOx4=; b=DKX/Ih0l9mfXAa8HRwt5rcHmyOK79b6swFUe5U+k34vIv8QqShjRIZS64pZdZBswAmvYJK KfTfevAiBa4QF1Dw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao , Petr Mladek , Sergey Senozhatsky Subject: [PATCH v13 02/12] printk: Make vprintk_deferred() public Date: Wed, 9 Jul 2025 21:21:13 +0200 Message-Id: <66086aa267f2f3b431ff46dba1e7092030fcfe58.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" vprintk_deferred() is useful for implementing runtime verification reactors. Make it public. Signed-off-by: Nam Cao Reviewed-by: Petr Mladek --- Cc: John Ogness Cc: Sergey Senozhatsky --- v13: keep consistent format and put __printf(1, 0) in another line --- include/linux/printk.h | 7 +++++++ kernel/printk/internal.h | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index 5b462029d03c..5d22b803f51e 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -154,6 +154,8 @@ int vprintk_emit(int facility, int level, =20 asmlinkage __printf(1, 0) int vprintk(const char *fmt, va_list args); +__printf(1, 0) +int vprintk_deferred(const char *fmt, va_list args); =20 asmlinkage __printf(1, 2) __cold int _printk(const char *fmt, ...); @@ -214,6 +216,11 @@ int vprintk(const char *s, va_list args) { return 0; } +static inline __printf(1, 0) +int vprintk_deferred(const char *fmt, va_list args) +{ + return 0; +} static inline __printf(1, 2) __cold int _printk(const char *s, ...) { diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 48a24e7b309d..bbed41ad29cf 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -72,7 +72,6 @@ int vprintk_store(int facility, int level, const char *fmt, va_list args); =20 __printf(1, 0) int vprintk_default(const char *fmt, va_list args); -__printf(1, 0) int vprintk_deferred(const char *fmt, va_list args); =20 void __printk_safe_enter(void); void __printk_safe_exit(void); --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 0B70D23B63F; Wed, 9 Jul 2025 19:21:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; cv=none; b=ksxoBNFqSaRWI3l/OutXVasKHq/CyrLwfeR6W4XlAhU9XHILJeTFTZq+ip1H1qgNjDzoN41dXMy53ghHjJmT5HkVJhW9gH7h70ovWgCjvhkX9Qox4ld1AO4JajZtfIAnjHDjFk+S82K8ueoRBu3uQerHgU72lgGgG56F2592S6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088906; c=relaxed/simple; bh=2IXfDh1oS1h6wWEMQZiEwy1hIKMEajle4bNe7OQluPA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=blsW+BkDa8XZFtpiCv7bfeeRyYg+z/I+fj7O5Z+CEfERr/FgMtGz/3pDGF/l80JXwMZjKBKsCjCzw3JMcJihX6Rg2kj4AIOgyohXUNk519KCrc3zDwukRrjrdZJP07UVlEECqhSbO5hUX1pWh1CDLJXiolIa3QpfJRFG3VJrQWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=IsOff8sJ; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=E/Sv1EgY; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="IsOff8sJ"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="E/Sv1EgY" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088903; 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=BWqBXMYBmwEqdQKIVhrED21UDRTdi5qDQ7ZTDhJVn3E=; b=IsOff8sJfVgVzHZU42AKNwOOq1rQpNX8zX2bdvQu+4TBqAbr5f5xqlDgK1W424Nu18G3Mv IU73OfSB4yNcG9V4O04W7lTw10XiOrEFhSBxRebJDf/QhQJJIUt7m1mwHBiCU6c9apwAqf YvJ8Cr5nMBvuoLqYyKDnt1NLx/rS5SD5ElhItPVxpz6qTKlok9H20eAoptkBpxD+7+GygH Jhcez21WqP95fMLsvXqijcgIB816ssllf5SKKKIrv9xhbHHHS/Qcdj+OiQrGz5/B0uq7Nv ubskyfO/ra2lx94QOXcxRw7IJk/GKLXqcWt77ZYvWkSkf9H6iu2Uxw32JaCdoA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088903; 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=BWqBXMYBmwEqdQKIVhrED21UDRTdi5qDQ7ZTDhJVn3E=; b=E/Sv1EgYSFMcFA4A9oaXSEEAuZYH/iWKRWk9WBjyKPR+C2N8OCwfxPLzyWKRoakr0v4NuK 5yrObGB8wFXcR9BA== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao , Petr Mladek , Sergey Senozhatsky Subject: [PATCH v13 03/12] panic: Add vpanic() Date: Wed, 9 Jul 2025 21:21:14 +0200 Message-Id: <30ecde56bb120d1bface8da41238772439e9fbd3.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" vpanic() is useful for implementing runtime verification reactors. Add it. Signed-off-by: Nam Cao Reviewed-by: Petr Mladek --- Cc: John Ogness Cc: Sergey Senozhatsky --- include/linux/panic.h | 3 +++ kernel/panic.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/panic.h b/include/linux/panic.h index 4adc65766935..0332c6d6771f 100644 --- a/include/linux/panic.h +++ b/include/linux/panic.h @@ -3,6 +3,7 @@ #define _LINUX_PANIC_H =20 #include +#include #include =20 struct pt_regs; @@ -10,6 +11,8 @@ struct pt_regs; extern long (*panic_blink)(int state); __printf(1, 2) void panic(const char *fmt, ...) __noreturn __cold; +__printf(1, 0) +void vpanic(const char *fmt, va_list args) __noreturn __cold; void nmi_panic(struct pt_regs *regs, const char *msg); void check_panic_on_warn(const char *origin); extern void oops_enter(void); diff --git a/kernel/panic.c b/kernel/panic.c index b0b9a8bf4560..6a1823c383d0 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -309,13 +309,13 @@ static void panic_other_cpus_shutdown(bool crash_kexe= c) /** * panic - halt the system * @fmt: The text string to print + * @args: Arguments for the format string * * Display a message, then perform cleanups. This function never returns. */ -void panic(const char *fmt, ...) +void vpanic(const char *fmt, va_list args) { static char buf[1024]; - va_list args; long i, i_next =3D 0, len; int state =3D 0; int old_cpu, this_cpu; @@ -366,9 +366,7 @@ void panic(const char *fmt, ...) =20 console_verbose(); bust_spinlocks(1); - va_start(args, fmt); len =3D vscnprintf(buf, sizeof(buf), fmt, args); - va_end(args); =20 if (len && buf[len - 1] =3D=3D '\n') buf[len - 1] =3D '\0'; @@ -505,7 +503,17 @@ void panic(const char *fmt, ...) mdelay(PANIC_TIMER_STEP); } } +EXPORT_SYMBOL(vpanic); =20 +/* Identical to vpanic(), except it takes variadic arguments instead of va= _list */ +void panic(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vpanic(fmt, args); + va_end(args); +} EXPORT_SYMBOL(panic); =20 #define TAINT_FLAG(taint, _c_true, _c_false, _module) \ --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 7A06523FC7D; Wed, 9 Jul 2025 19:21:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; cv=none; b=JcuElA3uLyxZeTkdIcFkh4+llGoNH/qlkVl9GidiD6lxJ4JSwsEq03AwqGj0sbswFap1aCu1O5W4DX2mfPYblUYM9GjSyNmES0E/dwzjujfNeVjcfgCQMCjhhMmgZl3X6BfabdKSTrc6xu6fUXaROJmWyW7Bprd2rLpFAMRPTdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; c=relaxed/simple; bh=wn2eJuS+zEx8XuEUjHUhCIJA/y0N3h9PIoDYfiC14KY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IkqMLJDi1/UrbNcOqPnUWQ6+uodYrpbEHrsuLQcDgOKXruDydLJW9USTKUE77DYNvFoU21tyXUPc/zij4QZuaPdSoOhQMGW+XGRFzRMJDO4ngV9ERmWJAtATXfk4w5Q73CcYMuZxRvEpga/z8lsBvEpYBq13qRL8M8QyqeS3oKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=pozCRbxE; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NW1VlUeR; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="pozCRbxE"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NW1VlUeR" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088903; 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=X6K97kNqS9iVwLaZLV56vbzJZXc6QFuHBHlvLvdFEbg=; b=pozCRbxEDKgqgk5WJ/OmvMCBPiSpezn8rxYnITh9Ifl5+MibJWXREyUmhmT7Xgl+ar/a3c /9BA3GEO1yBeMVbXWHSIhzdPBfETe/VsJHM+8Nb5igkQu6Kdp199HmBIC/Qp62f2fM5IY4 FxN03Q/G76vcqb28vVIA9dlcgjnEuA1mK6OvEGG9iYfQ9sXFPzMyMygQjX3LaAOSSlX03L UmWvyAXGi8IfdtN9PCquTHixCe762TUrLrvk+DRzeVWT7hr0wJbKyjk8rnCmBNt5S9ieQK 5GkVRFVH28vdnx9YJgvrL4kEvopIjTNdjPViI2xFE9OqSD7sElZfK2EzjRSinw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088903; 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=X6K97kNqS9iVwLaZLV56vbzJZXc6QFuHBHlvLvdFEbg=; b=NW1VlUeRiZkDqMJ/HmlXsRXPP+bX7Ch1baqDSY9XEGVMgBiDb7kd0raIABV6sQAABWSOn5 UiyLddrnOBq+eVAA== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao , Petr Mladek , Sergey Senozhatsky Subject: [PATCH v13 04/12] rv: Let the reactors take care of buffers Date: Wed, 9 Jul 2025 21:21:15 +0200 Message-Id: <620a25d4b2e0f73701c4f255063b60c8d8feb7e7.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Each RV monitor has one static buffer to send to the reactors. If multiple errors are detected simultaneously, the one buffer could be overwritten. Instead, leave it to the reactors to handle buffering. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- Cc: Petr Mladek Cc: John Ogness Cc: Sergey Senozhatsky --- include/linux/rv.h | 9 +++++-- include/rv/da_monitor.h | 45 +++++++------------------------- kernel/trace/rv/reactor_panic.c | 8 ++++-- kernel/trace/rv/reactor_printk.c | 8 ++++-- kernel/trace/rv/rv_reactors.c | 2 +- 5 files changed, 30 insertions(+), 42 deletions(-) diff --git a/include/linux/rv.h b/include/linux/rv.h index 3452b5e4b29e..9428e62eb8e9 100644 --- a/include/linux/rv.h +++ b/include/linux/rv.h @@ -38,7 +38,7 @@ union rv_task_monitor { struct rv_reactor { const char *name; const char *description; - void (*react)(char *msg); + __printf(1, 2) void (*react)(const char *msg, ...); }; #endif =20 @@ -50,7 +50,7 @@ struct rv_monitor { void (*disable)(void); void (*reset)(void); #ifdef CONFIG_RV_REACTORS - void (*react)(char *msg); + __printf(1, 2) void (*react)(const char *msg, ...); #endif }; =20 @@ -64,6 +64,11 @@ void rv_put_task_monitor_slot(int slot); bool rv_reacting_on(void); int rv_unregister_reactor(struct rv_reactor *reactor); int rv_register_reactor(struct rv_reactor *reactor); +#else +static inline bool rv_reacting_on(void) +{ + return false; +} #endif /* CONFIG_RV_REACTORS */ =20 #endif /* CONFIG_RV */ diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h index 510c88bfabd4..15f9ed4e4bb6 100644 --- a/include/rv/da_monitor.h +++ b/include/rv/da_monitor.h @@ -19,45 +19,22 @@ #ifdef CONFIG_RV_REACTORS =20 #define DECLARE_RV_REACTING_HELPERS(name, type) \ -static char REACT_MSG_##name[1024]; \ - \ -static inline char *format_react_msg_##name(type curr_state, type event) = \ -{ \ - snprintf(REACT_MSG_##name, 1024, \ - "rv: monitor %s does not allow event %s on state %s\n", \ - #name, \ - model_get_event_name_##name(event), \ - model_get_state_name_##name(curr_state)); \ - return REACT_MSG_##name; \ -} \ - \ -static void cond_react_##name(char *msg) \ +static void cond_react_##name(type curr_state, type event) \ { \ - if (rv_##name.react) \ - rv_##name.react(msg); \ -} \ - \ -static bool rv_reacting_on_##name(void) \ -{ \ - return rv_reacting_on(); \ + if (!rv_reacting_on() || !rv_##name.react) \ + return; \ + rv_##name.react("rv: monitor %s does not allow event %s on state %s\n", = \ + #name, \ + model_get_event_name_##name(event), \ + model_get_state_name_##name(curr_state)); \ } =20 #else /* CONFIG_RV_REACTOR */ =20 #define DECLARE_RV_REACTING_HELPERS(name, type) \ -static inline char *format_react_msg_##name(type curr_state, type event) = \ -{ \ - return NULL; \ -} \ - \ -static void cond_react_##name(char *msg) \ +static void cond_react_##name(type curr_state, type event) \ { \ return; \ -} \ - \ -static bool rv_reacting_on_##name(void) \ -{ \ - return 0; \ } #endif =20 @@ -170,8 +147,7 @@ da_event_##name(struct da_monitor *da_mon, enum events_= ##name event) \ return true; \ } \ \ - if (rv_reacting_on_##name()) \ - cond_react_##name(format_react_msg_##name(curr_state, event)); \ + cond_react_##name(curr_state, event); \ \ trace_error_##name(model_get_state_name_##name(curr_state), \ model_get_event_name_##name(event)); \ @@ -202,8 +178,7 @@ static inline bool da_event_##name(struct da_monitor *d= a_mon, struct task_struct return true; \ } \ \ - if (rv_reacting_on_##name()) \ - cond_react_##name(format_react_msg_##name(curr_state, event)); \ + cond_react_##name(curr_state, event); \ \ trace_error_##name(tsk->pid, \ model_get_state_name_##name(curr_state), \ diff --git a/kernel/trace/rv/reactor_panic.c b/kernel/trace/rv/reactor_pani= c.c index 0186ff4cbd0b..74c6bcc2c749 100644 --- a/kernel/trace/rv/reactor_panic.c +++ b/kernel/trace/rv/reactor_panic.c @@ -13,9 +13,13 @@ #include #include =20 -static void rv_panic_reaction(char *msg) +__printf(1, 2) static void rv_panic_reaction(const char *msg, ...) { - panic(msg); + va_list args; + + va_start(args, msg); + vpanic(msg, args); + va_end(args); } =20 static struct rv_reactor rv_panic =3D { diff --git a/kernel/trace/rv/reactor_printk.c b/kernel/trace/rv/reactor_pri= ntk.c index 178759dbf89f..2dae2916c05f 100644 --- a/kernel/trace/rv/reactor_printk.c +++ b/kernel/trace/rv/reactor_printk.c @@ -12,9 +12,13 @@ #include #include =20 -static void rv_printk_reaction(char *msg) +__printf(1, 2) static void rv_printk_reaction(const char *msg, ...) { - printk_deferred(msg); + va_list args; + + va_start(args, msg); + vprintk_deferred(msg, args); + va_end(args); } =20 static struct rv_reactor rv_printk =3D { diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index 9501ca886d83..740603670dd1 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -490,7 +490,7 @@ void reactor_cleanup_monitor(struct rv_monitor_def *mde= f) /* * Nop reactor register */ -static void rv_nop_reaction(char *msg) +__printf(1, 2) static void rv_nop_reaction(const char *msg, ...) { } =20 --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 7A13624292E; Wed, 9 Jul 2025 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; cv=none; b=UDCZ9C4kn91nHfG7tPTuPBskH6A/eYXY+w1OG7m3/goEFkhgLV+PplXbDgdeDlKplWeumaV1ZcAZnE5Bhv7lVFHohCSQPCbYQmjsQsdvhPIrvB1QHJoUm0Y5AYsWW5GGQWVRQfYlBDXCn0Ace8TyEz++0Fbe9mYVsEHSvKrCjMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; c=relaxed/simple; bh=MRg+w2iH0HGF5UyuFu3lFXx9krIj2AUo3GAFy7nbrK8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nIU4cetPKtfc6S1T9Fce8R3vmAsXV3/kz6E+XGtfqWQX8CAPzegrZaKDylibK0lCq6dwCGvI+pVm9egq6AmfUVnn1J6KPblGjf1fl7QnUFhBAWvQvbYvjTtvBYY+CvEoUhujG2HqaE7M8XlderjYXNdtsxJ3BphDZrrjLFT+DZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=VNS7+a0o; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=x9rSmtZo; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="VNS7+a0o"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="x9rSmtZo" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088904; 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=wd36I9Oi5n/Lmp8CkDPUxkaX/ZJRiNSgqZM9aUNzkIY=; b=VNS7+a0onmi/twVypPL3RE6lFGRA959YsP+dSE93gCU3E8blY4fGEU7UKjHrWfGMPWNp5g FCT6af34QSnEUwe0PjvcTAKnOGOeQ+aZgy5e1doVCkKOYLWFRoKTbf9KYL908i6NEta0aQ MGZE3tbnBh6dsBYQJGYt5ICTVH56UCijF9Z1z8/yFyvf2HGksvKTH9/CPps/ohaiiHbYiN vrWrPpxo7IuTEmvgOwIDaD2iIhKnzIYkY39UFI6HnnVqy6JXp9XjBVxe4O33ZWZTluiRjQ 2PPudeiXzN9faua8zs6daRxao3ItdpVfHEwo1dc/pi1zQn7vYdLS6EB8w18D1Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088904; 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=wd36I9Oi5n/Lmp8CkDPUxkaX/ZJRiNSgqZM9aUNzkIY=; b=x9rSmtZoLSVe4VmQ5x9EVq7rmWxw0Ih0y+nvgvRgmpZ4ANC5psLlci2kYGJIt2UJwXBsty Uad0ZN3QCFIevqBw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 05/12] rv: rename CONFIG_DA_MON_EVENTS to CONFIG_RV_MON_EVENTS Date: Wed, 9 Jul 2025 21:21:16 +0200 Message-Id: <507210517123d887c1d208aa2fd45ec69765d3f0.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" CONFIG_DA_MON_EVENTS is not specific to deterministic automaton. It could be used for other monitor types. Therefore rename it to CONFIG_RV_MON_EVENTS. This prepares for the introduction of linear temporal logic monitor. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- kernel/trace/rv/Kconfig | 6 +++--- kernel/trace/rv/rv.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index b39f36013ef2..6cdffc04b73c 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -1,14 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-only # -config DA_MON_EVENTS +config RV_MON_EVENTS bool =20 config DA_MON_EVENTS_IMPLICIT - select DA_MON_EVENTS + select RV_MON_EVENTS bool =20 config DA_MON_EVENTS_ID - select DA_MON_EVENTS + select RV_MON_EVENTS bool =20 menuconfig RV diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c index e4077500a91d..e25d65fe432a 100644 --- a/kernel/trace/rv/rv.c +++ b/kernel/trace/rv/rv.c @@ -143,7 +143,7 @@ #include #include =20 -#ifdef CONFIG_DA_MON_EVENTS +#ifdef CONFIG_RV_MON_EVENTS #define CREATE_TRACE_POINTS #include #endif --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 7A0CD242925; Wed, 9 Jul 2025 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; cv=none; b=Da4s3QtIosCrp+ffxouD4IY6agqIu/Jl4IOVAY0mh1SCGd6J3g7K2Sk2FwxAgdTmyFc4KtGEmPAKQKlViz6qSxMxU9XTF/VY8TLNCmcazC4sW5oj6Y9Oj4ZSDG0U3M6i8Fd5eR10z37rCpFqhpzpHS0QKlybkK+Gpis72KZRkAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; c=relaxed/simple; bh=t966SBTRSkTazpO3zLrg8iJK79jVq7Q8fs/VhLQsRwc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=d7E9Md8JU8jEUKvVVZcrDh480wsGO4JAR1AcXtQStEWfTClds2UPT2hv/E61JHY6D8R/G5iL3wfbyXa+cUK0q4z8uLZ/vrQpRX5UbnZeOOIh6ohpA0BIet6mXlgCYUG3jzaaAF9X3N+j9SPdI1uI1NAjFICHh05oumBvgownmxQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=BfJhuED9; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1223+vl6; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="BfJhuED9"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1223+vl6" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088904; 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=v+8V91KjOkCp/pfQj+U3LLLv35Icg6E4+KOLEJJ0DqE=; b=BfJhuED9pfU2u3Dfkwa/2jry1zxkdCNXJIH+CXrlgozLGpIiiglsUEHf7NOOVhp6H/asW1 pmNp+kBIBJgiNTM6p/lFPbvxBQqD+I6ILMX6bOu8HP3kjuunZMYh/Z/1MPRhmABOlihtE1 mr3e56rNkJjPneTDpp4EON+I9CpBHx5DUr7RzksxLv3avnI4Lf8BCQ8qhXiLavub53BjMA pu8ObAE4+06ZmuuVTzgnerC5L218CAGaDgznSyeRgWp3uK+zQCCGBGR06a/DmjjOQfAqjO mnBh/WzLUpb6AGvC9Dt8J1ZoVW00QVchIqiAvq7fuDRTPU9ykq+5QFFNFERunw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088904; 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=v+8V91KjOkCp/pfQj+U3LLLv35Icg6E4+KOLEJJ0DqE=; b=1223+vl6rVNnQefQX5kwnHnvNY6rC3HRG5xWywuQ6WO2RkfNS6S23rV7+KwxhQVOfe1U7w xqAeJOvLGQEvDYCw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 06/12] rv: Add support for LTL monitors Date: Wed, 9 Jul 2025 21:21:17 +0200 Message-Id: In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" While attempting to implement DA monitors for some complex specifications, deterministic automaton is found to be inappropriate as the specification language. The automaton is complicated, hard to understand, and error-prone. For these cases, linear temporal logic is more suitable as the specification language. Add support for linear temporal logic runtime verification monitor. Signed-off-by: Nam Cao --- include/linux/rv.h | 63 ++++++++++++- include/rv/ltl_monitor.h | 184 +++++++++++++++++++++++++++++++++++++ kernel/fork.c | 5 +- kernel/trace/rv/Kconfig | 7 ++ kernel/trace/rv/rv_trace.h | 47 ++++++++++ 5 files changed, 298 insertions(+), 8 deletions(-) create mode 100644 include/rv/ltl_monitor.h diff --git a/include/linux/rv.h b/include/linux/rv.h index 9428e62eb8e9..1d5579f9b75a 100644 --- a/include/linux/rv.h +++ b/include/linux/rv.h @@ -10,6 +10,10 @@ #define MAX_DA_NAME_LEN 32 =20 #ifdef CONFIG_RV +#include +#include +#include + /* * Deterministic automaton per-object variables. */ @@ -18,6 +22,59 @@ struct da_monitor { unsigned int curr_state; }; =20 +#ifdef CONFIG_RV_LTL_MONITOR + +/* + * In the future, if the number of atomic propositions or the size of Buchi + * automaton is larger, we can switch to dynamic allocation. For now, the = code + * is simpler this way. + */ +#define RV_MAX_LTL_ATOM 32 +#define RV_MAX_BA_STATES 32 + +/** + * struct ltl_monitor - A linear temporal logic runtime verification monit= or + * @states: States in the Buchi automaton. As Buchi automaton is a + * non-deterministic state machine, the monitor can be in multiple + * states simultaneously. This is a bitmask of all possible states. + * If this is zero, that means either: + * - The monitor has not started yet (e.g. because not all + * atomic propositions are known). + * - There is no possible state to be in. In other words, a + * violation of the LTL property is detected. + * @atoms: The values of atomic propositions. + * @unknown_atoms: Atomic propositions which are still unknown. + */ +struct ltl_monitor { + DECLARE_BITMAP(states, RV_MAX_BA_STATES); + DECLARE_BITMAP(atoms, RV_MAX_LTL_ATOM); + DECLARE_BITMAP(unknown_atoms, RV_MAX_LTL_ATOM); +}; + +static inline bool rv_ltl_valid_state(struct ltl_monitor *mon) +{ + for (int i =3D 0; i < ARRAY_SIZE(mon->states); ++i) { + if (mon->states[i]) + return true; + } + return false; +} + +static inline bool rv_ltl_all_atoms_known(struct ltl_monitor *mon) +{ + for (int i =3D 0; i < ARRAY_SIZE(mon->unknown_atoms); ++i) { + if (mon->unknown_atoms[i]) + return false; + } + return true; +} + +#else + +struct ltl_monitor {}; + +#endif /* CONFIG_RV_LTL_MONITOR */ + /* * Per-task RV monitors count. Nowadays fixed in RV_PER_TASK_MONITORS. * If we find justification for more monitors, we can think about @@ -27,11 +84,9 @@ struct da_monitor { #define RV_PER_TASK_MONITORS 1 #define RV_PER_TASK_MONITOR_INIT (RV_PER_TASK_MONITORS) =20 -/* - * Futher monitor types are expected, so make this a union. - */ union rv_task_monitor { - struct da_monitor da_mon; + struct da_monitor da_mon; + struct ltl_monitor ltl_mon; }; =20 #ifdef CONFIG_RV_REACTORS diff --git a/include/rv/ltl_monitor.h b/include/rv/ltl_monitor.h new file mode 100644 index 000000000000..9a583125b566 --- /dev/null +++ b/include/rv/ltl_monitor.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/** + * This file must be combined with the $(MODEL_NAME).h file generated by + * tools/verification/rvgen. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef MONITOR_NAME +#error "Please include $(MODEL_NAME).h generated by rvgen" +#endif + +#ifdef CONFIG_RV_REACTORS +#define RV_MONITOR_NAME CONCATENATE(rv_, MONITOR_NAME) +static struct rv_monitor RV_MONITOR_NAME; + +static void rv_cond_react(struct task_struct *task) +{ + if (!rv_reacting_on() || !RV_MONITOR_NAME.react) + return; + RV_MONITOR_NAME.react("rv: "__stringify(MONITOR_NAME)": %s[%d]: violation= detected\n", + task->comm, task->pid); +} +#else +static void rv_cond_react(struct task_struct *task) +{ +} +#endif + +static int ltl_monitor_slot =3D RV_PER_TASK_MONITOR_INIT; + +static void ltl_atoms_fetch(struct task_struct *task, struct ltl_monitor *= mon); +static void ltl_atoms_init(struct task_struct *task, struct ltl_monitor *m= on, bool task_creation); + +static struct ltl_monitor *ltl_get_monitor(struct task_struct *task) +{ + return &task->rv[ltl_monitor_slot].ltl_mon; +} + +static void ltl_task_init(struct task_struct *task, bool task_creation) +{ + struct ltl_monitor *mon =3D ltl_get_monitor(task); + + memset(&mon->states, 0, sizeof(mon->states)); + + for (int i =3D 0; i < LTL_NUM_ATOM; ++i) + __set_bit(i, mon->unknown_atoms); + + ltl_atoms_init(task, mon, task_creation); + ltl_atoms_fetch(task, mon); +} + +static void handle_task_newtask(void *data, struct task_struct *task, unsi= gned long flags) +{ + ltl_task_init(task, true); +} + +static int ltl_monitor_init(void) +{ + struct task_struct *g, *p; + int ret, cpu; + + ret =3D rv_get_task_monitor_slot(); + if (ret < 0) + return ret; + + ltl_monitor_slot =3D ret; + + rv_attach_trace_probe(name, task_newtask, handle_task_newtask); + + read_lock(&tasklist_lock); + + for_each_process_thread(g, p) + ltl_task_init(p, false); + + for_each_present_cpu(cpu) + ltl_task_init(idle_task(cpu), false); + + read_unlock(&tasklist_lock); + + return 0; +} + +static void ltl_monitor_destroy(void) +{ + rv_detach_trace_probe(name, task_newtask, handle_task_newtask); + + rv_put_task_monitor_slot(ltl_monitor_slot); + ltl_monitor_slot =3D RV_PER_TASK_MONITOR_INIT; +} + +static void ltl_illegal_state(struct task_struct *task, struct ltl_monitor= *mon) +{ + CONCATENATE(trace_error_, MONITOR_NAME)(task); + rv_cond_react(task); +} + +static void ltl_attempt_start(struct task_struct *task, struct ltl_monitor= *mon) +{ + if (rv_ltl_all_atoms_known(mon)) + ltl_start(task, mon); +} + +static inline void ltl_atom_set(struct ltl_monitor *mon, enum ltl_atom ato= m, bool value) +{ + __clear_bit(atom, mon->unknown_atoms); + if (value) + __set_bit(atom, mon->atoms); + else + __clear_bit(atom, mon->atoms); +} + +static void +ltl_trace_event(struct task_struct *task, struct ltl_monitor *mon, unsigne= d long *next_state) +{ + const char *format_str =3D "%s"; + DECLARE_SEQ_BUF(atoms, 64); + char states[32], next[32]; + int i; + + if (!CONCATENATE(CONCATENATE(trace_event_, MONITOR_NAME), _enabled)()) + return; + + snprintf(states, sizeof(states), "%*pbl", RV_MAX_BA_STATES, mon->states); + snprintf(next, sizeof(next), "%*pbl", RV_MAX_BA_STATES, next_state); + + for (i =3D 0; i < LTL_NUM_ATOM; ++i) { + if (test_bit(i, mon->atoms)) { + seq_buf_printf(&atoms, format_str, ltl_atom_str(i)); + format_str =3D ",%s"; + } + } + + CONCATENATE(trace_event_, MONITOR_NAME)(task, states, atoms.buffer, next); +} + +static void ltl_validate(struct task_struct *task, struct ltl_monitor *mon) +{ + DECLARE_BITMAP(next_states, RV_MAX_BA_STATES) =3D {0}; + + if (!rv_ltl_valid_state(mon)) + return; + + for (unsigned int i =3D 0; i < RV_NUM_BA_STATES; ++i) { + if (test_bit(i, mon->states)) + ltl_possible_next_states(mon, i, next_states); + } + + ltl_trace_event(task, mon, next_states); + + memcpy(mon->states, next_states, sizeof(next_states)); + + if (!rv_ltl_valid_state(mon)) + ltl_illegal_state(task, mon); +} + +static void ltl_atom_update(struct task_struct *task, enum ltl_atom atom, = bool value) +{ + struct ltl_monitor *mon =3D ltl_get_monitor(task); + + ltl_atom_set(mon, atom, value); + ltl_atoms_fetch(task, mon); + + if (!rv_ltl_valid_state(mon)) + ltl_attempt_start(task, mon); + + ltl_validate(task, mon); +} + +static void __maybe_unused ltl_atom_pulse(struct task_struct *task, enum l= tl_atom atom, bool value) +{ + struct ltl_monitor *mon =3D ltl_get_monitor(task); + + ltl_atom_update(task, atom, value); + + ltl_atom_set(mon, atom, !value); + ltl_validate(task, mon); +} diff --git a/kernel/fork.c b/kernel/fork.c index 1ee8eb11f38b..1f06559d17bf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1886,10 +1886,7 @@ static void copy_oom_score_adj(u64 clone_flags, stru= ct task_struct *tsk) #ifdef CONFIG_RV static void rv_task_fork(struct task_struct *p) { - int i; - - for (i =3D 0; i < RV_PER_TASK_MONITORS; i++) - p->rv[i].da_mon.monitoring =3D false; + memset(&p->rv, 0, sizeof(p->rv)); } #else #define rv_task_fork(p) do {} while (0) diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index 6cdffc04b73c..6e157f964991 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -11,6 +11,13 @@ config DA_MON_EVENTS_ID select RV_MON_EVENTS bool =20 +config LTL_MON_EVENTS_ID + select RV_MON_EVENTS + bool + +config RV_LTL_MONITOR + bool + menuconfig RV bool "Runtime Verification" depends on TRACING diff --git a/kernel/trace/rv/rv_trace.h b/kernel/trace/rv/rv_trace.h index 99c3801616d4..fd3111ad1d51 100644 --- a/kernel/trace/rv/rv_trace.h +++ b/kernel/trace/rv/rv_trace.h @@ -127,6 +127,53 @@ DECLARE_EVENT_CLASS(error_da_monitor_id, // Add new monitors based on CONFIG_DA_MON_EVENTS_ID here =20 #endif /* CONFIG_DA_MON_EVENTS_ID */ +#ifdef CONFIG_LTL_MON_EVENTS_ID +DECLARE_EVENT_CLASS(event_ltl_monitor_id, + + TP_PROTO(struct task_struct *task, char *states, char *atoms, char *next), + + TP_ARGS(task, states, atoms, next), + + TP_STRUCT__entry( + __string(comm, task->comm) + __field(pid_t, pid) + __string(states, states) + __string(atoms, atoms) + __string(next, next) + ), + + TP_fast_assign( + __assign_str(comm); + __entry->pid =3D task->pid; + __assign_str(states); + __assign_str(atoms); + __assign_str(next); + ), + + TP_printk("%s[%d]: (%s) x (%s) -> (%s)", __get_str(comm), __entry->pid, + __get_str(states), __get_str(atoms), __get_str(next)) +); + +DECLARE_EVENT_CLASS(error_ltl_monitor_id, + + TP_PROTO(struct task_struct *task), + + TP_ARGS(task), + + TP_STRUCT__entry( + __string(comm, task->comm) + __field(pid_t, pid) + ), + + TP_fast_assign( + __assign_str(comm); + __entry->pid =3D task->pid; + ), + + TP_printk("%s[%d]: violation detected", __get_str(comm), __entry->pid) +); +// Add new monitors based on CONFIG_LTL_MON_EVENTS_ID here +#endif /* CONFIG_LTL_MON_EVENTS_ID */ #endif /* _TRACE_RV_H */ =20 /* This part must be outside protection */ --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 DDF60242D76; Wed, 9 Jul 2025 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; cv=none; b=A/VUUd2kGePlagB7E5t/I5j8kcrsiViwr1bl24uV2a6HIMBDiiRHdUrJfPfj3zSFjGQwIAHvMqYNYgJ2rRdhubV9w9akM+nexiojbz3skun0egyHikb1IejcbOnQkMqOBUbtSGPGcQjjPsfBTFKNsU5Gt/vRwTCkcAJCZdmOOZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; c=relaxed/simple; bh=85/U39BHNtL7BqDwSk7MztK54qQamsoQh/UQWNU8dqI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=V6xkwX3eMBBdDCuujieDd0zqIGDsMHCykBfb8FBPu9pAv9wWKFjA7366Mes2Fvp+LrWjGxs+SYqmQCvr96SjTN3JRRqRKBHQFWrFZyWX1VmWhVh72eji9EiFBVYbfAJnSvmRcQOa55m7oL+pAM2PV2ZUuU+3PHJfO76qr0I4kPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0eoRKFRB; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=MC3wXHI+; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0eoRKFRB"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="MC3wXHI+" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088905; 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=5dQqqOzbNH8/khkeLA5QFd/dgTcqukCvnc+4mKvB/t8=; b=0eoRKFRBGulJ+4LMNTde7VNIcJs5uoZ09kUqozji/C6zrXV28DCe+RdoG2WBdPXVUXmnr1 aRvROFnOj05hMD2N2qCAszwTpAq3+K3mLZ/8TN6yqpZtwxdtFv52/EE8yJ+vxDNneJYoXt elYzK2vi0KGt/7tEcyUVuXKtkf9oGpzI4+UChvCnzPFHsHL+x5mljMo8Jah88TxkRudDQG CQDz6HnDg+EVxcotXJuQU7UY/HedacavUfujV/ki0zuqGVFZPcM9MpyeAn96lGjuMCDnMr d/8sjDXQwVoa9W8foFjHySY0kt4DyzoUdmpWAdiqjPuIfpb7oqBtEpg+4cBkNQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088905; 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=5dQqqOzbNH8/khkeLA5QFd/dgTcqukCvnc+4mKvB/t8=; b=MC3wXHI+7fy8rhqJRNEfweTWTXPCLRuarAr4wdl1gttDAzXeksXnqmamrqFGD73XwWQ2jw tELr3/hJXRzJb+Cw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 07/12] rv: Add rtapp container monitor Date: Wed, 9 Jul 2025 21:21:18 +0200 Message-Id: In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Add the container "rtapp" which is the monitor collection for detecting problems with real-time applications. The monitors will be added in the follow-up commits. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- kernel/trace/rv/Kconfig | 1 + kernel/trace/rv/Makefile | 1 + kernel/trace/rv/monitors/rtapp/Kconfig | 10 ++++++++ kernel/trace/rv/monitors/rtapp/rtapp.c | 33 ++++++++++++++++++++++++++ kernel/trace/rv/monitors/rtapp/rtapp.h | 3 +++ 5 files changed, 48 insertions(+) create mode 100644 kernel/trace/rv/monitors/rtapp/Kconfig create mode 100644 kernel/trace/rv/monitors/rtapp/rtapp.c create mode 100644 kernel/trace/rv/monitors/rtapp/rtapp.h diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index 6e157f964991..5c407d291661 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -41,6 +41,7 @@ source "kernel/trace/rv/monitors/snroc/Kconfig" source "kernel/trace/rv/monitors/scpd/Kconfig" source "kernel/trace/rv/monitors/snep/Kconfig" source "kernel/trace/rv/monitors/sncid/Kconfig" +source "kernel/trace/rv/monitors/rtapp/Kconfig" # Add new monitors here =20 config RV_REACTORS diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile index f9b2cd0483c3..9b28c2419995 100644 --- a/kernel/trace/rv/Makefile +++ b/kernel/trace/rv/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_RV_MON_SNROC) +=3D monitors/snroc/snroc.o obj-$(CONFIG_RV_MON_SCPD) +=3D monitors/scpd/scpd.o obj-$(CONFIG_RV_MON_SNEP) +=3D monitors/snep/snep.o obj-$(CONFIG_RV_MON_SNCID) +=3D monitors/sncid/sncid.o +obj-$(CONFIG_RV_MON_RTAPP) +=3D monitors/rtapp/rtapp.o # Add new monitors here obj-$(CONFIG_RV_REACTORS) +=3D rv_reactors.o obj-$(CONFIG_RV_REACT_PRINTK) +=3D reactor_printk.o diff --git a/kernel/trace/rv/monitors/rtapp/Kconfig b/kernel/trace/rv/monit= ors/rtapp/Kconfig new file mode 100644 index 000000000000..b7415c3570bb --- /dev/null +++ b/kernel/trace/rv/monitors/rtapp/Kconfig @@ -0,0 +1,10 @@ +config RV_MON_RTAPP + depends on RV + bool "rtapp monitor" + help + Collection of monitors to check for common problems with real-time + application that may cause unexpected latency. + + If you are developing a real-time system and not entirely sure whether + the applications are designed correctly for real-time, you want to say + Y here. diff --git a/kernel/trace/rv/monitors/rtapp/rtapp.c b/kernel/trace/rv/monit= ors/rtapp/rtapp.c new file mode 100644 index 000000000000..fd75fc927d65 --- /dev/null +++ b/kernel/trace/rv/monitors/rtapp/rtapp.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +#define MODULE_NAME "rtapp" + +#include "rtapp.h" + +struct rv_monitor rv_rtapp; + +struct rv_monitor rv_rtapp =3D { + .name =3D "rtapp", + .description =3D "Collection of monitors for detecting problems with real= -time applications", +}; + +static int __init register_rtapp(void) +{ + return rv_register_monitor(&rv_rtapp, NULL); +} + +static void __exit unregister_rtapp(void) +{ + rv_unregister_monitor(&rv_rtapp); +} + +module_init(register_rtapp); +module_exit(unregister_rtapp); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nam Cao "); +MODULE_DESCRIPTION("Collection of monitors for detecting problems with rea= l-time applications"); diff --git a/kernel/trace/rv/monitors/rtapp/rtapp.h b/kernel/trace/rv/monit= ors/rtapp/rtapp.h new file mode 100644 index 000000000000..4c200d67c7f6 --- /dev/null +++ b/kernel/trace/rv/monitors/rtapp/rtapp.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +extern struct rv_monitor rv_rtapp; --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 2405A242D89; Wed, 9 Jul 2025 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; cv=none; b=lxOqosXottYUYWgAMwWDqgtCI1J43qEYk/NKq6kEy5DsInK00+7MMoM0CbaegWk/63GT/KjI4tgU5LM+RWwmAxd38Q7QlAvzRgkuiVTW0d15cpotceURCXuoELgMgC8qzSel3rV2B3zeibfh4NmvG1cixG+akSYr/7qH2Nqshec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088909; c=relaxed/simple; bh=eX5oXC+HBcw1mu0TCAHq5i0a+I/QmsXUI8/vYm8odp4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bEzU7SDS3JFlgIE/Tw2JJwHqbvhsBKmo9g3rnlBAip+AtECXHKjyzX7ca3yUcKByaI/Ii3ekl2gRGLpcNKkxSGm12oEoMDni0Jg8cLcL3E/0gA+Qapq524183LOtvg/rJgRItvZDgR4KzDqhxsk4AVfPNqyI6ssK9emRRENVWhI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wa8z0sAu; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=TyMHXPJv; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wa8z0sAu"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="TyMHXPJv" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088905; 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=GRN84yAGCbJ9jXd7YMFr0fN4dU5tvyZpKeky5D5bT9k=; b=wa8z0sAuK1tiGbDfapoO96J/FGkwok40iUnS56I0IB64jgisRzbeikXEc1zqh4Oc0kwPmX brR8UwfHYy1wi1EbqV5d3vKZ0CTye/y1HM96qSqH9n52DRerNKgM62IJVNoIGmdYyFo6+p le93w1R7/BZ86gP+pSLbTfkBtgeZeFwJm15emhC+hsh4E0pzUF89/AJPYhzMHd1iz4NLvj 0xQdfut08GvXYwbe+p11xHbZLmiL6trAAlros8pfGYfmQ8JY/Dl14kJYU/Dm1rHrcRcsbP Jk+SyGCo+3A3kIbCRm+FVB9LXecMoZmmNo5kJTLMMWDCbd0n/wBqsh2d6T0uyw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088905; 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=GRN84yAGCbJ9jXd7YMFr0fN4dU5tvyZpKeky5D5bT9k=; b=TyMHXPJvN47f4ZgztQwm6plU2xf6yUgtDfxc+6KRAQOwhrs+Uov4WT3BdZxDaN4YQ1Sbex woLTrV73fwWuZPAw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao , Alexandre Ghiti , Paul Walmsley , Palmer Dabbelt , Albert Ou , linux-riscv@lists.infradead.org Subject: [PATCH v13 08/12] riscv: mm: Add page fault trace points Date: Wed, 9 Jul 2025 21:21:19 +0200 Message-Id: <4cf34e53b16dde872369bab76bb019685d262a9e.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Add page fault trace points, which are useful to implement RV monitor that watches page faults. Signed-off-by: Nam Cao Acked-by: Alexandre Ghiti --- Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: linux-riscv@lists.infradead.org --- arch/riscv/mm/fault.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index 0194324a0c50..04ed6f8acae4 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -20,6 +20,9 @@ #include #include =20 +#define CREATE_TRACE_POINTS +#include + #include "../kernel/head.h" =20 static void show_pte(unsigned long addr) @@ -291,6 +294,11 @@ void handle_page_fault(struct pt_regs *regs) if (kprobe_page_fault(regs, cause)) return; =20 + if (user_mode(regs)) + trace_page_fault_user(addr, regs, cause); + else + trace_page_fault_kernel(addr, regs, cause); + /* * Fault-in kernel-space virtual memory on-demand. * The 'reference' page table is init_mm.pgd. --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 120F1242D79; Wed, 9 Jul 2025 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; cv=none; b=Qj77vcaDiVfUm7Zfo02YNu+Sgux6wovclOsHUy5mmE154Owq37yfhLzxZSV78mp1heNfuqgNDF7GgG4WC1lm0uXJxkpB/QdfucnKjuknxlFFAA+SH+VNDPvJ3iR91do1K17HXNS6j+t2528eWARVnGj8lBirsq4NTemCssiex4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; c=relaxed/simple; bh=AfS6TQQh82okS9DkGW8GQh9IptmjH99b08416Bg0FsU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hFeilWt4bJkFE3d2+Ahl9IAcEwoKs0XWPLrfhoiv04h7XXyRUQp4yU6EttxdTjIeJXhpXg0OKnKeuuDbEOO3kmHQS5eDnf2457Zm/A/NWqjwjwhvOg3yYSMAFg/iWWAKqD+9vp+c8yyvK+GDANMURDZ8r8XdmdJizqjlwHFGUDc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=TLbcQeTX; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=LV/30EJU; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="TLbcQeTX"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="LV/30EJU" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088906; 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=aa+pYL1S1rGVwB7K8u9n1mKPCXiF5HJyzw8bW7g2Blo=; b=TLbcQeTX/PFGeHGmPlNGOIdFkJgjcnvYxwnWvPtob9nJK6HYnNUea+ceHsJYR46L3q27h1 tV7lupC2mfuo2Y2WWCOnnqqinm6PMuKg9VL2EOQtV182orBQ0DsepRNM4ME92xh3RUWhxB rNYVUEb6XIMVBYZAx/+QmOAVw4zWRq4/RPvHvESiPNyUb1F616S26SPRHffJOvA7KmSpFO 1QdKCKeyDT2+lOSXvaLrRaW1LaGVH6DVu365JzhhB9x4G4fUaE/GE5PjTNJ71FY8RUMrib K+N9bsdWHc+2IGokZ59pECumttFSeMsUxiwAr/DYXucH68ZDNmsC+u6mtOlIdg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088906; 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=aa+pYL1S1rGVwB7K8u9n1mKPCXiF5HJyzw8bW7g2Blo=; b=LV/30EJUT2U2NAuJEiNhtwanjrHBxO+9B0Gf3IzpeciWpBRZkuqd1NBuPYz5mH16nyVODz XShQavaFh4jcB5AA== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 09/12] rv: Add rtapp_pagefault monitor Date: Wed, 9 Jul 2025 21:21:20 +0200 Message-Id: <78fea8a2de6d058241d3c6502c1a92910772b0ed.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Userspace real-time applications may have design flaws that they raise page faults in real-time threads, and thus have unexpected latencies. Add an linear temporal logic monitor to detect this scenario. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- kernel/trace/rv/Kconfig | 1 + kernel/trace/rv/Makefile | 1 + kernel/trace/rv/monitors/pagefault/Kconfig | 20 +++++ .../trace/rv/monitors/pagefault/pagefault.c | 88 +++++++++++++++++++ .../trace/rv/monitors/pagefault/pagefault.h | 64 ++++++++++++++ .../rv/monitors/pagefault/pagefault_trace.h | 14 +++ kernel/trace/rv/rv_trace.h | 1 + tools/verification/models/rtapp/pagefault.ltl | 1 + 8 files changed, 190 insertions(+) create mode 100644 kernel/trace/rv/monitors/pagefault/Kconfig create mode 100644 kernel/trace/rv/monitors/pagefault/pagefault.c create mode 100644 kernel/trace/rv/monitors/pagefault/pagefault.h create mode 100644 kernel/trace/rv/monitors/pagefault/pagefault_trace.h create mode 100644 tools/verification/models/rtapp/pagefault.ltl diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index 5c407d291661..6f86d8501e87 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -42,6 +42,7 @@ source "kernel/trace/rv/monitors/scpd/Kconfig" source "kernel/trace/rv/monitors/snep/Kconfig" source "kernel/trace/rv/monitors/sncid/Kconfig" source "kernel/trace/rv/monitors/rtapp/Kconfig" +source "kernel/trace/rv/monitors/pagefault/Kconfig" # Add new monitors here =20 config RV_REACTORS diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile index 9b28c2419995..353ecf939d0e 100644 --- a/kernel/trace/rv/Makefile +++ b/kernel/trace/rv/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_RV_MON_SCPD) +=3D monitors/scpd/scpd.o obj-$(CONFIG_RV_MON_SNEP) +=3D monitors/snep/snep.o obj-$(CONFIG_RV_MON_SNCID) +=3D monitors/sncid/sncid.o obj-$(CONFIG_RV_MON_RTAPP) +=3D monitors/rtapp/rtapp.o +obj-$(CONFIG_RV_MON_PAGEFAULT) +=3D monitors/pagefault/pagefault.o # Add new monitors here obj-$(CONFIG_RV_REACTORS) +=3D rv_reactors.o obj-$(CONFIG_RV_REACT_PRINTK) +=3D reactor_printk.o diff --git a/kernel/trace/rv/monitors/pagefault/Kconfig b/kernel/trace/rv/m= onitors/pagefault/Kconfig new file mode 100644 index 000000000000..5e16625f1653 --- /dev/null +++ b/kernel/trace/rv/monitors/pagefault/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +config RV_MON_PAGEFAULT + depends on RV + select RV_LTL_MONITOR + depends on RV_MON_RTAPP + depends on X86 || RISCV + default y + select LTL_MON_EVENTS_ID + bool "pagefault monitor" + help + Monitor that real-time tasks do not raise page faults, causing + undesirable latency. + + If you are developing a real-time system and not entirely sure whether + the applications are designed correctly for real-time, you want to say + Y here. + + This monitor does not affect execution speed while it is not running, + therefore it is safe to enable this in production kernel. diff --git a/kernel/trace/rv/monitors/pagefault/pagefault.c b/kernel/trace/= rv/monitors/pagefault/pagefault.c new file mode 100644 index 000000000000..9fe6123b2200 --- /dev/null +++ b/kernel/trace/rv/monitors/pagefault/pagefault.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "pagefault" + +#include +#include +#include + +#include "pagefault.h" +#include + +static void ltl_atoms_fetch(struct task_struct *task, struct ltl_monitor *= mon) +{ + /* + * This includes "actual" real-time tasks and also PI-boosted + * tasks. A task being PI-boosted means it is blocking an "actual" + * real-task, therefore it should also obey the monitor's rule, + * otherwise the "actual" real-task may be delayed. + */ + ltl_atom_set(mon, LTL_RT, rt_or_dl_task(task)); +} + +static void ltl_atoms_init(struct task_struct *task, struct ltl_monitor *m= on, bool task_creation) +{ + if (task_creation) + ltl_atom_set(mon, LTL_PAGEFAULT, false); +} + +static void handle_page_fault(void *data, unsigned long address, struct pt= _regs *regs, + unsigned long error_code) +{ + ltl_atom_pulse(current, LTL_PAGEFAULT, true); +} + +static int enable_pagefault(void) +{ + int retval; + + retval =3D ltl_monitor_init(); + if (retval) + return retval; + + rv_attach_trace_probe("rtapp_pagefault", page_fault_kernel, handle_page_f= ault); + rv_attach_trace_probe("rtapp_pagefault", page_fault_user, handle_page_fau= lt); + + return 0; +} + +static void disable_pagefault(void) +{ + rv_detach_trace_probe("rtapp_pagefault", page_fault_kernel, handle_page_f= ault); + rv_detach_trace_probe("rtapp_pagefault", page_fault_user, handle_page_fau= lt); + + ltl_monitor_destroy(); +} + +static struct rv_monitor rv_pagefault =3D { + .name =3D "pagefault", + .description =3D "Monitor that RT tasks do not raise page faults", + .enable =3D enable_pagefault, + .disable =3D disable_pagefault, +}; + +static int __init register_pagefault(void) +{ + return rv_register_monitor(&rv_pagefault, &rv_rtapp); +} + +static void __exit unregister_pagefault(void) +{ + rv_unregister_monitor(&rv_pagefault); +} + +module_init(register_pagefault); +module_exit(unregister_pagefault); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nam Cao "); +MODULE_DESCRIPTION("pagefault: Monitor that RT tasks do not raise page fau= lts"); diff --git a/kernel/trace/rv/monitors/pagefault/pagefault.h b/kernel/trace/= rv/monitors/pagefault/pagefault.h new file mode 100644 index 000000000000..c580ec194009 --- /dev/null +++ b/kernel/trace/rv/monitors/pagefault/pagefault.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * C implementation of Buchi automaton, automatically generated by + * tools/verification/rvgen from the linear temporal logic specification. + * For further information, see kernel documentation: + * Documentation/trace/rv/linear_temporal_logic.rst + */ + +#include + +#define MONITOR_NAME pagefault + +enum ltl_atom { + LTL_PAGEFAULT, + LTL_RT, + LTL_NUM_ATOM +}; +static_assert(LTL_NUM_ATOM <=3D RV_MAX_LTL_ATOM); + +static const char *ltl_atom_str(enum ltl_atom atom) +{ + static const char *const names[] =3D { + "pa", + "rt", + }; + + return names[atom]; +} + +enum ltl_buchi_state { + S0, + RV_NUM_BA_STATES +}; +static_assert(RV_NUM_BA_STATES <=3D RV_MAX_BA_STATES); + +static void ltl_start(struct task_struct *task, struct ltl_monitor *mon) +{ + bool pagefault =3D test_bit(LTL_PAGEFAULT, mon->atoms); + bool val3 =3D !pagefault; + bool rt =3D test_bit(LTL_RT, mon->atoms); + bool val1 =3D !rt; + bool val4 =3D val1 || val3; + + if (val4) + __set_bit(S0, mon->states); +} + +static void +ltl_possible_next_states(struct ltl_monitor *mon, unsigned int state, unsi= gned long *next) +{ + bool pagefault =3D test_bit(LTL_PAGEFAULT, mon->atoms); + bool val3 =3D !pagefault; + bool rt =3D test_bit(LTL_RT, mon->atoms); + bool val1 =3D !rt; + bool val4 =3D val1 || val3; + + switch (state) { + case S0: + if (val4) + __set_bit(S0, next); + break; + } +} diff --git a/kernel/trace/rv/monitors/pagefault/pagefault_trace.h b/kernel/= trace/rv/monitors/pagefault/pagefault_trace.h new file mode 100644 index 000000000000..fe1f82597b1a --- /dev/null +++ b/kernel/trace/rv/monitors/pagefault/pagefault_trace.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Snippet to be included in rv_trace.h + */ + +#ifdef CONFIG_RV_MON_PAGEFAULT +DEFINE_EVENT(event_ltl_monitor_id, event_pagefault, + TP_PROTO(struct task_struct *task, char *states, char *atoms, char *= next), + TP_ARGS(task, states, atoms, next)); +DEFINE_EVENT(error_ltl_monitor_id, error_pagefault, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); +#endif /* CONFIG_RV_MON_PAGEFAULT */ diff --git a/kernel/trace/rv/rv_trace.h b/kernel/trace/rv/rv_trace.h index fd3111ad1d51..98eee8ec96e4 100644 --- a/kernel/trace/rv/rv_trace.h +++ b/kernel/trace/rv/rv_trace.h @@ -172,6 +172,7 @@ DECLARE_EVENT_CLASS(error_ltl_monitor_id, =20 TP_printk("%s[%d]: violation detected", __get_str(comm), __entry->pid) ); +#include // Add new monitors based on CONFIG_LTL_MON_EVENTS_ID here #endif /* CONFIG_LTL_MON_EVENTS_ID */ #endif /* _TRACE_RV_H */ diff --git a/tools/verification/models/rtapp/pagefault.ltl b/tools/verifica= tion/models/rtapp/pagefault.ltl new file mode 100644 index 000000000000..d7ce62102733 --- /dev/null +++ b/tools/verification/models/rtapp/pagefault.ltl @@ -0,0 +1 @@ +RULE =3D always (RT imply not PAGEFAULT) --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 6D6BB2405E8; Wed, 9 Jul 2025 19:21:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088911; cv=none; b=b/o+hVfHUimKoYg3k7bsu3wiefphUE05DysTEJ4KB9DUBUf9FBLvsHZxdFsRCEmYDBO7QwpXNgjYOeFli0ZsX7XknjcM0siD+uW5ylDdnH/IboK09gZSC9wx/+1y+7+joKI4k37KyMaWlR61qCYIWybdSsaKXB12PGizspqgh6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088911; c=relaxed/simple; bh=eKYjVn5JgnKJcgX62JfcI/kgh5dZ1HjnzTdycW2no8U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tOAP1O/6lI30ujEOeQ6rSkKT0QMelZ9zBT/NIvFPcFe2VL14QI/t/uyZZee0ezsi0RPjQQbUVWkuGo5CqkV/K0LvH/y6NjkfvCXFf41ExRpHP9sUIwlzl3IPnxS9oKCVZV8SGTClmktXXtKyeWoFs6Hsh1O2etlYTy1QOebHn9M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ehqXexl8; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=GWLI2blI; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ehqXexl8"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="GWLI2blI" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088906; 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=ulXF/iZtZBoGD1L+R95TA8D1hHIUmEHHDXVZhQi87x0=; b=ehqXexl8+sp+OaSZM7s4eWWNUMgklC621ka3IDbhtMXtepoDFwnrFN0FxVx59gLtX09q7d Aonc8Cpn9vPYkbMdML0KDYvx9SnCCXXf4MmHIM1IYB0TwAHqUIu0p/DTwaLxq0hxSruPJi ZY4GbA0pEgXEg5urjTYcaCJhcONt3uaite3iBwXzaqdat5Vo3udY8LhLtgbtbTYAlPZxy7 +3FP+pv0DRBFy/3hVAN2MZwLAu9rIqthhnU7fEwbI/tasXigbinX9VofoOnVW7AEeUb159 weHlzharCWhS7axmLnA9QzCPUwG14cL+1EouuE1OSEROBK0Q2hyk3JRfGWQ7WQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088906; 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=ulXF/iZtZBoGD1L+R95TA8D1hHIUmEHHDXVZhQi87x0=; b=GWLI2blIt3jUMavV/qb6RcKl04OrjsyiMaXItyCYnaKitjwIfzrbfI4egPZF6yq8Gn+K0s 1gm8P+sLtW031RDA== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 10/12] rv: Add rtapp_sleep monitor Date: Wed, 9 Jul 2025 21:21:21 +0200 Message-Id: <75bc5bcc741d153aa279c95faf778dff35c5c8ad.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Add a monitor for checking that real-time tasks do not go to sleep in a manner that may cause undesirable latency. Also change RV depends on TRACING to RV select TRACING to avoid the following recursive dependency: error: recursive dependency detected! symbol TRACING is selected by PREEMPTIRQ_TRACEPOINTS symbol PREEMPTIRQ_TRACEPOINTS depends on TRACE_IRQFLAGS symbol TRACE_IRQFLAGS is selected by RV_MON_SLEEP symbol RV_MON_SLEEP depends on RV symbol RV depends on TRACING Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- kernel/trace/rv/Kconfig | 3 +- kernel/trace/rv/Makefile | 1 + kernel/trace/rv/monitors/sleep/Kconfig | 22 ++ kernel/trace/rv/monitors/sleep/sleep.c | 237 +++++++++++++++++ kernel/trace/rv/monitors/sleep/sleep.h | 257 +++++++++++++++++++ kernel/trace/rv/monitors/sleep/sleep_trace.h | 14 + kernel/trace/rv/rv_trace.h | 1 + tools/verification/models/rtapp/sleep.ltl | 22 ++ 8 files changed, 556 insertions(+), 1 deletion(-) create mode 100644 kernel/trace/rv/monitors/sleep/Kconfig create mode 100644 kernel/trace/rv/monitors/sleep/sleep.c create mode 100644 kernel/trace/rv/monitors/sleep/sleep.h create mode 100644 kernel/trace/rv/monitors/sleep/sleep_trace.h create mode 100644 tools/verification/models/rtapp/sleep.ltl diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index 6f86d8501e87..942d57575e67 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -20,7 +20,7 @@ config RV_LTL_MONITOR =20 menuconfig RV bool "Runtime Verification" - depends on TRACING + select TRACING help Enable the kernel runtime verification infrastructure. RV is a lightweight (yet rigorous) method that complements classical @@ -43,6 +43,7 @@ source "kernel/trace/rv/monitors/snep/Kconfig" source "kernel/trace/rv/monitors/sncid/Kconfig" source "kernel/trace/rv/monitors/rtapp/Kconfig" source "kernel/trace/rv/monitors/pagefault/Kconfig" +source "kernel/trace/rv/monitors/sleep/Kconfig" # Add new monitors here =20 config RV_REACTORS diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile index 353ecf939d0e..13ec2944c665 100644 --- a/kernel/trace/rv/Makefile +++ b/kernel/trace/rv/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_RV_MON_SNEP) +=3D monitors/snep/snep.o obj-$(CONFIG_RV_MON_SNCID) +=3D monitors/sncid/sncid.o obj-$(CONFIG_RV_MON_RTAPP) +=3D monitors/rtapp/rtapp.o obj-$(CONFIG_RV_MON_PAGEFAULT) +=3D monitors/pagefault/pagefault.o +obj-$(CONFIG_RV_MON_SLEEP) +=3D monitors/sleep/sleep.o # Add new monitors here obj-$(CONFIG_RV_REACTORS) +=3D rv_reactors.o obj-$(CONFIG_RV_REACT_PRINTK) +=3D reactor_printk.o diff --git a/kernel/trace/rv/monitors/sleep/Kconfig b/kernel/trace/rv/monit= ors/sleep/Kconfig new file mode 100644 index 000000000000..6b7a122e7b47 --- /dev/null +++ b/kernel/trace/rv/monitors/sleep/Kconfig @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +config RV_MON_SLEEP + depends on RV + select RV_LTL_MONITOR + depends on HAVE_SYSCALL_TRACEPOINTS + depends on RV_MON_RTAPP + select TRACE_IRQFLAGS + default y + select LTL_MON_EVENTS_ID + bool "sleep monitor" + help + Monitor that real-time tasks do not sleep in a manner that may + cause undesirable latency. + + If you are developing a real-time system and not entirely sure whether + the applications are designed correctly for real-time, you want to say + Y here. + + Enabling this monitor may have performance impact (due to select + TRACE_IRQFLAGS). Therefore, you probably should say N for + production kernel. diff --git a/kernel/trace/rv/monitors/sleep/sleep.c b/kernel/trace/rv/monit= ors/sleep/sleep.c new file mode 100644 index 000000000000..eea447b06907 --- /dev/null +++ b/kernel/trace/rv/monitors/sleep/sleep.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "sleep" + +#include +#include +#include +#include +#include +#include + +#include "sleep.h" +#include + +static void ltl_atoms_fetch(struct task_struct *task, struct ltl_monitor *= mon) +{ + /* + * This includes "actual" real-time tasks and also PI-boosted + * tasks. A task being PI-boosted means it is blocking an "actual" + * real-task, therefore it should also obey the monitor's rule, + * otherwise the "actual" real-task may be delayed. + */ + ltl_atom_set(mon, LTL_RT, rt_or_dl_task(task)); +} + +static void ltl_atoms_init(struct task_struct *task, struct ltl_monitor *m= on, bool task_creation) +{ + ltl_atom_set(mon, LTL_SLEEP, false); + ltl_atom_set(mon, LTL_WAKE, false); + ltl_atom_set(mon, LTL_ABORT_SLEEP, false); + ltl_atom_set(mon, LTL_WOKEN_BY_HARDIRQ, false); + ltl_atom_set(mon, LTL_WOKEN_BY_NMI, false); + ltl_atom_set(mon, LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, false); + + if (task_creation) { + ltl_atom_set(mon, LTL_KTHREAD_SHOULD_STOP, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_MONOTONIC, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_TAI, false); + ltl_atom_set(mon, LTL_NANOSLEEP_TIMER_ABSTIME, false); + ltl_atom_set(mon, LTL_CLOCK_NANOSLEEP, false); + ltl_atom_set(mon, LTL_FUTEX_WAIT, false); + ltl_atom_set(mon, LTL_FUTEX_LOCK_PI, false); + ltl_atom_set(mon, LTL_BLOCK_ON_RT_MUTEX, false); + } + + if (task->flags & PF_KTHREAD) { + ltl_atom_set(mon, LTL_KERNEL_THREAD, true); + + /* kernel tasks do not do syscall */ + ltl_atom_set(mon, LTL_FUTEX_WAIT, false); + ltl_atom_set(mon, LTL_FUTEX_LOCK_PI, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_MONOTONIC, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_TAI, false); + ltl_atom_set(mon, LTL_NANOSLEEP_TIMER_ABSTIME, false); + ltl_atom_set(mon, LTL_CLOCK_NANOSLEEP, false); + + if (strstarts(task->comm, "migration/")) + ltl_atom_set(mon, LTL_TASK_IS_MIGRATION, true); + else + ltl_atom_set(mon, LTL_TASK_IS_MIGRATION, false); + + if (strstarts(task->comm, "rcu")) + ltl_atom_set(mon, LTL_TASK_IS_RCU, true); + else + ltl_atom_set(mon, LTL_TASK_IS_RCU, false); + } else { + ltl_atom_set(mon, LTL_KTHREAD_SHOULD_STOP, false); + ltl_atom_set(mon, LTL_KERNEL_THREAD, false); + ltl_atom_set(mon, LTL_TASK_IS_RCU, false); + ltl_atom_set(mon, LTL_TASK_IS_MIGRATION, false); + } + +} + +static void handle_sched_set_state(void *data, struct task_struct *task, i= nt state) +{ + if (state & TASK_INTERRUPTIBLE) + ltl_atom_pulse(task, LTL_SLEEP, true); + else if (state =3D=3D TASK_RUNNING) + ltl_atom_pulse(task, LTL_ABORT_SLEEP, true); +} + +static void handle_sched_wakeup(void *data, struct task_struct *task) +{ + ltl_atom_pulse(task, LTL_WAKE, true); +} + +static void handle_sched_waking(void *data, struct task_struct *task) +{ + if (this_cpu_read(hardirq_context)) { + ltl_atom_pulse(task, LTL_WOKEN_BY_HARDIRQ, true); + } else if (in_task()) { + if (current->prio <=3D task->prio) + ltl_atom_pulse(task, LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, true); + } else if (in_nmi()) { + ltl_atom_pulse(task, LTL_WOKEN_BY_NMI, true); + } +} + +static void handle_contention_begin(void *data, void *lock, unsigned int f= lags) +{ + if (flags & LCB_F_RT) + ltl_atom_update(current, LTL_BLOCK_ON_RT_MUTEX, true); +} + +static void handle_contention_end(void *data, void *lock, int ret) +{ + ltl_atom_update(current, LTL_BLOCK_ON_RT_MUTEX, false); +} + +static void handle_sys_enter(void *data, struct pt_regs *regs, long id) +{ + struct ltl_monitor *mon; + unsigned long args[6]; + int op, cmd; + + mon =3D ltl_get_monitor(current); + + switch (id) { + case __NR_clock_nanosleep: +#ifdef __NR_clock_nanosleep_time64 + case __NR_clock_nanosleep_time64: +#endif + syscall_get_arguments(current, regs, args); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_MONOTONIC, args[0] =3D=3D CLOCK_MO= NOTONIC); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_TAI, args[0] =3D=3D CLOCK_TAI); + ltl_atom_set(mon, LTL_NANOSLEEP_TIMER_ABSTIME, args[1] =3D=3D TIMER_ABST= IME); + ltl_atom_update(current, LTL_CLOCK_NANOSLEEP, true); + break; + + case __NR_futex: +#ifdef __NR_futex_time64 + case __NR_futex_time64: +#endif + syscall_get_arguments(current, regs, args); + op =3D args[1]; + cmd =3D op & FUTEX_CMD_MASK; + + switch (cmd) { + case FUTEX_LOCK_PI: + case FUTEX_LOCK_PI2: + ltl_atom_update(current, LTL_FUTEX_LOCK_PI, true); + break; + case FUTEX_WAIT: + case FUTEX_WAIT_BITSET: + case FUTEX_WAIT_REQUEUE_PI: + ltl_atom_update(current, LTL_FUTEX_WAIT, true); + break; + } + break; + } +} + +static void handle_sys_exit(void *data, struct pt_regs *regs, long ret) +{ + struct ltl_monitor *mon =3D ltl_get_monitor(current); + + ltl_atom_set(mon, LTL_FUTEX_LOCK_PI, false); + ltl_atom_set(mon, LTL_FUTEX_WAIT, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_MONOTONIC, false); + ltl_atom_set(mon, LTL_NANOSLEEP_CLOCK_TAI, false); + ltl_atom_set(mon, LTL_NANOSLEEP_TIMER_ABSTIME, false); + ltl_atom_update(current, LTL_CLOCK_NANOSLEEP, false); +} + +static void handle_kthread_stop(void *data, struct task_struct *task) +{ + /* FIXME: this could race with other tracepoint handlers */ + ltl_atom_update(task, LTL_KTHREAD_SHOULD_STOP, true); +} + +static int enable_sleep(void) +{ + int retval; + + retval =3D ltl_monitor_init(); + if (retval) + return retval; + + rv_attach_trace_probe("rtapp_sleep", sched_waking, handle_sched_waking); + rv_attach_trace_probe("rtapp_sleep", sched_wakeup, handle_sched_wakeup); + rv_attach_trace_probe("rtapp_sleep", sched_set_state_tp, handle_sched_set= _state); + rv_attach_trace_probe("rtapp_sleep", contention_begin, handle_contention_= begin); + rv_attach_trace_probe("rtapp_sleep", contention_end, handle_contention_en= d); + rv_attach_trace_probe("rtapp_sleep", sched_kthread_stop, handle_kthread_s= top); + rv_attach_trace_probe("rtapp_sleep", sys_enter, handle_sys_enter); + rv_attach_trace_probe("rtapp_sleep", sys_exit, handle_sys_exit); + return 0; +} + +static void disable_sleep(void) +{ + rv_detach_trace_probe("rtapp_sleep", sched_waking, handle_sched_waking); + rv_detach_trace_probe("rtapp_sleep", sched_wakeup, handle_sched_wakeup); + rv_detach_trace_probe("rtapp_sleep", sched_set_state_tp, handle_sched_set= _state); + rv_detach_trace_probe("rtapp_sleep", contention_begin, handle_contention_= begin); + rv_detach_trace_probe("rtapp_sleep", contention_end, handle_contention_en= d); + rv_detach_trace_probe("rtapp_sleep", sched_kthread_stop, handle_kthread_s= top); + rv_detach_trace_probe("rtapp_sleep", sys_enter, handle_sys_enter); + rv_detach_trace_probe("rtapp_sleep", sys_exit, handle_sys_exit); + + ltl_monitor_destroy(); +} + +static struct rv_monitor rv_sleep =3D { + .name =3D "sleep", + .description =3D "Monitor that RT tasks do not undesirably sleep", + .enable =3D enable_sleep, + .disable =3D disable_sleep, +}; + +static int __init register_sleep(void) +{ + return rv_register_monitor(&rv_sleep, &rv_rtapp); +} + +static void __exit unregister_sleep(void) +{ + rv_unregister_monitor(&rv_sleep); +} + +module_init(register_sleep); +module_exit(unregister_sleep); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nam Cao "); +MODULE_DESCRIPTION("sleep: Monitor that RT tasks do not undesirably sleep"= ); diff --git a/kernel/trace/rv/monitors/sleep/sleep.h b/kernel/trace/rv/monit= ors/sleep/sleep.h new file mode 100644 index 000000000000..2ab46fd218d2 --- /dev/null +++ b/kernel/trace/rv/monitors/sleep/sleep.h @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * C implementation of Buchi automaton, automatically generated by + * tools/verification/rvgen from the linear temporal logic specification. + * For further information, see kernel documentation: + * Documentation/trace/rv/linear_temporal_logic.rst + */ + +#include + +#define MONITOR_NAME sleep + +enum ltl_atom { + LTL_ABORT_SLEEP, + LTL_BLOCK_ON_RT_MUTEX, + LTL_CLOCK_NANOSLEEP, + LTL_FUTEX_LOCK_PI, + LTL_FUTEX_WAIT, + LTL_KERNEL_THREAD, + LTL_KTHREAD_SHOULD_STOP, + LTL_NANOSLEEP_CLOCK_MONOTONIC, + LTL_NANOSLEEP_CLOCK_TAI, + LTL_NANOSLEEP_TIMER_ABSTIME, + LTL_RT, + LTL_SLEEP, + LTL_TASK_IS_MIGRATION, + LTL_TASK_IS_RCU, + LTL_WAKE, + LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, + LTL_WOKEN_BY_HARDIRQ, + LTL_WOKEN_BY_NMI, + LTL_NUM_ATOM +}; +static_assert(LTL_NUM_ATOM <=3D RV_MAX_LTL_ATOM); + +static const char *ltl_atom_str(enum ltl_atom atom) +{ + static const char *const names[] =3D { + "ab_sl", + "bl_on_rt_mu", + "cl_na", + "fu_lo_pi", + "fu_wa", + "ker_th", + "kth_sh_st", + "na_cl_mo", + "na_cl_ta", + "na_ti_ab", + "rt", + "sl", + "ta_mi", + "ta_rc", + "wak", + "wo_eq_hi_pr", + "wo_ha", + "wo_nm", + }; + + return names[atom]; +} + +enum ltl_buchi_state { + S0, + S1, + S2, + S3, + S4, + S5, + S6, + S7, + RV_NUM_BA_STATES +}; +static_assert(RV_NUM_BA_STATES <=3D RV_MAX_BA_STATES); + +static void ltl_start(struct task_struct *task, struct ltl_monitor *mon) +{ + bool task_is_migration =3D test_bit(LTL_TASK_IS_MIGRATION, mon->atoms); + bool task_is_rcu =3D test_bit(LTL_TASK_IS_RCU, mon->atoms); + bool val40 =3D task_is_rcu || task_is_migration; + bool futex_lock_pi =3D test_bit(LTL_FUTEX_LOCK_PI, mon->atoms); + bool val41 =3D futex_lock_pi || val40; + bool block_on_rt_mutex =3D test_bit(LTL_BLOCK_ON_RT_MUTEX, mon->atoms); + bool val5 =3D block_on_rt_mutex || val41; + bool kthread_should_stop =3D test_bit(LTL_KTHREAD_SHOULD_STOP, mon->atoms= ); + bool abort_sleep =3D test_bit(LTL_ABORT_SLEEP, mon->atoms); + bool val32 =3D abort_sleep || kthread_should_stop; + bool woken_by_nmi =3D test_bit(LTL_WOKEN_BY_NMI, mon->atoms); + bool val33 =3D woken_by_nmi || val32; + bool woken_by_hardirq =3D test_bit(LTL_WOKEN_BY_HARDIRQ, mon->atoms); + bool val34 =3D woken_by_hardirq || val33; + bool woken_by_equal_or_higher_prio =3D test_bit(LTL_WOKEN_BY_EQUAL_OR_HIG= HER_PRIO, + mon->atoms); + bool val14 =3D woken_by_equal_or_higher_prio || val34; + bool wake =3D test_bit(LTL_WAKE, mon->atoms); + bool val13 =3D !wake; + bool kernel_thread =3D test_bit(LTL_KERNEL_THREAD, mon->atoms); + bool nanosleep_clock_tai =3D test_bit(LTL_NANOSLEEP_CLOCK_TAI, mon->atoms= ); + bool nanosleep_clock_monotonic =3D test_bit(LTL_NANOSLEEP_CLOCK_MONOTONIC= , mon->atoms); + bool val24 =3D nanosleep_clock_monotonic || nanosleep_clock_tai; + bool nanosleep_timer_abstime =3D test_bit(LTL_NANOSLEEP_TIMER_ABSTIME, mo= n->atoms); + bool val25 =3D nanosleep_timer_abstime && val24; + bool clock_nanosleep =3D test_bit(LTL_CLOCK_NANOSLEEP, mon->atoms); + bool val18 =3D clock_nanosleep && val25; + bool futex_wait =3D test_bit(LTL_FUTEX_WAIT, mon->atoms); + bool val9 =3D futex_wait || val18; + bool val11 =3D val9 || kernel_thread; + bool sleep =3D test_bit(LTL_SLEEP, mon->atoms); + bool val2 =3D !sleep; + bool rt =3D test_bit(LTL_RT, mon->atoms); + bool val1 =3D !rt; + bool val3 =3D val1 || val2; + + if (val3) + __set_bit(S0, mon->states); + if (val11 && val13) + __set_bit(S1, mon->states); + if (val11 && val14) + __set_bit(S4, mon->states); + if (val5) + __set_bit(S5, mon->states); +} + +static void +ltl_possible_next_states(struct ltl_monitor *mon, unsigned int state, unsi= gned long *next) +{ + bool task_is_migration =3D test_bit(LTL_TASK_IS_MIGRATION, mon->atoms); + bool task_is_rcu =3D test_bit(LTL_TASK_IS_RCU, mon->atoms); + bool val40 =3D task_is_rcu || task_is_migration; + bool futex_lock_pi =3D test_bit(LTL_FUTEX_LOCK_PI, mon->atoms); + bool val41 =3D futex_lock_pi || val40; + bool block_on_rt_mutex =3D test_bit(LTL_BLOCK_ON_RT_MUTEX, mon->atoms); + bool val5 =3D block_on_rt_mutex || val41; + bool kthread_should_stop =3D test_bit(LTL_KTHREAD_SHOULD_STOP, mon->atoms= ); + bool abort_sleep =3D test_bit(LTL_ABORT_SLEEP, mon->atoms); + bool val32 =3D abort_sleep || kthread_should_stop; + bool woken_by_nmi =3D test_bit(LTL_WOKEN_BY_NMI, mon->atoms); + bool val33 =3D woken_by_nmi || val32; + bool woken_by_hardirq =3D test_bit(LTL_WOKEN_BY_HARDIRQ, mon->atoms); + bool val34 =3D woken_by_hardirq || val33; + bool woken_by_equal_or_higher_prio =3D test_bit(LTL_WOKEN_BY_EQUAL_OR_HIG= HER_PRIO, + mon->atoms); + bool val14 =3D woken_by_equal_or_higher_prio || val34; + bool wake =3D test_bit(LTL_WAKE, mon->atoms); + bool val13 =3D !wake; + bool kernel_thread =3D test_bit(LTL_KERNEL_THREAD, mon->atoms); + bool nanosleep_clock_tai =3D test_bit(LTL_NANOSLEEP_CLOCK_TAI, mon->atoms= ); + bool nanosleep_clock_monotonic =3D test_bit(LTL_NANOSLEEP_CLOCK_MONOTONIC= , mon->atoms); + bool val24 =3D nanosleep_clock_monotonic || nanosleep_clock_tai; + bool nanosleep_timer_abstime =3D test_bit(LTL_NANOSLEEP_TIMER_ABSTIME, mo= n->atoms); + bool val25 =3D nanosleep_timer_abstime && val24; + bool clock_nanosleep =3D test_bit(LTL_CLOCK_NANOSLEEP, mon->atoms); + bool val18 =3D clock_nanosleep && val25; + bool futex_wait =3D test_bit(LTL_FUTEX_WAIT, mon->atoms); + bool val9 =3D futex_wait || val18; + bool val11 =3D val9 || kernel_thread; + bool sleep =3D test_bit(LTL_SLEEP, mon->atoms); + bool val2 =3D !sleep; + bool rt =3D test_bit(LTL_RT, mon->atoms); + bool val1 =3D !rt; + bool val3 =3D val1 || val2; + + switch (state) { + case S0: + if (val3) + __set_bit(S0, next); + if (val11 && val13) + __set_bit(S1, next); + if (val11 && val14) + __set_bit(S4, next); + if (val5) + __set_bit(S5, next); + break; + case S1: + if (val11 && val13) + __set_bit(S1, next); + if (val13 && val3) + __set_bit(S2, next); + if (val14 && val3) + __set_bit(S3, next); + if (val11 && val14) + __set_bit(S4, next); + if (val13 && val5) + __set_bit(S6, next); + if (val14 && val5) + __set_bit(S7, next); + break; + case S2: + if (val11 && val13) + __set_bit(S1, next); + if (val13 && val3) + __set_bit(S2, next); + if (val14 && val3) + __set_bit(S3, next); + if (val11 && val14) + __set_bit(S4, next); + if (val13 && val5) + __set_bit(S6, next); + if (val14 && val5) + __set_bit(S7, next); + break; + case S3: + if (val3) + __set_bit(S0, next); + if (val11 && val13) + __set_bit(S1, next); + if (val11 && val14) + __set_bit(S4, next); + if (val5) + __set_bit(S5, next); + break; + case S4: + if (val3) + __set_bit(S0, next); + if (val11 && val13) + __set_bit(S1, next); + if (val11 && val14) + __set_bit(S4, next); + if (val5) + __set_bit(S5, next); + break; + case S5: + if (val3) + __set_bit(S0, next); + if (val11 && val13) + __set_bit(S1, next); + if (val11 && val14) + __set_bit(S4, next); + if (val5) + __set_bit(S5, next); + break; + case S6: + if (val11 && val13) + __set_bit(S1, next); + if (val13 && val3) + __set_bit(S2, next); + if (val14 && val3) + __set_bit(S3, next); + if (val11 && val14) + __set_bit(S4, next); + if (val13 && val5) + __set_bit(S6, next); + if (val14 && val5) + __set_bit(S7, next); + break; + case S7: + if (val3) + __set_bit(S0, next); + if (val11 && val13) + __set_bit(S1, next); + if (val11 && val14) + __set_bit(S4, next); + if (val5) + __set_bit(S5, next); + break; + } +} diff --git a/kernel/trace/rv/monitors/sleep/sleep_trace.h b/kernel/trace/rv= /monitors/sleep/sleep_trace.h new file mode 100644 index 000000000000..22eaf31da987 --- /dev/null +++ b/kernel/trace/rv/monitors/sleep/sleep_trace.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Snippet to be included in rv_trace.h + */ + +#ifdef CONFIG_RV_MON_SLEEP +DEFINE_EVENT(event_ltl_monitor_id, event_sleep, + TP_PROTO(struct task_struct *task, char *states, char *atoms, char *= next), + TP_ARGS(task, states, atoms, next)); +DEFINE_EVENT(error_ltl_monitor_id, error_sleep, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); +#endif /* CONFIG_RV_MON_SLEEP */ diff --git a/kernel/trace/rv/rv_trace.h b/kernel/trace/rv/rv_trace.h index 98eee8ec96e4..b6f310498466 100644 --- a/kernel/trace/rv/rv_trace.h +++ b/kernel/trace/rv/rv_trace.h @@ -173,6 +173,7 @@ DECLARE_EVENT_CLASS(error_ltl_monitor_id, TP_printk("%s[%d]: violation detected", __get_str(comm), __entry->pid) ); #include +#include // Add new monitors based on CONFIG_LTL_MON_EVENTS_ID here #endif /* CONFIG_LTL_MON_EVENTS_ID */ #endif /* _TRACE_RV_H */ diff --git a/tools/verification/models/rtapp/sleep.ltl b/tools/verification= /models/rtapp/sleep.ltl new file mode 100644 index 000000000000..6379bbeb6212 --- /dev/null +++ b/tools/verification/models/rtapp/sleep.ltl @@ -0,0 +1,22 @@ +RULE =3D always ((RT and SLEEP) imply (RT_FRIENDLY_SLEEP or ALLOWLIST)) + +RT_FRIENDLY_SLEEP =3D (RT_VALID_SLEEP_REASON or KERNEL_THREAD) + and ((not WAKE) until RT_FRIENDLY_WAKE) + +RT_VALID_SLEEP_REASON =3D FUTEX_WAIT + or RT_FRIENDLY_NANOSLEEP + +RT_FRIENDLY_NANOSLEEP =3D CLOCK_NANOSLEEP + and NANOSLEEP_TIMER_ABSTIME + and (NANOSLEEP_CLOCK_MONOTONIC or NANOSLEEP_CLOCK_TAI) + +RT_FRIENDLY_WAKE =3D WOKEN_BY_EQUAL_OR_HIGHER_PRIO + or WOKEN_BY_HARDIRQ + or WOKEN_BY_NMI + or ABORT_SLEEP + or KTHREAD_SHOULD_STOP + +ALLOWLIST =3D BLOCK_ON_RT_MUTEX + or FUTEX_LOCK_PI + or TASK_IS_RCU + or TASK_IS_MIGRATION --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 BA03E243951; Wed, 9 Jul 2025 19:21:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; cv=none; b=CXnZecdntWVWSsQpr9M2heS9Ve0Ztuqao69Rotjvl2xSicjIP6jElbqL4VlDF+ecvxvsnO3yAxGMAO1CRejPckR4Y0rA7UuV9Rg2ovMBdqmZ37YCrrgUtJisAn6kjjmH4iLUmntTDHvz87H/1XFIbKB7B7XcYK8xGvbCmI2fbqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088910; c=relaxed/simple; bh=QikPuesc4B/13zDdpgGHsddz3vJrrDz110M8NWmMzvY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UMQHUypqYF7et2vOUb+C6xHdHrEqDZvlxf+jXMvoT3hLbpHyG5oNw+HDeUYw2DTSY3NZ/lPF4Bc1flHCd3zuuRKM9G+QuHa0RLHJuexBuwmKPwStByFJDwghgeopsMjuJioSNHEt96plkpgdrLkKKCHspP5TnVWckgGe+TBqdCY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=sd0sBo95; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jmeEHfTW; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="sd0sBo95"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jmeEHfTW" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088907; 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=GvaGJm6tNpJP8KHlvubeC777ZLLmkrS528HtYD07bQE=; b=sd0sBo95cAKp3UQwHX9qCDT1jo9be9bfryZ0R6dD+4xekiE1ngrrmYmPXKZnMwmL4SY1yf O1NptUJkqumLymcGH2QC6AjCEk6kUiHly9BAMuE/AocENH3plDCZiaupsO+lYILO9PvW/V qYjRX4aEMHJQOILucY7lVlAGvcynboaWITMczL/5zUa2zHeo4jYGZnSZzG45TzQ7dXl+vl BZLq0efKQC1mKQlPfELSZNmmBVHNgGIdDJ38056YcI0A5AI31tIVxh3Ed9gFMLzuoBsOJR /DIM6UYAI3qAvo18dVLe2/BoOAdolm67ZM8TLLg7LgLuONowrKEz+XYT3jIL0Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088907; 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=GvaGJm6tNpJP8KHlvubeC777ZLLmkrS528HtYD07bQE=; b=jmeEHfTWVjh4WIUOSA6i0zd2A5tQA8+6S5BEJab0rcyLIyE3MSt4CEv2sUg/C8250+vMgW T2IQDl+YT1C9YiBw== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 11/12] rv: Add documentation for rtapp monitor Date: Wed, 9 Jul 2025 21:21:22 +0200 Message-Id: In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Add documentation describing the rtapp monitor. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- Documentation/trace/rv/index.rst | 1 + Documentation/trace/rv/monitor_rtapp.rst | 133 +++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 Documentation/trace/rv/monitor_rtapp.rst diff --git a/Documentation/trace/rv/index.rst b/Documentation/trace/rv/inde= x.rst index e80e0057feb4..26042dff70bb 100644 --- a/Documentation/trace/rv/index.rst +++ b/Documentation/trace/rv/index.rst @@ -13,3 +13,4 @@ Runtime Verification monitor_wip.rst monitor_wwnr.rst monitor_sched.rst + monitor_rtapp.rst diff --git a/Documentation/trace/rv/monitor_rtapp.rst b/Documentation/trace= /rv/monitor_rtapp.rst new file mode 100644 index 000000000000..c8104eda924a --- /dev/null +++ b/Documentation/trace/rv/monitor_rtapp.rst @@ -0,0 +1,133 @@ +Real-time application monitors +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +- Name: rtapp +- Type: container for multiple monitors +- Author: Nam Cao + +Description +----------- + +Real-time applications may have design flaws such that they experience +unexpected latency and fail to meet their time requirements. Often, these = flaws +follow a few patterns: + + - Page faults: A real-time thread may access memory that does not have a + mapped physical backing or must first be copied (such as for copy-on-w= rite). + Thus a page fault is raised and the kernel must first perform the expe= nsive + action. This causes significant delays to the real-time thread + - Priority inversion: A real-time thread blocks waiting for a lower-prio= rity + thread. This causes the real-time thread to effectively take on the + scheduling priority of the lower-priority thread. For example, the rea= l-time + thread needs to access a shared resource that is protected by a + non-pi-mutex, but the mutex is currently owned by a non-real-time thre= ad. + +The `rtapp` monitor detects these patterns. It aids developers to identify +reasons for unexpected latency with real-time applications. It is a contai= ner of +multiple sub-monitors described in the following sections. + +Monitor pagefault ++++++++++++++++++ + +The `pagefault` monitor reports real-time tasks raising page faults. Its +specification is:: + + RULE =3D always (RT imply not PAGEFAULT) + +To fix warnings reported by this monitor, `mlockall()` or `mlock()` can be= used +to ensure physical backing for memory. + +This monitor may have false negatives because the pages used by the real-t= ime +threads may just happen to be directly available during testing. To minim= ize +this, the system can be put under memory pressure (e.g. invoking the OOM = killer +using a program that does `ptr =3D malloc(SIZE_OF_RAM); memset(ptr, 0, +SIZE_OF_RAM);`) so that the kernel executes aggressive strategies to recyc= le as +much physical memory as possible. + +Monitor sleep ++++++++++++++ + +The `sleep` monitor reports real-time threads sleeping in a manner that may +cause undesirable latency. Real-time applications should only put a real-t= ime +thread to sleep for one of the following reasons: + + - Cyclic work: real-time thread sleeps waiting for the next cycle. For t= his + case, only the `clock_nanosleep` syscall should be used with `TIMER_AB= STIME` + (to avoid time drift) and `CLOCK_MONOTONIC` (to avoid the clock being + changed). No other method is safe for real-time. For example, threads + waiting for timerfd can be woken by softirq which provides no real-time + guarantee. + - Real-time thread waiting for something to happen (e.g. another thread + releasing shared resources, or a completion signal from another thread= ). In + this case, only futexes (FUTEX_LOCK_PI, FUTEX_LOCK_PI2 or one of + FUTEX_WAIT_*) should be used. Applications usually do not use futexes + directly, but use PI mutexes and PI condition variables which are buil= t on + top of futexes. Be aware that the C library might not implement condit= ional + variables as safe for real-time. As an alternative, the librtpi library + exists to provide a conditional variable implementation that is correc= t for + real-time applications in Linux. + +Beside the reason for sleeping, the eventual waker should also be +real-time-safe. Namely, one of: + + - An equal-or-higher-priority thread + - Hard interrupt handler + - Non-maskable interrupt handler + +This monitor's warning usually means one of the following: + + - Real-time thread is blocked by a non-real-time thread (e.g. due to + contention on a mutex without priority inheritance). This is priority + inversion. + - Time-critical work waits for something which is not safe for real-time= (e.g. + timerfd). + - The work executed by the real-time thread does not need to run at real= -time + priority at all. This is not a problem for the real-time thread itsel= f, but + it is potentially taking the CPU away from other important real-time w= ork. + +Application developers may purposely choose to have their real-time applic= ation +sleep in a way that is not safe for real-time. It is debatable whether tha= t is a +problem. Application developers must analyze the warnings to make a proper +assessment. + +The monitor's specification is:: + + RULE =3D always ((RT and SLEEP) imply (RT_FRIENDLY_SLEEP or ALLOWLIST)) + + RT_FRIENDLY_SLEEP =3D (RT_VALID_SLEEP_REASON or KERNEL_THREAD) + and ((not WAKE) until RT_FRIENDLY_WAKE) + + RT_VALID_SLEEP_REASON =3D FUTEX_WAIT + or RT_FRIENDLY_NANOSLEEP + + RT_FRIENDLY_NANOSLEEP =3D CLOCK_NANOSLEEP + and NANOSLEEP_TIMER_ABSTIME + and NANOSLEEP_CLOCK_MONOTONIC + + RT_FRIENDLY_WAKE =3D WOKEN_BY_EQUAL_OR_HIGHER_PRIO + or WOKEN_BY_HARDIRQ + or WOKEN_BY_NMI + or KTHREAD_SHOULD_STOP + + ALLOWLIST =3D BLOCK_ON_RT_MUTEX + or FUTEX_LOCK_PI + or TASK_IS_RCU + or TASK_IS_MIGRATION + +Beside the scenarios described above, this specification also handle some +special cases: + + - `KERNEL_THREAD`: kernel tasks do not have any pattern that can be reco= gnized + as valid real-time sleeping reasons. Therefore sleeping reason is not + checked for kernel tasks. + - `KTHREAD_SHOULD_STOP`: a non-real-time thread may stop a real-time ker= nel + thread by waking it and waiting for it to exit (`kthread_stop()`). This + wakeup is safe for real-time. + - `ALLOWLIST`: to handle known false positives with the kernel. + - `BLOCK_ON_RT_MUTEX` is included in the allowlist due to its implementa= tion. + In the release path of rt_mutex, a boosted task is de-boosted before w= aking + the rt_mutex's waiter. Consequently, the monitor may see a real-time-u= nsafe + wakeup (e.g. non-real-time task waking real-time task). This is actual= ly + real-time-safe because preemption is disabled for the duration. + - `FUTEX_LOCK_PI` is included in the allowlist for the same reason as + `BLOCK_ON_RT_MUTEX`. --=20 2.39.5 From nobody Tue Oct 7 12:28:20 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 41921244676; Wed, 9 Jul 2025 19:21:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088911; cv=none; b=eNze0+Ef6yAbsprzgB9TXPqYglV6t7+NWFjiUv/kFLNr3izp9zoPeZLGGTGWXkXVjU4jhyg4qEtIeMkyfb3rvUN8etTsRNhhm/vQKa6EpTXbiG43TD9LO7n6CiVmy7GppNItV8ZWN8XMaZIi7IxfLGODrTN/LragyJG5DpJZPf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752088911; c=relaxed/simple; bh=Wgc5TeCxTSHrIluk/Zchk1qeFdkcI5CAnbfWjST87wc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sY4WgdsRq1Pz95nA0uL6Tot2tlqBcMGEGydjUbf5j/ybQxe17kwMKEHzcxqrWpjR2ugKXk4m3THAhTyK8Oh3Tf4DhecOnfw3ZUxm1JUB0V1ZHQE2dPgNBXCuiGva9dF2N5gy/HhFWM4r25PWgy64pDQoVNnS+Rgmicu1NxHAS00= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=D7hiEdo0; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=6sO63G7O; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="D7hiEdo0"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="6sO63G7O" From: Nam Cao DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752088907; 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=bJJiizdaOD7bLY57+4l2vOqWNZK0dHtbValv5ybO8Ck=; b=D7hiEdo0UwSYy61UmfwI2smYLX5Xd0ztWTt4Rf//tYAinUlZqYkF3cL7uamYK97Qoy9ctR yiKl5QdWjSFtPcYb/n+CXzXL0N2pZh2mG5GNOO9jsxDLrXL2RYuvtn68s1BBrRI+TpmLHv HXwiSVXG1IujlFGD97JCUDcDfFviM1diXSraUl9hJr0djvZKN8XV+1bBrV1VHzRagGF548 z7zgkPfSrRBVDgEQbpwJ05yVtgN59/oEfEavAwyCj4nZTunmkgDaqX1NH4klADVxJWegcM 9JcKOEp39xmDDWnu9qjQ11QJv0oSJlLRZa2waBO6jUDW2NYFiJ3uf6Ai4ORK4g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752088907; 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=bJJiizdaOD7bLY57+4l2vOqWNZK0dHtbValv5ybO8Ck=; b=6sO63G7OTHQb16XwD+XJDiQ01CQgQ/7tbjljEfXPbWkV+TWk9rBunJwd8oeGYg/toeyDAP JzPG/ahplzI6qBCQ== To: Steven Rostedt , John Ogness , Masami Hiramatsu , Mathieu Desnoyers , Gabriele Monaco , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Nam Cao Subject: [PATCH v13 12/12] rv: Allow to configure the number of per-task monitor Date: Wed, 9 Jul 2025 21:21:23 +0200 Message-Id: <93e83313fc4ba7f6e66f4abe80ca5f5494d658d0.1752088709.git.namcao@linutronix.de> In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" Now that there are 2 monitors for real-time applications, users may want to enable both of them simultaneously. Make the number of per-task monitor configurable. Default it to 2 for now. Reviewed-by: Gabriele Monaco Signed-off-by: Nam Cao --- include/linux/rv.h | 9 +-------- include/linux/sched.h | 8 +++----- kernel/trace/rv/Kconfig | 9 +++++++++ kernel/trace/rv/monitors/rtapp/Kconfig | 1 + kernel/trace/rv/rv.c | 8 ++++---- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/linux/rv.h b/include/linux/rv.h index 1d5579f9b75a..97baf58d88b2 100644 --- a/include/linux/rv.h +++ b/include/linux/rv.h @@ -75,14 +75,7 @@ struct ltl_monitor {}; =20 #endif /* CONFIG_RV_LTL_MONITOR */ =20 -/* - * Per-task RV monitors count. Nowadays fixed in RV_PER_TASK_MONITORS. - * If we find justification for more monitors, we can think about - * adding more or developing a dynamic method. So far, none of - * these are justified. - */ -#define RV_PER_TASK_MONITORS 1 -#define RV_PER_TASK_MONITOR_INIT (RV_PER_TASK_MONITORS) +#define RV_PER_TASK_MONITOR_INIT (CONFIG_RV_PER_TASK_MONITORS) =20 union rv_task_monitor { struct da_monitor da_mon; diff --git a/include/linux/sched.h b/include/linux/sched.h index 4f78a64beb52..fabd7fe1a07a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1642,12 +1642,10 @@ struct task_struct { =20 #ifdef CONFIG_RV /* - * Per-task RV monitor. Nowadays fixed in RV_PER_TASK_MONITORS. - * If we find justification for more monitors, we can think - * about adding more or developing a dynamic method. So far, - * none of these are justified. + * Per-task RV monitor, fixed in CONFIG_RV_PER_TASK_MONITORS. + * If memory becomes a concern, we can think about a dynamic method. */ - union rv_task_monitor rv[RV_PER_TASK_MONITORS]; + union rv_task_monitor rv[CONFIG_RV_PER_TASK_MONITORS]; #endif =20 #ifdef CONFIG_USER_EVENTS diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index 942d57575e67..c11bf7e61ebf 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -32,6 +32,15 @@ menuconfig RV For further information, see: Documentation/trace/rv/runtime-verification.rst =20 +config RV_PER_TASK_MONITORS + int "Maximum number of per-task monitor" + depends on RV + range 1 8 + default 2 + help + This option configures the maximum number of per-task RV monitors that = can run + simultaneously. + source "kernel/trace/rv/monitors/wip/Kconfig" source "kernel/trace/rv/monitors/wwnr/Kconfig" source "kernel/trace/rv/monitors/sched/Kconfig" diff --git a/kernel/trace/rv/monitors/rtapp/Kconfig b/kernel/trace/rv/monit= ors/rtapp/Kconfig index b7415c3570bb..1ce9370a9ba8 100644 --- a/kernel/trace/rv/monitors/rtapp/Kconfig +++ b/kernel/trace/rv/monitors/rtapp/Kconfig @@ -1,5 +1,6 @@ config RV_MON_RTAPP depends on RV + depends on RV_PER_TASK_MONITORS >=3D 2 bool "rtapp monitor" help Collection of monitors to check for common problems with real-time diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c index e25d65fe432a..108429d16ec1 100644 --- a/kernel/trace/rv/rv.c +++ b/kernel/trace/rv/rv.c @@ -165,7 +165,7 @@ struct dentry *get_monitors_root(void) LIST_HEAD(rv_monitors_list); =20 static int task_monitor_count; -static bool task_monitor_slots[RV_PER_TASK_MONITORS]; +static bool task_monitor_slots[CONFIG_RV_PER_TASK_MONITORS]; =20 int rv_get_task_monitor_slot(void) { @@ -173,12 +173,12 @@ int rv_get_task_monitor_slot(void) =20 lockdep_assert_held(&rv_interface_lock); =20 - if (task_monitor_count =3D=3D RV_PER_TASK_MONITORS) + if (task_monitor_count =3D=3D CONFIG_RV_PER_TASK_MONITORS) return -EBUSY; =20 task_monitor_count++; =20 - for (i =3D 0; i < RV_PER_TASK_MONITORS; i++) { + for (i =3D 0; i < CONFIG_RV_PER_TASK_MONITORS; i++) { if (task_monitor_slots[i] =3D=3D false) { task_monitor_slots[i] =3D true; return i; @@ -194,7 +194,7 @@ void rv_put_task_monitor_slot(int slot) { lockdep_assert_held(&rv_interface_lock); =20 - if (slot < 0 || slot >=3D RV_PER_TASK_MONITORS) { + if (slot < 0 || slot >=3D CONFIG_RV_PER_TASK_MONITORS) { WARN_ONCE(1, "RV releasing an invalid slot!: %d\n", slot); return; } --=20 2.39.5