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
|
@ -28,7 +28,15 @@ int __ratelimit(struct ratelimit_state *rs)
|
|||
if (!rs->interval)
|
||||
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)
|
||||
rs->begin = jiffies;
|
||||
|
||||
|
|
Loading…
Reference in New Issue