From: Paul E. McKenney Date: Wed, 16 Apr 2025 16:34:14 +0000 (-0700) Subject: ratelimit: Avoid atomic decrement under lock if already rate-limited X-Git-Tag: v6.16-rc1~178^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96d366048fed6a70accf4ddb55c4c65ab27aa48f;p=thirdparty%2Fkernel%2Flinux.git 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. 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 Reviewed-by: Petr Mladek Cc: Andrew Morton Cc: Kuniyuki Iwashima Cc: Mateusz Guzik Cc: Steven Rostedt Cc: John Ogness Cc: Sergey Senozhatsky --- diff --git a/lib/ratelimit.c b/lib/ratelimit.c index a7aaebb7a7189..ab8472edeb1d2 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -103,13 +103,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; + } } }