From nobody Mon Sep 28 01:55:30 2026 Received: from mta1.migadu.com (out-217.mta1.migadu.com [95.215.58.217]) (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 905F71FC0 for ; Thu, 27 Aug 2026 18:23:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.217 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854989; cv=none; b=spdkVsMcH/f5a+4d5vXi8PuMSUsLg7qbQDknC8R04n6ysdUP6VmtClrZVwWOMJNBvZHreXDzaRs7KO9p6koo7W74t4pAH1b//4dXsMsDCX7Gu5X5ej352WMN2jBeYsa5rAPPqmd+Oz0ztjoCJvofRExqPb5uL9aQNy0MkBo0AMk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854989; c=relaxed/simple; bh=8cCS/yHD0Hxn9OGFpeTmmVcyFPIB1KOkunFFvBFQ880=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=RXewHbjKeoIi7zRx/3wUA4RZWh+HBIC6KTAOHPuBD5n36oaq2pavXNAv4n+1Ur5Pq+PIa72TwBNjaeFw0fTOsOJZKTblJR6TGOlC1LthYXnX1ZH2nieQOohr0IVR9n3GTfsWqurSFXmQBA9NZJxlL93DF2dvNEyuG4Yx5Pi8X2o= 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=HV+iovnn; arc=none smtp.client-ip=95.215.58.217 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="HV+iovnn" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=8cCS/yHD0Hxn9OGFpeTmmVcyFPIB1KOkunFFvBFQ880=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787854983; v=1; x=1788459783; b=HV+iovnnYiFMRsuW2VgmY4ab6e6nlmPsBITnW9eXaTPpW6ruBiKp9EXlSCOFL0bQ2AqEEVQD tPE/JSRL0j+TDsms/2s5rIsaJVCd+y9xDOjJw72xb3AcHs2yINUvG4I95cNlj8Uz02qqfuQyoSw wx17/fYBQTeTNkT7qmqEKOAU= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 293872663368d0fc; Thu, 27 Aug 2026 18:23:03 +0000 X-Mizu-Trace-ID: 293872663368d0fc 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 v4 1/4] rv/reactors: use LD_WAIT_SPIN as the reactor lockdep wait type Date: Fri, 28 Aug 2026 02:22:43 +0800 Message-Id: <7bfe97bd497a2641de36b35e17f69e6f3f291c2a.1787854397.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-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 --- Documentation/trace/rv/monitor_synthesis.rst | 20 ++++++++++++++++++++ kernel/trace/rv/rv_reactors.c | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Documentation/trace/rv/monitor_synthesis.rst b/Documentation/t= race/rv/monitor_synthesis.rst index 2c1b5a0ae154..aab4b0342d5f 100644 --- a/Documentation/trace/rv/monitor_synthesis.rst +++ b/Documentation/trace/rv/monitor_synthesis.rst @@ -365,6 +365,26 @@ but higher overhead. The timer wheel (``HA_TIMER_WHEEL= ``) is a good alternative for monitors with several instances (e.g. per-task) that achieves lower overhead with increased latency, yet without compromising precision. =20 +Reactors +-------- + +A reactor is a callback triggered by a monitor when a violation is +detected. Reactors are registered via ``/sys/kernel/tracing/rv/reactors/`` +and enabled per monitor. + +Reactor Locking Rules ++++++++++++++++++++++ + +A reactor callback may be invoked from various contexts (process, +softirq, hardirq, NMI) depending on the tracepoint to which its +monitor is attached. + +Lockdep uses a fixed wait type: ``LD_WAIT_SPIN``. This allows +``raw_spinlock_t`` but disallows sleepable locks. ``LD_WAIT_FREE`` is +not viable in preemptible contexts because scheduler preemption takes +``rq->__lock`` (``LD_WAIT_SPIN``), which would cause false-positive +warnings. + Final remarks ------------- =20 diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index 2f5fc8d18dea..afc97d097109 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -465,7 +465,11 @@ 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); + /* + * Use LD_WAIT_SPIN uniformly for deterministic lockdep checking. + * See Documentation/trace/rv/runtime-verification.rst. + */ + 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 Mon Sep 28 01:55:30 2026 Received: from mta0.migadu.com (out-15.mta0.migadu.com [91.218.175.15]) (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 4DF60499F11 for ; Thu, 27 Aug 2026 18:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854991; cv=none; b=anKcj+ynTvRBt6iRRlDyNpLOga47VST2yagasW0OCKQt7uI9vpnspVyHmm0Aq3h7JImuhl9DN9JOAmcOO9to9dW8Iv9R592hT3XtwG1PDGjkSl6cyl/KA0P6fh0T3+KfUlqKXMQfrLruFmESEiS/dbbvvm9+2Rq29gQWuR6bbdg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854991; c=relaxed/simple; bh=xb99JgDGTtCItKyuxlPAFODc8L6TfNE8KIBXgN0TWUQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mPt9PUjh0SSSsyUJ/jUh57TZ6cCfyVR3SEHMDg1yzjP2OaIpYEnaG+413HgVu9rqOQBYGUdgvaXylsUldphCghj108WWBMLufF8IQIiz2ynKizFfDoA4GVu897GlIHXUUe4c93hurJHczky6YPUgGeheYJCwUipRPDt6Bax9UfE= 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=PdS1hFgT; arc=none smtp.client-ip=91.218.175.15 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="PdS1hFgT" 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=1787854986; v=1; x=1788459786; b=PdS1hFgTN9o8N1NH3DiyiwbgIkId+ekz1g/47QL1oIOCKGS/at00Lp+apW8+T6Y9GHjtJnq+ qhyuU+CPAnm444mEhiYN6+H7n0F/TsgbEwuSixWMsUXxH50yNR/Jz6a7DlsvGbgID47kj5sCgGO IYleiJwY7P5SUdMc8j4i1l4Q= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 94ff23ca2328d543; Thu, 27 Aug 2026 18:23:06 +0000 X-Mizu-Trace-ID: 94ff23ca2328d543 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 v4 2/4] rv/reactors: propagate rv_register_reactor() error from reactor init Date: Fri, 28 Aug 2026 02:22:44 +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 Mon Sep 28 01:55:30 2026 Received: from mta0.migadu.com (out-17.mta0.migadu.com [91.218.175.17]) (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 C163F1FC0 for ; Thu, 27 Aug 2026 18:23:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854997; cv=none; b=JlqJBoi107yBQn2elPUpILpC5c5j2sVz3vRol9DUkmbzoOwbuXj/KhrNVQHCEUO84l4+okTpgIuOAPzaLxpcDmeMy/Rwbk4mCFiJr2kl1HceiJp8IKIISQ/Kw7Jc8Sgq8KwydRucKs/iGOnLrD/Nitn6WQ+MoqSshEU/lhuKnsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854997; c=relaxed/simple; bh=oZCQnmaMY7RmKSo6gOlFToZcdvtgy5XfSLCCNn/8tEo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YJhax5iZWId2FKAVlCw8NqqN83ksMZrg1LRqp6Y+HOHp680XNAXpPIW/eC8MuAQ2wJOYYUPehmmBjyeUjyWBeyYM/x0+F2NXD7LevV+oyIB0wehWTUHX4+xMl7tQLGZchzFMMMykKiKnKEx0nnIMRrOhpOaJXDQSZ0jKKPNX91M= 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=bj1UVUjV; arc=none smtp.client-ip=91.218.175.17 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="bj1UVUjV" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=oZCQnmaMY7RmKSo6gOlFToZcdvtgy5XfSLCCNn/8tEo=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787854993; v=1; x=1788459793; b=bj1UVUjVgGcDcoLJT1boMRZpeLxzH3z3w58+JuonyeE73pz3BXAb8hpuFNiFncO7p/FjFHup X7bkXEbqW3G5R97FF+g/rDYmpDsQm3xo7OJGF/0vMh/z8tzgog68UMWsragQg22F2PMvVSTIWV2 Em7xBFaau1ElThYBPnVY31g0= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 4e58507071cf7aed; Thu, 27 Aug 2026 18:23:13 +0000 X-Mizu-Trace-ID: 4e58507071cf7aed 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 v4 3/4] rv/reactors: export rv_register_reactor() and rv_unregister_reactor() Date: Fri, 28 Aug 2026 02:22:45 +0800 Message-Id: <888aca9131b5e9c80ac5085f964099b5090e7185.1787854397.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). Reviewed-by: Gabriele Monaco Signed-off-by: Wen Yang --- kernel/trace/rv/rv_reactors.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index afc97d097109..606c530de2f0 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -314,6 +314,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 +328,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. --=20 2.25.1 From nobody Mon Sep 28 01:55:30 2026 Received: from mta0.migadu.com (out-18.mta0.migadu.com [91.218.175.18]) (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 BFF413DCDBC for ; Thu, 27 Aug 2026 18:23:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854999; cv=none; b=UXq9UyRSR6l0nTPnENS32FmJ1J0t1aiFFwHu+qdBDZSrXRKOFlNUp8OL3FuRvHtT9S0nVAX6HLurYNmki1mjOePz7+gz09UOBzP38YNCl0tQULv1cP+4OutFMtMLrmul3t4rbU7OWnOsxnPbdER+1oeyojqGw3UVnpLq8SnJwv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787854999; c=relaxed/simple; bh=oHPCXF7JgvUkyyf6uF5a4JEpbpTZhJHx4pcplb6yknc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RjPRb1ehCkYd6LShbqvGlNTnHS02z037OvUlHOGvIwvLyK458R9r20JVh6bNBBNiUesS1HKmsJQFmtXdu3v3pwPlUknL6xz6wLJd8PeElxwWWfNxovM8whw5PVkv5fzsyP0QNH5bVMEYmZCF9zzaug2HFh+sGr0hu9SQy2uKZFU= 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=ubwIX/lf; arc=none smtp.client-ip=91.218.175.18 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="ubwIX/lf" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=oHPCXF7JgvUkyyf6uF5a4JEpbpTZhJHx4pcplb6yknc=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787854995; v=1; x=1788459795; b=ubwIX/lfFf3lwnFe0Vf42r7nC361NNnzdBWeorpeKr84tg+g5g2Ou9MbABQsSgl0Ps/4n91y BgQLheuPh/0bxOSv9uhRvVOf89qshpfIhbl7bGW/Z1CBUYfZ/rtWYpqFr4iOGI5c35t1gHVg6jv Qol+eJdC9YgLoho3sjzqznQ8= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta11.migadu.com with ESMTPS id 28f2f9d6a0f5d900; Thu, 27 Aug 2026 18:23:15 +0000 X-Mizu-Trace-ID: 28f2f9d6a0f5d900 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 v4 4/4] rv/reactors: add KUnit tests for reactor registration and dispatch Date: Fri, 28 Aug 2026 02:22:46 +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 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. 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 | 105 ++++++++++++++++++++++++++++ 3 files changed, 118 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..2ccbe55ce408 --- /dev/null +++ b/kernel/trace/rv/rv_reactors_kunit.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for RV reactor registration and dispatch. + */ + +#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(5); +} + +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