Skip to content

Commit 96d3660

Browse files
committed
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/[email protected]/ Signed-off-by: Paul E. McKenney <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Kuniyuki Iwashima <[email protected]> Cc: Mateusz Guzik <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: John Ogness <[email protected]> Cc: Sergey Senozhatsky <[email protected]>
1 parent 123a1d9 commit 96d3660

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

lib/ratelimit.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,16 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
103103
}
104104
}
105105
if (burst) {
106-
int n_left;
106+
int n_left = atomic_read(&rs->rs_n_left);
107107

108108
/* The burst might have been taken by a parallel call. */
109-
n_left = atomic_dec_return(&rs->rs_n_left);
110-
if (n_left >= 0) {
111-
ret = 1;
112-
goto unlock_ret;
109+
110+
if (n_left > 0) {
111+
n_left = atomic_dec_return(&rs->rs_n_left);
112+
if (n_left >= 0) {
113+
ret = 1;
114+
goto unlock_ret;
115+
}
113116
}
114117
}
115118

0 commit comments

Comments
 (0)