[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250418171359.1187719-14-paulmck@kernel.org>
Date: Fri, 18 Apr 2025 10:13:59 -0700
From: "Paul E. McKenney" <paulmck@...nel.org>
To: linux-kernel@...r.kernel.org
Cc: kernel-team@...a.com,
Andrew Morton <akpm@...ux-foundation.org>,
Kuniyuki Iwashima <kuniyu@...zon.com>,
Mateusz Guzik <mjguzik@...il.com>,
Petr Mladek <pmladek@...e.com>,
Steven Rostedt <rostedt@...dmis.org>,
John Ogness <john.ogness@...utronix.de>,
Sergey Senozhatsky <senozhatsky@...omium.org>,
Jon Pan-Doh <pandoh@...gle.com>,
Bjorn Helgaas <bhelgaas@...gle.com>,
Karolina Stolarek <karolina.stolarek@...cle.com>,
"Paul E. McKenney" <paulmck@...nel.org>
Subject: [PATCH v2 ratelimit 14/14] ratelimit: Avoid atomic decrement under lock if already rate-limited
Currently, if the lock is acquired, the code unconditionally does
an atomic decrement on ->rs_n_left, even if that atomic operation is
guaranteed to return a limit-rate verdict. A limit-rate verdict will
in fact be the common case when something is spewing into a rate limit.
This unconditional atomic operation incurs needless overhead and also
raises the spectre of counter wrap.
Therefore, do the atomic decrement only if there is some chance that
rates won't be limited.
Signed-off-by: Paul E. McKenney <paulmck@...nel.org>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Kuniyuki Iwashima <kuniyu@...zon.com>
Cc: Mateusz Guzik <mjguzik@...il.com>
Cc: Petr Mladek <pmladek@...e.com>
Cc: Steven Rostedt <rostedt@...dmis.org>
Cc: John Ogness <john.ogness@...utronix.de>
Cc: Sergey Senozhatsky <senozhatsky@...omium.org>
---
lib/ratelimit.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 2048f20561f31..0603b2ecd63f3 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -98,13 +98,16 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
}
}
if (burst) {
- int n_left;
+ int n_left = atomic_read(&rs->rs_n_left);
/* The burst might have been taken by a parallel call. */
- n_left = atomic_dec_return(&rs->rs_n_left);
- if (n_left >= 0) {
- ret = 1;
- goto unlock_ret;
+
+ if (n_left > 0) {
+ n_left = atomic_dec_return(&rs->rs_n_left);
+ if (n_left >= 0) {
+ ret = 1;
+ goto unlock_ret;
+ }
}
}
--
2.40.1
Powered by blists - more mailing lists