From nobody Sun Sep 27 02:40:14 2026 Received: from mta1.migadu.com (out-237.mta1.migadu.com [95.215.58.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3ACC538B127 for ; Sun, 6 Sep 2026 17:10:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.237 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714658; cv=none; b=WiLBgUtlD5JIOaoIdrx9O7JWpZHJZVkldjyhy3DdwLiYbb+58FN+9/akTtxDMk09j6q5T88bP5TQhsKLz2TaehWxgL627+/GKpM72S4lZsehBd7TUWoHvWaJmE4soDhJQKKAu79xENaCAl+3/Ik5h86LLgQFL2xqDRmxfMP+6EQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714658; c=relaxed/simple; bh=IxTknAVVR/YuLoBNpva2eVMorqanFY6/8SlH81Mm0vI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Ib4buKPHFT2hT9o3VIPxDsOkmgZPNqgMr/dDaq8XLS8KcZLKJey6duGkiaZt1rvRSW8GbFVTvhCPlyOtO5EWyXqYQoyhEn5DblUyZJ1/ehtJ01MrRCZ0l2rR05sLN3W9PZ0DH6wmfhbVOuJ62BeT1llBASXkJozOAoxF70NowtU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=v35BbHe6; arc=none smtp.client-ip=95.215.58.237 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="v35BbHe6" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=IxTknAVVR/YuLoBNpva2eVMorqanFY6/8SlH81Mm0vI=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788714655; v=1; x=1789319455; b=v35BbHe6wN2oVaZopcqGPGH1TvrNaWonZWLjt5xqFlZAPugT7UkJC6FXKNYdZzkmMIpc29Vs 2J22ER7l54UvZIWlgAfpYI/1EV0qXePDwX41vxLlZ6H1wC8beQAeBWs4KX2JVLpmLlRt2dghSii UCL9JrHyXmi2KXVvTNfVok4I= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id f68e23973734dda4; Sun, 06 Sep 2026 17:10:55 +0000 X-Mizu-Trace-ID: f68e23973734dda4 X-Migadu-Flow: FLOW_OUT From: wen.yang@linux.dev To: Gabriele Monaco Cc: Nam Cao , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Wen Yang , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Subject: [PATCH v5 1/5] rv/reactors: use LD_WAIT_SPIN as the reactor lockdep wait type Date: Mon, 7 Sep 2026 01:10:37 +0800 Message-Id: X-Mailer: git-send-email 2.25.1 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Wen Yang rv_react() overrides the lockdep wait type to LD_WAIT_FREE to enforce that reactor callbacks take no locks. But callbacks run in the context of the triggering tracepoint, which can be preemptible task context on any kernel. A timer interrupt firing during the callback makes the interrupt-exit path schedule and take rq->__lock (LD_WAIT_SPIN) while the LD_WAIT_FREE override is still held, producing a spurious "Invalid wait context" warning: [ BUG: Invalid wait context ] context-{5:5} 1 lock held by kunit_try_catch/209: #0: (rv_react_map-wait-type-override){+.+.}-{1:1} kunit_try_catch/209 is trying to lock: ffff8a743ed3e8a0 (&rq->__lock){-...}-{2:2} Use LD_WAIT_SPIN instead of LD_WAIT_FREE, which causes false-positive warnings in preemptible contexts due to scheduler preemption taking rq->__lock. Add documentation to runtime-verification.rst. Fixes: 69d8895cb9a9 ("rv: Add explicit lockdep context for reactors") Reviewed-by: Gabriele Monaco Signed-off-by: Wen Yang Cc: Thomas Wei=C3=9Fschuh --- kernel/trace/rv/rv_reactors.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index 2f5fc8d18dea..ff7d478227c3 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -465,7 +465,15 @@ int init_rv_reactors(struct dentry *root_dir) =20 void rv_react(struct rv_monitor *monitor, const char *msg, ...) { - static DEFINE_WAIT_OVERRIDE_MAP(rv_react_map, LD_WAIT_FREE); + /* + * Reactors must not explicitly take locks, so they should be + * LD_WAIT_FREE. However, reactor callbacks can run with preemption + * enabled, meaning the preempting code (e.g. the scheduler taking + * rq->__lock at LD_WAIT_SPIN) may violate that constraint. Use + * LD_WAIT_SPIN to avoid false-positive lockdep reports. + * But you should still NOT be using locks in reactors. + */ + static DEFINE_WAIT_OVERRIDE_MAP(rv_react_map, LD_WAIT_SPIN); va_list args; =20 if (!rv_reacting_on() || !monitor->react) --=20 2.25.1 From nobody Sun Sep 27 02:40:14 2026 Received: from mta0.migadu.com (out-86.mta0.migadu.com [91.218.175.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C69E43BB101 for ; Sun, 6 Sep 2026 17:10:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.86 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714661; cv=none; b=jFm0LWxSrjtwIbJ3vnDBx+i7N6VwblmlbMHm2EDHQcu5eMVBrmYpd4Cm1zm/nUH1pJVwsa3XMlAVWxMuBknqAck9ErEraFQwOh0P0V0gFfDX8WNKtcENbyvJLK/5Y5MauYTnjfO351mjBL58TtOcxQv//kLgCxc5sRI0vYECELM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714661; c=relaxed/simple; bh=xb99JgDGTtCItKyuxlPAFODc8L6TfNE8KIBXgN0TWUQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FfUrhkzWyiKTjN93BSrdyKXUMV5RF/wi9dVADK/OykVtK0sgUkaHpdf/huKHH6RELlLN/Ad1XcNjEpIVx6SzKYb2ZgjB7BKvl8+nF5VF9NBNFccxy7tCn/g16rZNVNJ/tiDuCncu6kIcuZoWAkKfxMTS+eC6zEn4k70sw6gKN3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=muy++HDq; arc=none smtp.client-ip=91.218.175.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="muy++HDq" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=xb99JgDGTtCItKyuxlPAFODc8L6TfNE8KIBXgN0TWUQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788714657; v=1; x=1789319457; b=muy++HDqtPp/VbrU4jemK634lmgD8ytWvE3UFxX0ptLpbcZkLMm+EMuJKdbQ043fs5TfpJCT Ih0fOOhvorEewrGmKQLrZZtE1lOdg3Ww2ngPcAg9A88sjR6zNCQFrVFde1rv4Nuiv5oMCWQtvPm 5QCbJCoJb1gY8ScURkYlTUxg= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 1c5e610d1f1f794a; Sun, 06 Sep 2026 17:10:57 +0000 X-Mizu-Trace-ID: 1c5e610d1f1f794a X-Migadu-Flow: FLOW_OUT From: wen.yang@linux.dev To: Gabriele Monaco Cc: Nam Cao , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Wen Yang Subject: [PATCH v5 2/5] rv/reactors: propagate rv_register_reactor() error from reactor init Date: Mon, 7 Sep 2026 01:10:38 +0800 Message-Id: X-Mailer: git-send-email 2.25.1 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" From: Wen Yang Both register_react_printk() and register_react_panic() ignore the return value of rv_register_reactor() and always return 0. If the registration fails (e.g. a duplicate reactor name), the init functions silently report success even though the reactor was not registered. Propagate the error from rv_register_reactor() so a failed registration is reported instead of being silently ignored. Reviewed-by: Gabriele Monaco Reviewed-by: Nam Cao Signed-off-by: Wen Yang --- kernel/trace/rv/reactor_panic.c | 3 +-- kernel/trace/rv/reactor_printk.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/trace/rv/reactor_panic.c b/kernel/trace/rv/reactor_pani= c.c index 76537b8a4343..db7116ceafff 100644 --- a/kernel/trace/rv/reactor_panic.c +++ b/kernel/trace/rv/reactor_panic.c @@ -26,8 +26,7 @@ static struct rv_reactor rv_panic =3D { =20 static int __init register_react_panic(void) { - rv_register_reactor(&rv_panic); - return 0; + return rv_register_reactor(&rv_panic); } =20 static void __exit unregister_react_panic(void) diff --git a/kernel/trace/rv/reactor_printk.c b/kernel/trace/rv/reactor_pri= ntk.c index 48c934e315b3..002a10f6aa7b 100644 --- a/kernel/trace/rv/reactor_printk.c +++ b/kernel/trace/rv/reactor_printk.c @@ -25,8 +25,7 @@ static struct rv_reactor rv_printk =3D { =20 static int __init register_react_printk(void) { - rv_register_reactor(&rv_printk); - return 0; + return rv_register_reactor(&rv_printk); } =20 static void __exit unregister_react_printk(void) --=20 2.25.1 From nobody Sun Sep 27 02:40:14 2026 Received: from mta1.migadu.com (out-240.mta1.migadu.com [95.215.58.240]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FC593BB68B for ; Sun, 6 Sep 2026 17:11:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.240 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714665; cv=none; b=sjuHVJiq2A6UAQDlkfmjJ+WQCRhj8+p9XQSQfQJOWuuMrxtUefjlBQsNmGYWen4HQljGHAbGTR+UvZI9laaTwZn32Btk0KwErf1vcXCZxF4iSf0IZRx5jSo5ipNK2dbzUJUIkUwpN/8sxrijxhZuvbRHI5lFMZ6kQd4fsi5pCPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714665; c=relaxed/simple; bh=f6LFDEMk6FYwVLxOrnUS1Rj4z2TLtUVaSD1UsKyXNRQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eyMDnEc7UyWsnqmqC6oMIQRT74DQ12mHVI8m+ZjP7w2KwVUGkW+isM0LNYnp0FrhBOrgtNRlX1ORQHiGuv+qDDK5HpZ8T8AAsVN/DQeXvxowg0kEQzbqulB/t4VOmacN8aWV43bwnlpBpVJSHxUf37EoBf7GGLXjdZ7P89BOErw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=dU3K+dzd; arc=none smtp.client-ip=95.215.58.240 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="dU3K+dzd" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=f6LFDEMk6FYwVLxOrnUS1Rj4z2TLtUVaSD1UsKyXNRQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788714661; v=1; x=1789319461; b=dU3K+dzdGq9jmAcS9Zw8v6cyktYL3n/olWOyTNiQ0J613s067uCiMtrGfrvLgHcoAYuo3sqp Cg8n/IBX0AtTHRRB9NnySnMJXBDLpOuh/h9+6E9okcfSg/KDZLffvMgD8tAlQ+b6nJSoBPLWE+8 YFQFgejOqc2uTf2uwV4I4RDQ= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 847577e6d7094564; Sun, 06 Sep 2026 17:11:01 +0000 X-Mizu-Trace-ID: 847577e6d7094564 X-Migadu-Flow: FLOW_OUT From: wen.yang@linux.dev To: Gabriele Monaco Cc: Nam Cao , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Wen Yang Subject: [PATCH v5 3/5] rv/reactors: export rv_register_reactor() and rv_unregister_reactor() Date: Mon, 7 Sep 2026 01:10:39 +0800 Message-Id: <7c931773dacd7c3da35a22629c3d7dc286b5a0fe.1788705281.git.wen.yang@linux.dev> X-Mailer: git-send-email 2.25.1 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" From: Wen Yang rv_react() is exported to modules, but the reactor registration helpers are not. Export them with EXPORT_SYMBOL_GPL() so reactor modules and the tristate KUnit test module can register and unregister reactors without hitting undefined symbol errors at link time(modpost). Commit 3d3800b4f7f4 ("rv: Remove reactor's reference counter") noted that if module-based reactors are supported, try_module_get()/module_put() should be used. Add struct module *owner to struct rv_reactor so a module cat set owner =3D THIS_MODULE; pin the module in monitor_swap_reactors_ging= le() and release it when a monitor detaches or is unregistered. In-tree reactors leave owner =3D NULL and are unaffected. Reviewed-by: Gabriele Monaco Signed-off-by: Wen Yang reviewed-by, so I can quickly see I need to review it again. --- include/linux/rv.h | 3 +++ kernel/trace/rv/rv.c | 5 +++++ kernel/trace/rv/rv_reactors.c | 38 +++++++++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/linux/rv.h b/include/linux/rv.h index 541ba404926a..ff3289ba4f02 100644 --- a/include/linux/rv.h +++ b/include/linux/rv.h @@ -128,10 +128,13 @@ union rv_task_monitor { }; =20 #ifdef CONFIG_RV_REACTORS +struct module; + struct rv_reactor { const char *name; const char *description; __printf(1, 0) void (*react)(const char *msg, va_list args); + struct module *owner; struct list_head list; }; #endif diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c index 29f155c6968b..458b17c005b3 100644 --- a/kernel/trace/rv/rv.c +++ b/kernel/trace/rv/rv.c @@ -803,6 +803,11 @@ int rv_unregister_monitor(struct rv_monitor *monitor) guard(mutex)(&rv_interface_lock); =20 rv_disable_monitor(monitor); +#ifdef CONFIG_RV_REACTORS + if (monitor->reactor) + module_put(monitor->reactor->owner); + +#endif list_del(&monitor->list); destroy_monitor_dir(monitor); =20 diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index ff7d478227c3..136eb7f47c4a 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -62,6 +62,7 @@ */ =20 #include +#include #include =20 #include "rv.h" @@ -159,7 +160,7 @@ static const struct seq_operations monitor_reactors_seq= _ops =3D { .show =3D monitor_reactor_show }; =20 -static void monitor_swap_reactors_single(struct rv_monitor *mon, +static int monitor_swap_reactors_single(struct rv_monitor *mon, struct rv_reactor *reactor, bool nested) { @@ -167,29 +168,39 @@ static void monitor_swap_reactors_single(struct rv_mo= nitor *mon, =20 /* nothing to do */ if (mon->reactor =3D=3D reactor) - return; + return 0; + + if (reactor->owner && !try_module_get(reactor->owner)) + return -EBUSY; =20 monitor_enabled =3D mon->enabled; if (monitor_enabled) rv_disable_monitor(mon); =20 + if (mon->reactor) + module_put(mon->reactor->owner); mon->reactor =3D reactor; mon->react =3D reactor->react; =20 /* enable only once if iterating through a container */ if (monitor_enabled && !nested) rv_enable_monitor(mon); + + return 0; } =20 -static void monitor_swap_reactors(struct rv_monitor *mon, struct rv_reacto= r *reactor) +static int monitor_swap_reactors(struct rv_monitor *mon, struct rv_reactor= *reactor) { struct rv_monitor *p =3D mon; + int ret; =20 if (rv_is_container_monitor(mon)) list_for_each_entry_continue(p, &rv_monitors_list, list) { if (p->parent !=3D mon) break; - monitor_swap_reactors_single(p, reactor, true); + ret =3D monitor_swap_reactors_single(p, reactor, true); + if (ret) + return ret; } /* * This call enables and disables the monitor if they were active. @@ -197,7 +208,7 @@ static void monitor_swap_reactors(struct rv_monitor *mo= n, struct rv_reactor *rea * All nested monitors are enabled also if they were off, we may refine * this logic in the future. */ - monitor_swap_reactors_single(mon, reactor, false); + return monitor_swap_reactors_single(mon, reactor, false); } =20 static ssize_t @@ -236,10 +247,14 @@ monitor_reactors_write(struct file *file, const char = __user *user_buf, guard(mutex)(&rv_interface_lock); =20 list_for_each_entry(reactor, &rv_reactors_list, list) { + int ret; + if (strcmp(ptr, reactor->name) !=3D 0) continue; =20 - monitor_swap_reactors(mon, reactor); + ret =3D monitor_swap_reactors(mon, reactor); + if (ret) + return ret; =20 return count; } @@ -314,6 +329,7 @@ int rv_register_reactor(struct rv_reactor *reactor) guard(mutex)(&rv_interface_lock); return __rv_register_reactor(reactor); } +EXPORT_SYMBOL_GPL(rv_register_reactor); =20 /** * rv_unregister_reactor - unregister a rv reactor. @@ -327,6 +343,7 @@ int rv_unregister_reactor(struct rv_reactor *reactor) list_del(&reactor->list); return 0; } +EXPORT_SYMBOL_GPL(rv_unregister_reactor); =20 /* * reacting_on interface. @@ -421,6 +438,15 @@ int reactor_populate_monitor(struct rv_monitor *mon, s= truct dentry *root) * Configure as the rv_nop reactor. */ mon->reactor =3D get_reactor_rdef_by_name("nop"); + if (WARN_ON(!mon->reactor)) { + rv_remove(tmp); + return -EINVAL; + } + + if (mon->reactor->owner && !try_module_get(mon->reactor->owner)) { + rv_remove(tmp); + return -EBUSY; + } =20 return 0; } --=20 2.25.1 From nobody Sun Sep 27 02:40:14 2026 Received: from mta1.migadu.com (out-241.mta1.migadu.com [95.215.58.241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D5093BB101 for ; Sun, 6 Sep 2026 17:11:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.241 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714667; cv=none; b=eQkJiLGR8jcw07QIV5QW7XiJYtGHZdJjXIv9DVXXPlECUl91Q8ezKs21SGAdRT22KAheBuYpmZPz8KoIBgXUmBFjQiVzW1sfLfNXjUZCc779WzSre5hWde7XtQmU2mpXupBxqvlYjNLnLLR9r77IFzt9pJZPfQP8c2n1Z2yt+14= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714667; c=relaxed/simple; bh=97qOxR95BvEhLUNVNSUNlYfU51gXbkrkpDOCNYqvOAQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kkH+6MaBwKsijBMUYAi3oSGHZ2OootDZPv3MWketxe3ikhCkBD8Fvqal68Wc2RMhEmZOPSy5kz5ThrZPrY0umkIfcyz9yQm0FYzYhoCqQr2IRZ12j08fBG0WPvQ+0XletExXHbUqG9EbIcoFFCo5XRY0HvKvkWOzuy50pkNZ+0U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=wXSTDedu; arc=none smtp.client-ip=95.215.58.241 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="wXSTDedu" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=97qOxR95BvEhLUNVNSUNlYfU51gXbkrkpDOCNYqvOAQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788714663; v=1; x=1789319463; b=wXSTDeduTwzSxUjpsFwMMbJzu2NHFivZYkvq2i4jw160UKDvpEDE8ix4M6+rJfL/CX7J57XD judU3mzP41gjMCr9uRG3aW4ljNZ36AuKKjdXIRi8yu3DS3pUZT0obSi7nJXZFDBtQZs7sUPKrSn 9fkRbH+C1QhAQW4c2yY5D/5g= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 8a0cdfe16dd5e2d6; Sun, 06 Sep 2026 17:11:03 +0000 X-Mizu-Trace-ID: 8a0cdfe16dd5e2d6 X-Migadu-Flow: FLOW_OUT From: wen.yang@linux.dev To: Gabriele Monaco Cc: Nam Cao , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Wen Yang Subject: [PATCH v5 4/5] rv/reactors: add KUnit tests for reactor registration and dispatch Date: Mon, 7 Sep 2026 01:10:40 +0800 Message-Id: <1262e72539bd8ebc66707eb6f6598549a48285f7.1788705281.git.wen.yang@linux.dev> X-Mailer: git-send-email 2.25.1 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" From: Wen Yang Add KUnit tests covering the reactor register/unregister lifecycle (including duplicate and name-length rejection) and rv_react() dispatch (a no-op without a callback, exactly one invocation with one). The mdelay() callback keeps the CPU busy so a timer interrupt lands inside rv_react()'s lockdep context, exercising the LD_WAIT_SPIN wait type from the previous patch; a spurious lockdep splat there would show up in the test output. The dispatch tests rely o reacting_on being enabled, since rv_react() returns early when it if off. Reviewed-by: Gabriele Monaco Signed-off-by: Wen Yang --- kernel/trace/rv/Kconfig | 12 +++ kernel/trace/rv/Makefile | 1 + kernel/trace/rv/rv_reactors_kunit.c | 110 ++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 kernel/trace/rv/rv_reactors_kunit.c diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig index efa930f94ea4..9bfd429ffdea 100644 --- a/kernel/trace/rv/Kconfig +++ b/kernel/trace/rv/Kconfig @@ -113,6 +113,18 @@ config RV_REACT_PANIC Enables the panic reactor. The panic reactor emits a printk() message if an exception is found and panic()s the system. =20 +config RV_REACTORS_KUNIT + tristate "KUnit tests for RV reactors" if !KUNIT_ALL_TESTS + depends on KUNIT + depends on RV_REACTORS + default KUNIT_ALL_TESTS + help + Enable KUnit tests for RV reactor registration and dispatch. + These tests verify the register/unregister lifecycle, duplicate + rejection, and that rv_react() correctly invokes callbacks. + + If unsure, say N. + config RV_MONITORS_KUNIT_TEST tristate "KUnit tests for RV monitors" if !KUNIT_ALL_TESTS depends on KUNIT && RV && RV_REACTORS diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile index cdbf68c84f5a..c895d81dfdad 100644 --- a/kernel/trace/rv/Makefile +++ b/kernel/trace/rv/Makefile @@ -25,4 +25,5 @@ obj-$(CONFIG_RV_MON_WAKEUP) +=3D monitors/wakeup/wakeup.o obj-$(CONFIG_RV_REACTORS) +=3D rv_reactors.o obj-$(CONFIG_RV_REACT_PRINTK) +=3D reactor_printk.o obj-$(CONFIG_RV_REACT_PANIC) +=3D reactor_panic.o +obj-$(CONFIG_RV_REACTORS_KUNIT) +=3D rv_reactors_kunit.o obj-$(CONFIG_RV_MONITORS_KUNIT_TEST) +=3D rv_monitors_test.o diff --git a/kernel/trace/rv/rv_reactors_kunit.c b/kernel/trace/rv/rv_react= ors_kunit.c new file mode 100644 index 000000000000..a408edcdde04 --- /dev/null +++ b/kernel/trace/rv/rv_reactors_kunit.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for RV reactor registration and dispatch. + * + * The dispatch tests rely on reacting_on beinng enabled, since rv_react() + * returns early when it is off. It is on by default when the suites run + * built-in; as a module, re-enable it if disabled via + * /sys/kerne/tracing/rv/reacting_on. + */ + +#include +#include +#include +#include "rv.h" + +static struct rv_reactor test_reactor =3D { + .name =3D "kunit_test_reactor", + .description =3D "KUnit test reactor", +}; + +static void reactor_teardown(void *arg) +{ + rv_unregister_reactor(&test_reactor); +} + +static void register_test_reactor(struct kunit *test) +{ + KUNIT_ASSERT_EQ(test, rv_register_reactor(&test_reactor), 0); + KUNIT_ASSERT_EQ(test, + kunit_add_action_or_reset(test, reactor_teardown, NULL), 0); +} + +static void test_double_register(struct kunit *test) +{ + register_test_reactor(test); + KUNIT_EXPECT_EQ(test, rv_register_reactor(&test_reactor), -EINVAL); +} + +static const char long_reactor_name[] =3D "kunit_reactor_name_too_long_xxx= _"; +_Static_assert(sizeof(long_reactor_name) - 1 >=3D MAX_RV_REACTOR_NAME_SIZE, + "long_reactor_name must be at least MAX_RV_REACTOR_NAME_SIZE chars= "); + +static void test_name_too_long(struct kunit *test) +{ + static struct rv_reactor long_reactor =3D { + .name =3D long_reactor_name, + }; + + KUNIT_EXPECT_EQ(test, rv_register_reactor(&long_reactor), -EINVAL); +} + +static struct kunit_case rv_reactor_registration_cases[] =3D { + KUNIT_CASE(test_double_register), + KUNIT_CASE(test_name_too_long), + {} +}; + +static struct kunit_suite rv_reactor_registration_suite =3D { + .name =3D "rv_reactor_registration", + .test_cases =3D rv_reactor_registration_cases, +}; + +static int react_call_count; + +__printf(1, 0) static void mock_react(const char *msg, va_list args) +{ + react_call_count++; + /* Busy-wait so a timer interrupt fires inside rv_react(). */ + mdelay(20); +} + +static void test_react_no_callback(struct kunit *test) +{ + struct rv_monitor monitor =3D { + .name =3D "kunit_null_react", + }; + + react_call_count =3D 0; + rv_react(&monitor, "no callback"); + + KUNIT_EXPECT_EQ(test, react_call_count, 0); +} + +static void test_react_callback_invoked(struct kunit *test) +{ + struct rv_monitor monitor =3D { + .name =3D "kunit_dispatch_monitor", + .react =3D mock_react, + }; + + react_call_count =3D 0; + rv_react(&monitor, "callback invocation test"); + KUNIT_EXPECT_EQ(test, react_call_count, 1); +} + +static struct kunit_case rv_react_dispatch_cases[] =3D { + KUNIT_CASE(test_react_no_callback), + KUNIT_CASE(test_react_callback_invoked), + {} +}; + +static struct kunit_suite rv_react_dispatch_suite =3D { + .name =3D "rv_react_dispatch", + .test_cases =3D rv_react_dispatch_cases, +}; + +kunit_test_suites(&rv_reactor_registration_suite, &rv_react_dispatch_suite= ); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit tests for RV reactor registration and dispatch"); --=20 2.25.1 From nobody Sun Sep 27 02:40:14 2026 Received: from mta1.migadu.com (out-243.mta1.migadu.com [95.215.58.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F5DF3BBFCA for ; Sun, 6 Sep 2026 17:11:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.243 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714670; cv=none; b=saVyGRa8yDkDsLLxwoZH5BlO0HqAb5EO5R+NdVtAkXVm9zGQ+P8R2eL8ID1pFfKlIQ4/RPHyVDYRI95SjvL0z4C4UT4Pfqmb4qcWyWBpjvw4cowtr0bCc4naY9xCPA8R2xtWSW4qAd8XssgxMvfsI7EUCmw50zcm6ue2ixGbCt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714670; c=relaxed/simple; bh=OW4UqLTrNI7q54EASlGxQ7moAEK5tuNqr5Zpl0Z108A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NeZhebesGUhF1Hl/iKA5nYoHBUGTVX5VbunICvqNGwEsKmDQhO4Wx7XA8RjqXEjVDG3uFQZd5hq2dvSKlNgpDWQjlFUYvxppkO5a9SssuIGji7ALx2k6idHpm/7+r5KlswPCoN56ntNAOnRMLfeZyusGrzoo64gwFt+BkL5hVO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=dzPaHW5s; arc=none smtp.client-ip=95.215.58.243 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="dzPaHW5s" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=OW4UqLTrNI7q54EASlGxQ7moAEK5tuNqr5Zpl0Z108A=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788714666; v=1; x=1789319466; b=dzPaHW5smGFPxu8zV1Xzgu49dvQ3Jf0TG0KSl1nSkPEMsilStQmOibAfoUkQF6LzHae2A3xq 7C/P8bRfz7Pr9N84/RInY1ni+djd/p8ON9V2o9WUtousaQ/IpHTLps5mu4T20AKFOUsetZuDG7k /q3RY5podOiHliBx3MgJAO54= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 4fb2ac31f6cbe7cb; Sun, 06 Sep 2026 17:11:06 +0000 X-Mizu-Trace-ID: 4fb2ac31f6cbe7cb X-Migadu-Flow: FLOW_OUT From: wen.yang@linux.dev To: Gabriele Monaco Cc: Nam Cao , linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Wen Yang Subject: [PATCH v5 5/5] selftests/verification: Test loadable module-based reactor Date: Mon, 7 Sep 2026 01:10:41 +0800 Message-Id: <8337c115db6ca718a0d442ad85f0d2d4eaa2422b.1788705281.git.wen.yang@linux.dev> X-Mailer: git-send-email 2.25.1 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" From: Wen Yang Add a selftest module that register an RV reactor and a test that exercises the module pinning: rmmod must fail while a monitor is attached to the reactor and succeed after it is detached. A trap unloads the module on failure so it does not break the next insmod. THe module is built through the kselftest TEST_GEN_MODS_DIR mechanism, like the livepatch selftests. Signed-off-by: Wen Yang --- tools/testing/selftests/verification/Makefile | 1 + tools/testing/selftests/verification/config | 2 + .../test.d/rv_reactor_loadable.tc | 46 +++++++++++++++++++ .../verification/test_modules/Makefile | 16 +++++++ .../test_modules/rv_test_reactor.c | 37 +++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 tools/testing/selftests/verification/test.d/rv_reactor_= loadable.tc create mode 100644 tools/testing/selftests/verification/test_modules/Makef= ile create mode 100644 tools/testing/selftests/verification/test_modules/rv_te= st_reactor.c diff --git a/tools/testing/selftests/verification/Makefile b/tools/testing/= selftests/verification/Makefile index aa8790c22a71..7ff7382d11f0 100644 --- a/tools/testing/selftests/verification/Makefile +++ b/tools/testing/selftests/verification/Makefile @@ -3,6 +3,7 @@ all: =20 TEST_PROGS :=3D verificationtest-ktap TEST_FILES :=3D test.d settings +TEST_GEN_MODS_DIR :=3D test_modules EXTRA_CLEAN :=3D $(OUTPUT)/logs/* =20 include ../lib.mk diff --git a/tools/testing/selftests/verification/config b/tools/testing/se= lftests/verification/config index 43072c1c38f4..ddd7581f07b9 100644 --- a/tools/testing/selftests/verification/config +++ b/tools/testing/selftests/verification/config @@ -1 +1,3 @@ CONFIG_RV=3Dy +CONFIG_MODULES=3Dy +CONFIG_MODULES_UNLOAD=3Dy diff --git a/tools/testing/selftests/verification/test.d/rv_reactor_loadabl= e.tc b/tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc new file mode 100644 index 000000000000..ff1691661521 --- /dev/null +++ b/tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc @@ -0,0 +1,46 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# description: Test a loadable module-based reactor +# requires: available_reactors insmod:program rmmod:program + +MODULE_KO=3D"$FTRACETEST_ROOT/test_modules/rv_test_reactor.ko" +[ -f "$MODULE_KO" ] || exit_unsupported +[ -f /proc/modules ] || exit_unsupported +monitor=3D$(ls monitors | head -n 1) +[ -n "$monitor" ] || exit_unsupported + +cleanup() { + if grep -q '^test_reactors$' available_reactors; then + echo nop > "monitors/$monitor/reactors" || true + rmmod rv_test_reactor || true + fi +} +trap cleanup EXIT + +test_loadable_reactor() { + local monitor=3D"$1" + + insmod "$MODULE_KO" + grep -q test_reactor available_reactors + + echo test_reactor > "monitors/$monitor/reactors" + grep -q "\[test_reactor\]" "monitors/$monitor/reactors" + + echo 1 > "monitors/$monitor/enable" + + if rmmod rv_test_reactor 2> /dev/null; then + echo "FAIL: rmmod succeeded while the reactor is attached to a monitor" + return 1 + fi + grep -q test_reactor available_reactors + + echo nop > "monitors/$monitor/reactors" + grep -q "\[nop\]" "monitors/$monitor/reactors" + grep -q 1 "monitors/$monitor/enable" + + echo 0 > "monitors/$monitor/enable" + rmmod rv_test_reactor + ! grep -q test_reactor available_reactors +} + +test_loadable_reactor "$monitor" diff --git a/tools/testing/selftests/verification/test_modules/Makefile b/t= ools/testing/selftests/verification/test_modules/Makefile new file mode 100644 index 000000000000..0af95207a9a9 --- /dev/null +++ b/tools/testing/selftests/verification/test_modules/Makefile @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 + +TESTMODS_DIR :=3D $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))= )) +KDIR ?=3D /lib/modules/$(shell uname -r)/build + +obj-m +=3D rv_test_reactor.o + +modules: +ifneq ("$(wildcard $(KDIR))", "") + $(Q)$(MAKE) -C $(KDIR) modules KBUILD_EXTMOD=3D$(TESTMODS_DIR) +endif + +clean: +ifneq ("$(wildcard $(KDIR))", "") + $(Q)$(MAKE) -C $(KDIR) clean KBUILD_EXTMOD=3D$(TESTMODS_DIR) +endif diff --git a/tools/testing/selftests/verification/test_modules/rv_test_reac= tor.c b/tools/testing/selftests/verification/test_modules/rv_test_reactor.c new file mode 100644 index 000000000000..a243df81fa52 --- /dev/null +++ b/tools/testing/selftests/verification/test_modules/rv_test_reactor.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Loadable RV reactor for the verification selftests. Register a + * reactor with owner =3D THIS_MODULE so the selftests can exercise the + * module pinning: unloading is refused while a monitor is attached + * to the reactor. + */ + +#include +#include + +__printf(1, 0) static void rv_test_reaction(const char *msg, va_list args) +{ +} + +static struct rv_reactor rv_test_reactor =3D { + .name =3D "test_reactor", + .description =3D "selftest reactor: exercise module-based reactors.", + .react =3D rv_test_reaction, + .owner =3D THIS_MODULE, +}; + +static int __init rv_test_reactor_init(void) +{ + return rv_register_reactor(&rv_test_reactor); +} + +static void __exit rv_test_reactor_exit(void) +{ + rv_unregister_reactor(&rv_test_reactor); +} + +module_init(rv_test_reactor_init); +module_exit(rv_test_reactor_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Loadable RV reactor for verification selftests"); --=20 2.25.1