]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ratelimit: Avoid atomic decrement if already rate-limited
authorPaul E. McKenney <paulmck@kernel.org>
Mon, 14 Apr 2025 22:43:47 +0000 (15:43 -0700)
committerPaul E. McKenney <paulmck@kernel.org>
Thu, 8 May 2025 23:13:27 +0000 (16:13 -0700)
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@web.de/
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: John Ogness <john.ogness@linutronix.de>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
lib/ratelimit.c

index 4e520d029d28f08feb621fbc96409a2d7c590362..a7aaebb7a7189ff594b4b79ea39468bf862c114b 100644 (file)
@@ -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;