ratelimit: Fix/allow use in atomic contexts
I'd like to use printk_ratelimit() in NMI context, but it's not robust right now due to spinlock usage in lib/ratelimit.c. If an NMI is unlucky enough to hit just that spot we might lock up trying to take the spinlock again. Fix that by using a trylock variant. If we contend on that lock we can genuinely skip the message because the state is just being accessed by another CPU (or by this CPU). ( We could use atomics for the suppressed messages field, but i doubt it matters in practice and it makes the code heavier. ) Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: David S. Miller <davem@davemloft.net> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
979f693def
commit
edaac8e316
1 changed files with 9 additions and 1 deletions
|
@ -28,7 +28,15 @@ int __ratelimit(struct ratelimit_state *rs)
|
||||||
if (!rs->interval)
|
if (!rs->interval)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
spin_lock_irqsave(&rs->lock, flags);
|
/*
|
||||||
|
* If we contend on this state's lock then almost
|
||||||
|
* by definition we are too busy to print a message,
|
||||||
|
* in addition to the one that will be printed by
|
||||||
|
* the entity that is holding the lock already:
|
||||||
|
*/
|
||||||
|
if (!spin_trylock_irqsave(&rs->lock, flags))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (!rs->begin)
|
if (!rs->begin)
|
||||||
rs->begin = jiffies;
|
rs->begin = jiffies;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue