diff options
-rw-r--r-- | lib/ratelimit.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 7a7ba4835639..7d4f4e241213 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -35,11 +35,24 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) unsigned long flags; int ret; + /* + * Zero interval says never limit, otherwise, non-positive burst + * says always limit. + */ if (interval <= 0 || burst <= 0) { ret = interval == 0 || burst > 0; + if (!(READ_ONCE(rs->flags) & RATELIMIT_INITIALIZED) || (!interval && !burst) || + !raw_spin_trylock_irqsave(&rs->lock, flags)) { + if (!ret) + ratelimit_state_inc_miss(rs); + return ret; + } + + /* Force re-initialization once re-enabled. */ + rs->flags &= ~RATELIMIT_INITIALIZED; if (!ret) ratelimit_state_inc_miss(rs); - return ret; + goto unlock_ret; } /* |