From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 508332E62CD for ; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=PYpRe6neiONGUuS6mrgsJLW/Y02uxb6vz54VWCzHFXcH4YHX7rcBaxXBGtBVDLpaOshKtYpjNyeSmBCUIdcDpgBPJps/mZa5dpvXSlpvzwIOJX7NS+VPLLJx+Vy57qLdyvUxuUMJFtE1SaVMI7QUTl5ww4JOz8isXeq+oVyL610= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=OW4XttqWZSi/Drj8Nfcb9nRfI0qLGHAcFUjx8HdvV4A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XiPflhQwt3w2LoynLD9iZ2niTYBSCM/sRjlhoT2wgQMa2doThVWecKf375mNtQsv2eQZwbe/+L1hT1Ly2DblpU3vCZ0j+BQnH0hh9xGKPWhw5VNt/KqGmhCYimnJazedO5lDG34B2zS5aB6ip879qosr9RnmFOERx8xZxk2aOqI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Hjbi1ZNY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Hjbi1ZNY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BDEC5C4CEE3; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714916; bh=OW4XttqWZSi/Drj8Nfcb9nRfI0qLGHAcFUjx8HdvV4A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Hjbi1ZNYculHh5SMK5Q/HDA7ENHNgtVcvanSBRChWUcYPYkYkpFxjkq5GybYSxaAU qrzJmKIV+LxoG4uK+Nk+4f8pvUI5tjG+aACsGTqKNB4wi1ll/KUM9vT4nLv2FYu+0g L/QY42Co4juZbu0f87DJqj6wvMeRyOibNmKJp8wY5+8msn2jSOAfZY5TDD5u9sM2Uk KElgs61KcyDeJFrC17JZZOer2MbyYJbP8YjMvwNOfvuBHFMWvpvMSn3EIlCQjATk/K XHo+V/ZX44dChaE2j1Z7hOonTlOQgVxhOOT8K2kOVoM2U4+eHkvDSvVbgRHLfWgToP C8PtIWe88z99g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 96BE9CE0799; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky Subject: [PATCH RFC 1/9] ratelimit: Create functions to handle ratelimit_state internals Date: Thu, 3 Apr 2025 14:15:06 -0700 Message-Id: <20250403211514.985900-1-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" A number of ratelimit uses do open-coded access to the ratelimit_state structure's ->missed field. This works, but is a bit messy and makes it more annoying to make changes to this field. Therefore, provide a ratelimit_state_inc_miss() function that increments out the ->missed field ratelimit_state_get_miss() function that reads out the ->missed field of the specified ratelimit_state structure, and a ratelimit_state_reset_miss() function that reads out that field, but that also resets its value to zero. These functions will replace client-code open-coded uses of ->miss. In addition, a new ratelimit_state_reset_interval() encapsulates what was previously open-coded lock acquisition and resetting. [ paulmck: Apply kernel test robot feedback. ] Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Reviewed-by: Petr Mladek --- include/linux/ratelimit.h | 40 ++++++++++++++++++++++++++++++++++----- lib/ratelimit.c | 8 ++++---- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index b17e0cd0a30cf..8400c5356c187 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -22,16 +22,46 @@ static inline void ratelimit_default_init(struct rateli= mit_state *rs) DEFAULT_RATELIMIT_BURST); } =20 +static inline void ratelimit_state_inc_miss(struct ratelimit_state *rs) +{ + rs->missed++; +} + +static inline int ratelimit_state_get_miss(struct ratelimit_state *rs) +{ + return rs->missed; +} + +static inline int ratelimit_state_reset_miss(struct ratelimit_state *rs) +{ + int ret =3D rs->missed; + + rs->missed =3D 0; + return ret; +} + +static inline void ratelimit_state_reset_interval(struct ratelimit_state *= rs, int interval_init) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&rs->lock, flags); + rs->interval =3D interval_init; + rs->begin =3D 0; + rs->printed =3D 0; + ratelimit_state_reset_miss(rs); + raw_spin_unlock_irqrestore(&rs->lock, flags); +} + static inline void ratelimit_state_exit(struct ratelimit_state *rs) { + int m; + if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) return; =20 - if (rs->missed) { - pr_warn("%s: %d output lines suppressed due to ratelimiting\n", - current->comm, rs->missed); - rs->missed =3D 0; - } + m =3D ratelimit_state_reset_miss(rs); + if (m) + pr_warn("%s: %d output lines suppressed due to ratelimiting\n", current-= >comm, m); } =20 static inline void diff --git a/lib/ratelimit.c b/lib/ratelimit.c index ce945c17980b9..85e22f00180c5 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -51,12 +51,12 @@ int ___ratelimit(struct ratelimit_state *rs, const char= *func) rs->begin =3D jiffies; =20 if (time_is_before_jiffies(rs->begin + interval)) { - if (rs->missed) { + int m =3D ratelimit_state_reset_miss(rs); + + if (m) { if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { printk_deferred(KERN_WARNING - "%s: %d callbacks suppressed\n", - func, rs->missed); - rs->missed =3D 0; + "%s: %d callbacks suppressed\n", func, m); } } rs->begin =3D jiffies; --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 508902E62CF for ; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=pAsx3LNFoaQL6+3KO0IajZP10R+gR5z55Vxg2LWrfTrb2LMuKE+Ng1+M9d5pp3V3zuUlydHyz8eedTQjsXKUQLjtR4kAfizrRpza56FTujYEP+IReqbUPj7165a3lY2tR3BtAcfKOtiwVFdnSFdwSVg53p5TMaQUsomkuSt+NWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=3Bpfo4DQatNfIY3c7/fgBWsBW3JwZ3D48DIMz6i5ZiU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=L33tnEfnaSX+tDJEC7BdwZBnY4IijUfJtunV466RP1QM4a62gCMCOd0R1Efd/vwd5+OgHiHnGBFiWnY+fjkrXlFmSWUG2uAldIXktdnthUOBaK6Ew4fiwVOHzW3rvC6COc57Q0uWzAre5bSm9rdOCT88Q+8xE8+7NU1c7wz2e3k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HMjcpgg4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HMjcpgg4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CE46AC4CEE9; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714916; bh=3Bpfo4DQatNfIY3c7/fgBWsBW3JwZ3D48DIMz6i5ZiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HMjcpgg4+AfjLbVddSBj4VXPxD7c5aGFlx9cTWdwIHGE+f8FNHnFPwDp52SnRS6QV LcNeCHdstJjSaEyBiYek1SY94nmJnhjHTdiIbbjXuuTj52aQJqdkbq964ri4SF8glQ tBF9CARNTTK23JUuxjsNVgri27MzjqM7/YZRxRKb6thWAxaUEls+9hmNaqx84IGILK 22kknmtS5LUEaRoddmitDqhYoJBiWfTi2YxPHOlppFzXKsXmsUF+dbgakn62oRyViY QJo6SMPIi0asmz/ABIaRiVDE18sMyk6toH0iot1agRk3D6Sw4YUh5hZ6t6cQYSLoBa 215djR7qKemtQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 98DE9CE09BE; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , "Theodore Ts'o" Subject: [PATCH RFC 2/9] random: Avoid open-coded use of ratelimit_state structure's ->missed field Date: Thu, 3 Apr 2025 14:15:07 -0700 Message-Id: <20250403211514.985900-2-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The _credit_init_bits() function directly accesses the ratelimit_state structure's ->missed field, which work, but which also makes it more difficult to change this field. Therefore, make use of the ratelimit_state_get_miss() and ratelimit_state_inc_miss() functions instead of directly accessing the ->missed field. Signed-off-by: Paul E. McKenney Cc: "Theodore Ts'o" "Jason A. Donenfeld" Reviewed-by: Petr Mladek --- drivers/char/random.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 2581186fa61b7..cbd1692bf3f50 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -726,6 +726,7 @@ static void __cold _credit_init_bits(size_t bits) static DECLARE_WORK(set_ready, crng_set_ready); unsigned int new, orig, add; unsigned long flags; + int m; =20 if (!bits) return; @@ -748,9 +749,9 @@ static void __cold _credit_init_bits(size_t bits) wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN); pr_notice("crng init done\n"); - if (urandom_warning.missed) - pr_notice("%d urandom warning(s) missed due to ratelimiting\n", - urandom_warning.missed); + m =3D ratelimit_state_get_miss(&urandom_warning); + if (m) + pr_notice("%d urandom warning(s) missed due to ratelimiting\n", m); } else if (orig < POOL_EARLY_BITS && new >=3D POOL_EARLY_BITS) { spin_lock_irqsave(&base_crng.lock, flags); /* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */ @@ -1466,7 +1467,7 @@ static ssize_t urandom_read_iter(struct kiocb *kiocb,= struct iov_iter *iter) =20 if (!crng_ready()) { if (!ratelimit_disable && maxwarn <=3D 0) - ++urandom_warning.missed; + ratelimit_state_inc_miss(&urandom_warning); else if (ratelimit_disable || __ratelimit(&urandom_warning)) { --maxwarn; pr_notice("%s: uninitialized urandom read (%zu bytes read)\n", --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 508592E62CE for ; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=UIohDX0FScB9pAFCIp7wo6tXUddK4PBY2ZRHxkKe/p/m5m6eI5DX9DwsHc5mcLjva9ohMx6AgGqe8B5gxMMF9h+4I+HggPKhuNqdrrtjkdcL2GH3kYtc0pzvFhaVaItw/cOcfI5oqjGU6bF9DJksE7LyyK3gVL9CldrL/vnEFn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=+hz6Lt9eK0VnWHjtOAHlfl2JmWIwpKU2QhAqSPr3DC4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QmQ1aLXBlocqlqOqNQh84awIrKYV8ybw7Jebhz2u9uoxT4FuMLNSR8Vjf8eL6vpTh8BfuBCYIqkZUyVjD119EBjUUo04bjHPS3gSdS6YjoQ+2XJJ+MZag3KWW/e4OA6qXwdMEa4rl9YaqrAlBvdV5pbqiK1YsQ1LdESjC+XjTDs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IBdw/Vtt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IBdw/Vtt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CC2AEC4CEEA; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714916; bh=+hz6Lt9eK0VnWHjtOAHlfl2JmWIwpKU2QhAqSPr3DC4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IBdw/Vtt+K1fYwvlxBgSjY1CTLOhlYQaZCQQuN/WStvXTF//EqpSSL7VFNwGBmTR7 K8WB75u52q7sWFH3fQkfL3Xa7IMz2XIKzcx9pL24eGI1d+vMZksCKImV83t+hOb3VA J9zK1ZN+xqd2pqKQ4DBCqk0rpmK2OZDkvczIKuRigj52xoPr93/3iywSEjregKj1EP wDrHEHi0hszH6UV+FKVnPq5/5vDL7/5MdbKErSYsnqPWf3pBgpM0l67bGlydo1/TKU 0zHIOUNoH/6jn0RacPN1NWJsGWWdyci4ZCdw2HW1iujkrC2OSk2N1ZVGfLCGil8wF6 sstOpbxuNVI2w== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9B5C8CE09EE; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , Tvrtko Ursulin , David Airlie , Simona Vetter , intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH RFC 3/9] drm/i915: Avoid open-coded use of ratelimit_state structure's ->missed field Date: Thu, 3 Apr 2025 14:15:08 -0700 Message-Id: <20250403211514.985900-3-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The i915_oa_stream_destroy() function directly accesses the ratelimit_state structure's ->missed field, which work, but which also makes it more difficult to change this field. Therefore, make use of the ratelimit_state_get_miss() function instead of directly accessing the ->missed field. Signed-off-by: Paul E. McKenney Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: David Airlie Cc: Simona Vetter Cc: Cc: Reviewed-by: Petr Mladek --- drivers/gpu/drm/i915/i915_perf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_p= erf.c index 5384d1bb49233..a1ffb45a413b0 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -1663,6 +1663,7 @@ static void i915_oa_stream_destroy(struct i915_perf_s= tream *stream) struct i915_perf *perf =3D stream->perf; struct intel_gt *gt =3D stream->engine->gt; struct i915_perf_group *g =3D stream->engine->oa_group; + int m; =20 if (WARN_ON(stream !=3D g->exclusive_stream)) return; @@ -1687,10 +1688,9 @@ static void i915_oa_stream_destroy(struct i915_perf_= stream *stream) free_oa_configs(stream); free_noa_wait(stream); =20 - if (perf->spurious_report_rs.missed) { - gt_notice(gt, "%d spurious OA report notices suppressed due to ratelimit= ing\n", - perf->spurious_report_rs.missed); - } + m =3D ratelimit_state_get_miss(&perf->spurious_report_rs); + if (m) + gt_notice(gt, "%d spurious OA report notices suppressed due to ratelimit= ing\n", m); } =20 static void gen7_init_oa_buffer(struct i915_perf_stream *stream) --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5080B2E62BF for ; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=sgS4nBfJ9BYnIdQyt8tYp2XLtmdIdugag4gNIscGPqF4tJgs9KzRYhd8Pz3xnMNIOMO1RgWJG1Fkuz9/DmVlVxHCEw/N4ZQOrC7cZpiUvMd+XUVihzdx1jLgz+i7Cd/ZHb9hrIPSqrNa3nq4lXmwkyoF6O5BdJtF7arSMiTPJcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=4UdVmmVPfwx49eOtA9WGqhb1DLUQPHT/0m0UFvwzS+4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=WSeybR+o7yyHOwlqBbdCzq/OavYaMKU8N1gPYTE7PUhg4s5iSvqH9ythZBSJhGMTYs3Wns+jzQunb0qcW6NhdESKbagVSC9733BJ7iRCw8frhvzLbgEgNoaG2HJ0zoCFKCfMCxlHQG+6Hc1n1uReG39YMpBXt/sAD6fWsbo/aoM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VZgR4R2f; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VZgR4R2f" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C9A23C4CEE8; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714916; bh=4UdVmmVPfwx49eOtA9WGqhb1DLUQPHT/0m0UFvwzS+4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VZgR4R2foubZ/v5VPKKWMVB4Q+5WzqQS6CrS+G4tBeUemtxRb90IZZZgttSE+72Wa FEyU1YTag4I5gHW3aFDDDYgGku40+hIZczzNGkOfp2q+tTcCS9g6uExqwEA5jYnM3/ m2SI8/QvKCP/Ua5cgvSrL6FfWYOD1dJYpHkSfN0lv18TOQ3hE0si2aiHqAo+ceggSB 5jbxOo+rXZc0v382B/miu7brEwheyBj7JG4XqFg+Rp4DPYRq0nQiBT5i5V9Rk4lI+W kwF92d5pM6mWjBE6ngHd8CLyZezNGKY+47qZy4W9wt4Qu1s4pgqOvjBm8LloNZX6ne 8+2QF02VgLomQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9DD69CE0C98; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , kernel test robot , Kenneth Feng , Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= , Xinhui Pan , David Airlie , Simona Vetter , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH RFC 4/9] drm/amd/pm: Avoid open-coded use of ratelimit_state structure's internals Date: Thu, 3 Apr 2025 14:15:09 -0700 Message-Id: <20250403211514.985900-4-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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 The amdgpu_set_thermal_throttling_logging() function directly accesses the ratelimit_state structure's ->missed field, which work, but which also makes it more difficult to change this field. Therefore, make use of the ratelimit_state_reset_miss() function instead of directly accessing the ->missed field. Nevertheless, open-coded use of ->burst and ->interval is still permitted, for example, for runtime sysfs adjustment of these fields. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503180826.EiekA1MB-lkp@int= el.com/ Signed-off-by: Paul E. McKenney Cc: Kenneth Feng Cc: Alex Deucher Cc: "Christian K=C3=B6nig" Cc: Xinhui Pan Cc: David Airlie Cc: Simona Vetter Cc: Cc: Reviewed-by: Petr Mladek --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/am= dgpu_pm.c index e8ae7681bf0a3..6adf4e8822108 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -1663,7 +1663,6 @@ static ssize_t amdgpu_set_thermal_throttling_logging(= struct device *dev, struct drm_device *ddev =3D dev_get_drvdata(dev); struct amdgpu_device *adev =3D drm_to_adev(ddev); long throttling_logging_interval; - unsigned long flags; int ret =3D 0; =20 ret =3D kstrtol(buf, 0, &throttling_logging_interval); @@ -1674,18 +1673,12 @@ static ssize_t amdgpu_set_thermal_throttling_loggin= g(struct device *dev, return -EINVAL; =20 if (throttling_logging_interval > 0) { - raw_spin_lock_irqsave(&adev->throttling_logging_rs.lock, flags); /* * Reset the ratelimit timer internals. * This can effectively restart the timer. */ - adev->throttling_logging_rs.interval =3D - (throttling_logging_interval - 1) * HZ; - adev->throttling_logging_rs.begin =3D 0; - adev->throttling_logging_rs.printed =3D 0; - adev->throttling_logging_rs.missed =3D 0; - raw_spin_unlock_irqrestore(&adev->throttling_logging_rs.lock, flags); - + ratelimit_state_reset_interval(&adev->throttling_logging_rs, + (throttling_logging_interval - 1) * HZ); atomic_set(&adev->throttling_logging_enabled, 1); } else { atomic_set(&adev->throttling_logging_enabled, 0); --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 507D62E62A6 for ; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=eaOETgYlgYXTYPIyz8KkBSDx64guqAe9Wm2/31SqT0nLTJKrAxIcxnUy/yYA5OZlmeueapavnPLgJ/h6s7KHJKSfIGKtevsJD10yZcFtiBKa/kB3bVAITrFdgYnXP0CHLK9FvhLCnVt2iqTDgjQhM1crMUWq6+JEM5koy6nyxV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=2+F1hfYyUSHp5XVoCnxowVa/HEh8lIGm36K9Ci3o8eA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uuSu6hg9QN7nzznn+llDcgeSXE5nxFG/4TloVMaF4ktSjDU6eA39fsiO66jddY9ghEdM5ThGWqJIUP3SYKduMKc9vr5pyf3u33OhRjPeuL49T1zSRkdW+11ageMEL/ez5lu+WKYZSnO9Cy16s/wGOAS7JSk2w+R/hqVytUodFu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GEsFRuxJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GEsFRuxJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D36D2C4CEEC; Thu, 3 Apr 2025 21:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714916; bh=2+F1hfYyUSHp5XVoCnxowVa/HEh8lIGm36K9Ci3o8eA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GEsFRuxJ2g+ODHiYzgee+wmWVyg5jvCMneFQXWaNH8lW4vRjAeGN+xu8h3CjLb1qQ XMXeKVk4QcA86ika5NDwRuO8GiXDPNJH7KJL5ThHWBb/RytpMi5cw+VjkAEOWtV16m zGIpvhI0sqw+F0lDCtW/B7Qape8QzY8bO9OWXqVofptEb09lEGgoRebsEpdA2sHGNR KZZ87qa45hLxmL2gmYUjW0UiinrE5HeYr6ZtrMKzslvkkHkDyjfl+FsQLtpVORJ8Rk mNMzxP6SDp7lNCUVtVfWzbtZaptWL11V+2GQTY4d1zxvyqqTFRCfO+2fnTwk4EiDGw otXvCol7BVxYw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A0382CE0CF0; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky Subject: [PATCH RFC 5/9] ratelimit: Convert the ->missed field to atomic_t Date: Thu, 3 Apr 2025 14:15:10 -0700 Message-Id: <20250403211514.985900-5-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The ratelimit_state structure's ->missed field is sometimes incremented locklessly, and it would be good to avoid lost counts. This is also needed to count the number of misses due to try-lock failure. Therefore, convert the rratelimit_state structure's ->missed field to atomic_t. Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Reviewed-by: Petr Mladek --- include/linux/ratelimit.h | 9 +++------ include/linux/ratelimit_types.h | 2 +- lib/ratelimit.c | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index 8400c5356c187..c78b92b3e5cd8 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -24,20 +24,17 @@ static inline void ratelimit_default_init(struct rateli= mit_state *rs) =20 static inline void ratelimit_state_inc_miss(struct ratelimit_state *rs) { - rs->missed++; + atomic_inc(&rs->missed); } =20 static inline int ratelimit_state_get_miss(struct ratelimit_state *rs) { - return rs->missed; + return atomic_read(&rs->missed); } =20 static inline int ratelimit_state_reset_miss(struct ratelimit_state *rs) { - int ret =3D rs->missed; - - rs->missed =3D 0; - return ret; + return atomic_xchg_relaxed(&rs->missed, 0); } =20 static inline void ratelimit_state_reset_interval(struct ratelimit_state *= rs, int interval_init) diff --git a/include/linux/ratelimit_types.h b/include/linux/ratelimit_type= s.h index 765232ce0b5e9..d21fe82b67f67 100644 --- a/include/linux/ratelimit_types.h +++ b/include/linux/ratelimit_types.h @@ -18,7 +18,7 @@ struct ratelimit_state { int interval; int burst; int printed; - int missed; + atomic_t missed; unsigned int flags; unsigned long begin; }; diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 85e22f00180c5..18703f92d73e7 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -66,7 +66,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *= func) rs->printed++; ret =3D 1; } else { - rs->missed++; + ratelimit_state_inc_miss(rs); ret =3D 0; } raw_spin_unlock_irqrestore(&rs->lock, flags); --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9718A2E62D6 for ; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=MSoiVXDkP0kDnsIzpCFTsSWy1FRouP6F4QXoFz7YzmG+BzTmbwpSonVquePeh7m4yl5fNMxJfy6iEdyMcgy1LtOmK3L8w/O6meFaNs/3OJpkO9IJg0+Neh320KxN2tBsu8cZG+uDFDta1Zgtr8UljGkDCCm4ISjsuBgFjcoHofE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=S4zyoINK/k1VihcBkWzpPYAZOrOLyaqIzhpOR3LrUaE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sHz03L4MNvbLpxwgRGBxOaI11nSGDUqm2KyBQlFW+x+mjXYPdUMAiozlPVYQp69+vqR4b5gw20ncfEq5diZ3IG5uM2BjnUmmgZJZJhOPMWp7MaKYfplCfWeZi+ImGwGjldZ1rSa7gQjjhF3upRmxmQ+3EGa2vpcbWwrcLv5hfCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jzGkuS9w; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jzGkuS9w" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4848CC4CEED; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714917; bh=S4zyoINK/k1VihcBkWzpPYAZOrOLyaqIzhpOR3LrUaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jzGkuS9wkwuXNU0HP1n82gg1nGdKKcZtluT+XU4GMZER+yj+0gccV574vGinpC8F5 LUQ2zcKjc7BY+WS/T7P8DeJJP2unu1hZzKz/Sv0MRdGr2asq/IuUed8czpODtGlxNW WPG4pTfMxg6GN6eZWflC4eGVkr6wxWnnYo9vSCFq2bjdO/6IVonUl5z7k8jMEIIqLO qbiw4itjVhh7bCB5CSMQzqaiwxKuwCAL/UkNCTvh2Fi0Z7LC4fb17gwvFTKLdR5jwx IRRw+bYXVSC/PgGLSR0lec3KC/DIH0q0nOlDAZKH3TGu2iKD7Lf8+z8yYgRT/P39cV gm0aLWHmvR+oQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A2F7FCE0EDF; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky Subject: [PATCH RFC 6/9] ratelimit: Count misses due to lock contention Date: Thu, 3 Apr 2025 14:15:11 -0700 Message-Id: <20250403211514.985900-6-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The ___ratelimit() function simply returns zero ("do ratelimiting") if the trylock fails, but does not adjust the ->missed field. This means that the resulting dropped printk()s are dropped silently, which could seriously confuse people trying to do console-log-based debugging. Therefore, increment the ->missed field upon trylock failure. Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Reviewed-by: Petr Mladek --- lib/ratelimit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 18703f92d73e7..19ad3cdbd1711 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -44,8 +44,10 @@ int ___ratelimit(struct ratelimit_state *rs, const char = *func) * in addition to the one that will be printed by * the entity that is holding the lock already: */ - if (!raw_spin_trylock_irqsave(&rs->lock, flags)) + if (!raw_spin_trylock_irqsave(&rs->lock, flags)) { + ratelimit_state_inc_miss(rs); return 0; + } =20 if (!rs->begin) rs->begin =3D jiffies; --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 972052E62D8 for ; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=Td8gOF42A1vgTW0PoFEL6MNhvs5GpGvRFBsWfa27Kl/KpnES93AhU/z/B87MXRqGU86e6qxsTOKWapOg/RprHW+/wZvD0tZeVmapGQVy3/RPRUiLCRg2qaArVcOrQYAn6NeXWRLToTvEJPFk0GgmxnCcOpLCeK5PLrnPQTB1hmc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=j3yOGdgZ8xMCRP8ceU9TeIiJqrWt+5iLiJJkl91b5wM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QttjNB5LH/8RNNi1JYeK+jLonSOvUCIdkY3jFqZZLTVqWSOjdnC1rXBJKzqZSCkp9bNJ9HoeILrKu7acoV6NAN0+pkbDV5dkE6Q6z+Xi5/H05x+wEHNayV8R6ep42wQlYUnxL8U4Tc4Ahh5hB3k8Dbn/dGcTMsKT5To+0ehkauA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZqCoqiCz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZqCoqiCz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4933CC4CEEF; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714917; bh=j3yOGdgZ8xMCRP8ceU9TeIiJqrWt+5iLiJJkl91b5wM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZqCoqiCzpSef5aNYZrCvriPM8cciyqsIFMRZEnahuDwafH1WAOCHQQwxJWiGHFTnL A2W+m1FE6tnWGKnXHv98X3aRXNbdq8SehoGxVAPqh9lFUvVqeSIttkTogwX4yCN26K wsh3b7jXKVersPIKJsgmFap+aG4mwnha5LxdPmbiI8w6OUZFTZLVxI/OZX3r561DH9 GAgeJBMUFjkaOW5zxlHWeHny3JM8/9W56z6U4WBu06pPZI4ImAhSQrVEhEQ98a8som DaljLmHesjNLZlc6XlhhvRv5aQPo9pY25j2/a+LjBxbV8bh96uBABixYMOwu22b4R5 uysLdpIbVLVqg== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A5858CE0F64; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky Subject: [PATCH RFC 7/9] ratelimit: Avoid jiffies=0 special case Date: Thu, 3 Apr 2025 14:15:12 -0700 Message-Id: <20250403211514.985900-7-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The ___ratelimit() function special-cases the jiffies-counter value of zero as "uninitialized". This works well on 64-bit systems, where the jiffies counter is not going to return to zero for more than half a billion years on systems with HZ=3D1000, but similar 32-bit systems take less than 50 days to wrap the jiffies counter. And although the consequences of wrapping the jiffies counter seem to be limited to minor confusion on the duration of the rate-limiting interval that happens to end at time zero, it is almost no work to avoid this confusion. Therefore, introduce a RATELIMIT_INITIALIZED bit to the ratelimit_state structure's ->flags field so that a ->begin value of zero is no longer special. Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Reviewed-by: Petr Mladek --- include/linux/ratelimit.h | 2 +- include/linux/ratelimit_types.h | 1 + lib/ratelimit.c | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index c78b92b3e5cd8..adfec24061d16 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -43,7 +43,7 @@ static inline void ratelimit_state_reset_interval(struct = ratelimit_state *rs, in =20 raw_spin_lock_irqsave(&rs->lock, flags); rs->interval =3D interval_init; - rs->begin =3D 0; + rs->flags &=3D ~RATELIMIT_INITIALIZED; rs->printed =3D 0; ratelimit_state_reset_miss(rs); raw_spin_unlock_irqrestore(&rs->lock, flags); diff --git a/include/linux/ratelimit_types.h b/include/linux/ratelimit_type= s.h index d21fe82b67f67..ef6711b6b229f 100644 --- a/include/linux/ratelimit_types.h +++ b/include/linux/ratelimit_types.h @@ -11,6 +11,7 @@ =20 /* issue num suppressed message on exit */ #define RATELIMIT_MSG_ON_RELEASE BIT(0) +#define RATELIMIT_INITIALIZED BIT(1) =20 struct ratelimit_state { raw_spinlock_t lock; /* protect the state */ diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 19ad3cdbd1711..bd6e3b429e333 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -49,8 +49,10 @@ int ___ratelimit(struct ratelimit_state *rs, const char = *func) return 0; } =20 - if (!rs->begin) + if (!(rs->flags & RATELIMIT_INITIALIZED)) { rs->begin =3D jiffies; + rs->flags |=3D RATELIMIT_INITIALIZED; + } =20 if (time_is_before_jiffies(rs->begin + interval)) { int m =3D ratelimit_state_reset_miss(rs); --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AFAD82E62AF for ; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=dMWMR8/IS22f6EFaGJ3WPjfWScYeJ8PFpZX41ZXmg48/gFNZs/6YDQvjDRSEM0XZz5Ik3DrMcJOAgEITFT8ec6J19GPylHU0N6wVhh6k8Z2drDIdqcw4Z5tX1VSqUSn46AW2uZUiW7YhH3k/FBA8VNoVi8SmJ/lt36iiNUaAt1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=1FtdMy1Rhueyewfbz8XN7kT54xjPMjuYv3eXlpH+hqE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rzVq50oMngpGZ7FryaIdUKDOTp5bDGXm2R7vjcTdd1sbow40YDuiZiZfzlIdABobUoTfuxxwy7uGAVA8cCmExhafuar3OKHPKWj5JBa7Kl+1wwBy7M5BikP7ijXRkevA7A2lEiMan95I2S5E4fn4PyjeUNsUDo4ezwvo4R4swbc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sl5TeAHD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sl5TeAHD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 493BFC4AF0B; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714917; bh=1FtdMy1Rhueyewfbz8XN7kT54xjPMjuYv3eXlpH+hqE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sl5TeAHDmlIUwDvrQjdEjJRbdAAcD3gsD8afr9hunxvUf1nHqiyozI4c+KJdaiWIZ wgY6tQi207PVfM3X8+t5jErKCQmZUGI+aEQfiS0j8rgNh1yWxBOLBmJD6jK6sW05/V NcozV7+gLaAEneEyPJFeya1R4naDy07EAmsX1c3dhqg2YSxD8NIC18Je9t5Pq8rVO2 P/Nz2M5gT7znWY4nbhi/enJc52gNHDi5nT2IdWDUh2VbxHnlo2esAsuI2lEF9k2zBT 5Gt1n7bPT33tvOdk19vxsMQecnsNpS70hOmI2kA4unmKNnh7dt3GZ+wLjw6VH10rh/ BNeHXYK1kexrg== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A875ECE0FFA; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky , Jon Pan-Doh , Bjorn Helgaas , Karolina Stolarek Subject: [PATCH RFC 8/9] ratelimit: Reduce ratelimit's false-positive misses Date: Thu, 3 Apr 2025 14:15:13 -0700 Message-Id: <20250403211514.985900-8-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" The current ratelimit implementation can suffer from false-positive misses. That is, ___ratelimit() might return zero (causing the caller to invoke rate limiting, for example, by dropping printk()s) even when the current burst has not yet been consumed. This happens when one CPU holds a given ratelimit structure's lock and some other CPU concurrently invokes ___ratelimit(). The fact that the lock is a raw irq-disabled spinlock might make low-contention trylock failure seem unlikely, but vCPU preemption, NMIs, and firmware interrupts can greatly extend the trylock-failure window. Avoiding these false-positive misses is especially important when correlating console logged hardware failures with other information. Therefore, instead of attempting to acquire the lock on each call to ___ratelimit(), construct a lockless fastpath and only acquire the lock when retriggering (for the next burst) or when resynchronizing (due to either a long idle period or due to ratelimiting having been disabled). This reduces the number of lock-hold periods that can be extended by vCPU preemption, NMIs and firmware interrupts, but also means that these extensions must be of much longer durations (generally moving from milliseconds to seconds) before they can result in false-positive drops. In addition, the lockless fastpath gets a 10-20% speedup compared to the old fully locked code on my x86 laptop. Your mileage will of course vary depending on your hardware, workload, and configuration. [ paulmck: Apply feedback from Dan Carpenter. ] Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Cc: Jon Pan-Doh Cc: Bjorn Helgaas Cc: Karolina Stolarek Reviewed-by: Petr Mladek --- include/linux/ratelimit.h | 2 +- include/linux/ratelimit_types.h | 3 +- lib/ratelimit.c | 176 +++++++++++++++++++++++++------- 3 files changed, 144 insertions(+), 37 deletions(-) diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index adfec24061d16..7aaad158ee373 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -44,7 +44,7 @@ static inline void ratelimit_state_reset_interval(struct = ratelimit_state *rs, in raw_spin_lock_irqsave(&rs->lock, flags); rs->interval =3D interval_init; rs->flags &=3D ~RATELIMIT_INITIALIZED; - rs->printed =3D 0; + atomic_set(&rs->rs_n_left, rs->burst); ratelimit_state_reset_miss(rs); raw_spin_unlock_irqrestore(&rs->lock, flags); } diff --git a/include/linux/ratelimit_types.h b/include/linux/ratelimit_type= s.h index ef6711b6b229f..2f38345ffc1a5 100644 --- a/include/linux/ratelimit_types.h +++ b/include/linux/ratelimit_types.h @@ -18,7 +18,7 @@ struct ratelimit_state { =20 int interval; int burst; - int printed; + atomic_t rs_n_left; atomic_t missed; unsigned int flags; unsigned long begin; @@ -28,6 +28,7 @@ struct ratelimit_state { .lock =3D __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ .interval =3D interval_init, \ .burst =3D burst_init, \ + .rs_n_left =3D ATOMIC_INIT(burst_init), \ .flags =3D flags_init, \ } =20 diff --git a/lib/ratelimit.c b/lib/ratelimit.c index bd6e3b429e333..03704c6f8899e 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -26,55 +26,161 @@ */ int ___ratelimit(struct ratelimit_state *rs, const char *func) { - /* Paired with WRITE_ONCE() in .proc_handler(). - * Changing two values seperately could be inconsistent - * and some message could be lost. (See: net_ratelimit_state). - */ - int interval =3D READ_ONCE(rs->interval); + unsigned long begin; int burst =3D READ_ONCE(rs->burst); + int delta =3D 0; unsigned long flags; - int ret; - - if (!interval) - return 1; + bool gotlock =3D false; + bool initialized; + int interval =3D READ_ONCE(rs->interval); + unsigned long j; + int n_left; =20 /* - * If we contend on this state's lock then almost - * by definition we are too busy to print a message, - * in addition to the one that will be printed by - * the entity that is holding the lock already: + * If the burst or interval settings mark this ratelimit_state + * structure as disabled, then clear the RATELIMIT_INITIALIZED bit + * in ->flags to force resetting of the ratelimiting interval when + * this ratelimit_state structure is next re-enabled. */ - if (!raw_spin_trylock_irqsave(&rs->lock, flags)) { - ratelimit_state_inc_miss(rs); - return 0; + if (burst <=3D 0 || interval <=3D 0) { + if ((READ_ONCE(rs->flags) & RATELIMIT_INITIALIZED) && + raw_spin_trylock_irqsave(&rs->lock, flags)) { + if (READ_ONCE(rs->flags) & RATELIMIT_INITIALIZED) + smp_store_release(&rs->flags, rs->flags & ~RATELIMIT_INITIALIZED); + raw_spin_unlock_irqrestore(&rs->lock, flags); + } + return true; } =20 - if (!(rs->flags & RATELIMIT_INITIALIZED)) { - rs->begin =3D jiffies; - rs->flags |=3D RATELIMIT_INITIALIZED; + /* + * If this structure has just now been ratelimited, but not yet + * reset for the next rate-limiting interval, take an early and + * low-cost exit. + */ + if (atomic_read_acquire(&rs->rs_n_left) <=3D 0) /* Pair with release. */ + goto limited; + + /* + * If this structure is marked as initialized and has been + * recently used, pick up its ->begin field. Otherwise, pick up + * the current time and attempt to re-initialized the structure. + */ + j =3D jiffies; + initialized =3D smp_load_acquire(&rs->flags) & RATELIMIT_INITIALIZED; /* = Pair with release. */ + if (initialized) { + begin =3D READ_ONCE(rs->begin); + } else { + /* + * Uninitialized or long idle, so reset ->begin and + * mark initialized. If we fail to acquire the lock, + * let the lock holder do the work. + */ + begin =3D j; + if (raw_spin_trylock_irqsave(&rs->lock, flags)) { + if (!(READ_ONCE(rs->flags) & RATELIMIT_INITIALIZED)) { + begin =3D jiffies; + j =3D begin; + WRITE_ONCE(rs->begin, begin); + smp_store_release(&rs->flags, /* Pair with acquire. */ + rs->flags | RATELIMIT_INITIALIZED); + initialized =3D true; + } + raw_spin_unlock_irqrestore(&rs->lock, flags); + } } =20 - if (time_is_before_jiffies(rs->begin + interval)) { - int m =3D ratelimit_state_reset_miss(rs); + /* + * If this structure is still in the interval in which has + * already hit the rate limit, take an early and low-cost exit. + */ + if (initialized && time_before(begin - 2 * interval, j) && time_before(j,= begin)) + goto limited; =20 - if (m) { - if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { - printk_deferred(KERN_WARNING - "%s: %d callbacks suppressed\n", func, m); - } + /* + * Register another request, and take an early (but not low-cost) + * exit if rate-limiting just nowcame into effect. + */ + n_left =3D atomic_dec_return(&rs->rs_n_left); + if (n_left < 0) + goto limited; /* Just now started ratelimiting. */ + if (n_left > 0) { + /* + * Otherwise, there is not yet any rate limiting for the + * current interval, and furthermore there is at least one + * last count remaining. But check to see if initialization + * is required or if we have run off the end of the interval + * without rate limiting having been imposed. Either way, + * we eventually return @true to tell our caller to go ahead. + */ + if (initialized && + time_before(begin - interval, j) && time_before(j, begin + interval)) + return true; /* Nothing special to do. */ + if (!raw_spin_trylock_irqsave(&rs->lock, flags)) + return true; /* Let lock holder do special work. */ + interval =3D READ_ONCE(rs->interval); + begin =3D rs->begin; + initialized =3D smp_load_acquire(&rs->flags) & RATELIMIT_INITIALIZED; + if (interval <=3D 0 || + (initialized && + time_before(begin - interval, j) && time_before(j, begin + interval= ))) { + /* + * Someone else beat us to the special work, + * so release the lock and return. + */ + raw_spin_unlock_irqrestore(&rs->lock, flags); + return true; } - rs->begin =3D jiffies; - rs->printed =3D 0; + + /* We have the lock and will do initialization. */ + gotlock =3D true; + delta =3D -1; } - if (burst && burst > rs->printed) { - rs->printed++; - ret =3D 1; - } else { - ratelimit_state_inc_miss(rs); - ret =3D 0; + if (!gotlock) { + /* + * We get here if we got the last count (n_left =3D=3D 0), + * so that rate limiting is in effect for the next caller. + * We will return @true to tell our caller to go ahead, + * but first we acquire the lock and set things up for + * the next rate-limiting interval. + */ + raw_spin_lock_irqsave(&rs->lock, flags); + interval =3D READ_ONCE(rs->interval); + j =3D jiffies; + begin =3D rs->begin; + initialized =3D smp_load_acquire(&rs->flags) & RATELIMIT_INITIALIZED; + } + burst =3D READ_ONCE(rs->burst); + if (interval <=3D 0 || !initialized || + time_after(j, begin + interval) || time_after(begin - interval, j)) + begin =3D j; /* Long delay, reset interval. */ + else + begin +=3D interval; /* Next interval. */ + + /* + * If an acquire sees the value stored by either of these two + * store-release operations, it will also see the value from + * following store to ->begin, or from some later store. But not + * from any earlier now-obsolete earlier store to ->begin. + */ + WRITE_ONCE(rs->begin, begin); + atomic_set_release(&rs->rs_n_left, burst + delta); /* Pair with acquire.*/ + smp_store_release(&rs->flags, rs->flags | RATELIMIT_INITIALIZED); /* ^^^ = */ + + /* Print suppressed callback count if requested. */ + if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { + delta =3D ratelimit_state_reset_miss(rs); + if (delta) + printk_deferred(KERN_WARNING "%s: %d callbacks suppressed\n", func, del= ta); } raw_spin_unlock_irqrestore(&rs->lock, flags); + return true; =20 - return ret; +limited: + /* + * Count the number of rate-limited requests and tell the caller + * that this is a no-go. + */ + ratelimit_state_inc_miss(rs); + return false; } EXPORT_SYMBOL(___ratelimit); --=20 2.40.1 From nobody Fri Dec 19 22:07:25 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B033A4315C for ; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; cv=none; b=STCPq8Hnopq1idMYVyS72FK9DNkgkwVoyzozlVVHbfIj1kjDjtz1XEKkMNGRVqTiwhF8l4CLBtwzYHWsS3gJmkMCoykVoBEhzGZz9QlDsHMb6yjp8TtNpwObcSsKooeJSeWf1zLTccctDfMQdbqftXaKkzY9H5ZSLqdXFK8MYMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743714917; c=relaxed/simple; bh=JH4KSTZ+3aR7UCD0hbafpr1+1zcNSmk9+5u+ukE5vIk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iKB1cvLr4wL2NU6NjjHGmSYMvLYIywJM6u6dB9tZQnXeGhcncm228EzzLFEWxmCXQtn1qHAjW3d1gRxCkDhQZaUXLwv2KeK8clOLweWGMB9v+hvEtHPNixph6QACncD5scSrByqOFQpzhWVivVEFbj1BTx7QwVZoSxu8ZNIuCsE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R2iz6yvB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="R2iz6yvB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5315DC4CEEE; Thu, 3 Apr 2025 21:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743714917; bh=JH4KSTZ+3aR7UCD0hbafpr1+1zcNSmk9+5u+ukE5vIk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R2iz6yvBHHJnZuffa1/BCiskKIp0qyFTYKjtguZ3NYSzg9KqoSxe355jFJgbz/2zk nvWFwbUkOv+tmQpRd4cMdgJQjjNy+pYAHVWaj8H8TScsFHUxy4fAvW+Yx5jj1L4gJ5 LGj3u/pfeY35r4nc1q6F4g8Xhc9DtCvq4TwzeHGto3K3E8S0UYqHnVqhkMpE19VaAS N+fkmrzUa1u3B5hABak5uSRyKLwAglvb7xkE5l6kLvP8h3181Dp+7x5sqfSxzHljnU ShMuRzn0oU1dfKMYR21yQGrbA+1Ue0NDyxgdAWwOp3pBga+iWIBrQ3gxFPtqlK4QRM jF6f7ArBTtz2A== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id AB1A0CE0FFE; Thu, 3 Apr 2025 14:15:15 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, "Paul E. McKenney" , Andrew Morton , Shuah Khan , Kuniyuki Iwashima , Mateusz Guzik , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky , Jon Pan-Doh , Bjorn Helgaas , Karolina Stolarek Subject: [PATCH RFC 9/9] lib: Add trivial kunit test for ratelimit Date: Thu, 3 Apr 2025 14:15:14 -0700 Message-Id: <20250403211514.985900-9-paulmck@kernel.org> X-Mailer: git-send-email 2.40.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" Add a simple single-threaded smoke test for lib/ratelimit.c Signed-off-by: Paul E. McKenney Cc: Andrew Morton Cc: Shuah Khan Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Petr Mladek Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky Cc: Jon Pan-Doh Cc: Bjorn Helgaas Cc: Karolina Stolarek Reviewed-by: Petr Mladek --- lib/Kconfig.debug | 11 +++++++ lib/Makefile | 1 + lib/test_ratelimit.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 lib/test_ratelimit.c diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1af972a92d06f..4adbb9b93a6eb 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3166,6 +3166,17 @@ config TEST_OBJPOOL =20 If unsure, say N. =20 +config TEST_RATELIMIT + tristate "Test module for correctness and stress of ratelimit" if !KUNIT_= ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + This builds the "test_ratelimit" module that should be used + for correctness verification and concurrent testings of rate + limiting. + + If unsure, say N. + config INT_POW_TEST tristate "Integer exponentiation (int_pow) test" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/lib/Makefile b/lib/Makefile index d5cfc7afbbb82..21d45806c889c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -112,6 +112,7 @@ obj-$(CONFIG_TEST_REF_TRACKER) +=3D test_ref_tracker.o CFLAGS_test_fprobe.o +=3D $(CC_FLAGS_FTRACE) obj-$(CONFIG_FPROBE_SANITY_TEST) +=3D test_fprobe.o obj-$(CONFIG_TEST_OBJPOOL) +=3D test_objpool.o +obj-$(CONFIG_TEST_RATELIMIT) +=3D test_ratelimit.o =20 obj-$(CONFIG_TEST_FPU) +=3D test_fpu.o test_fpu-y :=3D test_fpu_glue.o test_fpu_impl.o diff --git a/lib/test_ratelimit.c b/lib/test_ratelimit.c new file mode 100644 index 0000000000000..3d6db9be6be22 --- /dev/null +++ b/lib/test_ratelimit.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include +#include + +/* a simple boot-time regression test */ + +#define TESTRL_INTERVAL (5 * HZ) +static DEFINE_RATELIMIT_STATE(testrl, TESTRL_INTERVAL, 3); + +#define test_ratelimited(test, expected) \ + KUNIT_ASSERT_EQ(test, ___ratelimit(&testrl, "test_ratelimit_smoke"), (exp= ected)); + +static void test_ratelimit_smoke(struct kunit *test) +{ + // Check settings. + KUNIT_ASSERT_GE(test, TESTRL_INTERVAL, 100); + + // Test normal operation. + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, false); + + schedule_timeout_idle(TESTRL_INTERVAL - 20); + test_ratelimited(test, false); + + schedule_timeout_idle(30); + test_ratelimited(test, true); + + schedule_timeout_idle(2 * TESTRL_INTERVAL); + test_ratelimited(test, true); + test_ratelimited(test, true); + + schedule_timeout_idle(TESTRL_INTERVAL - 20); + test_ratelimited(test, true); + schedule_timeout_idle(30); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, false); + + // Test disabling. + testrl.burst =3D 0; + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + + // Testing re-enabling. + testrl.burst =3D 3; + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, true); + test_ratelimited(test, false); + test_ratelimited(test, false); +} + +static struct kunit_case sort_test_cases[] =3D { + KUNIT_CASE(test_ratelimit_smoke), + {} +}; + +static struct kunit_suite ratelimit_test_suite =3D { + .name =3D "lib_ratelimit", + .test_cases =3D sort_test_cases, +}; + +kunit_test_suites(&ratelimit_test_suite); + +MODULE_DESCRIPTION("___ratelimit() KUnit test suite"); +MODULE_LICENSE("GPL"); --=20 2.40.1