[PATCH v3 13/20] ratelimit: Avoid atomic decrement if already rate-limited
From: Paul E. McKenney
Date: Thu Apr 24 2025 - 20:29:55 EST
Currently, if the lock could not be 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. This 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.
Link: https://lore.kernel.org/all/fbe93a52-365e-47fe-93a4-44a44547d601@paulmck-laptop/
Link: https://lore.kernel.org/all/20250423115409.3425-1-spasswolf@xxxxxx/
Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
Reviewed-by: Petr Mladek <pmladek@xxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Kuniyuki Iwashima <kuniyu@xxxxxxxxxx>
Cc: Mateusz Guzik <mjguzik@xxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: John Ogness <john.ogness@xxxxxxxxxxxxx>
Cc: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>
---
lib/ratelimit.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index ebffcfb049949..747a5a7787705 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -65,8 +65,10 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
unsigned int rs_flags = READ_ONCE(rs->flags);
if (rs_flags & RATELIMIT_INITIALIZED && burst) {
- int n_left;
+ int n_left = atomic_read(&rs->rs_n_left);
+ if (n_left <= 0)
+ return 0;
n_left = atomic_dec_return(&rs->rs_n_left);
if (n_left >= 0)
return 1;
--
2.40.1