2008-04-29 11:59:43 +04:00
/*
* ratelimit . c - Do something with rate limit .
*
* Isolated from kernel / printk . c by Dave Young < hidave . darkstar @ gmail . com >
*
2008-07-25 12:45:58 +04:00
* 2008 - 05 - 01 rewrite the function and use a ratelimit_state data struct as
* parameter . Now every user can use their own standalone ratelimit_state .
*
2008-04-29 11:59:43 +04:00
* This file is released under the GPLv2 .
*
*/
# include <linux/kernel.h>
# include <linux/jiffies.h>
# include <linux/module.h>
2008-07-25 12:45:58 +04:00
static DEFINE_SPINLOCK ( ratelimit_lock ) ;
2008-04-29 11:59:43 +04:00
/*
* __ratelimit - rate limiting
2008-07-25 12:45:58 +04:00
* @ rs : ratelimit_state data
2008-04-29 11:59:43 +04:00
*
2008-07-25 12:45:58 +04:00
* This enforces a rate limit : not more than @ rs - > ratelimit_burst callbacks
* in every @ rs - > ratelimit_jiffies
2008-04-29 11:59:43 +04:00
*/
2008-07-25 12:45:58 +04:00
int __ratelimit ( struct ratelimit_state * rs )
2008-04-29 11:59:43 +04:00
{
2008-07-29 02:46:21 +04:00
unsigned long flags ;
2008-07-25 12:45:58 +04:00
if ( ! rs - > interval )
return 1 ;
2008-04-29 11:59:43 +04:00
spin_lock_irqsave ( & ratelimit_lock , flags ) ;
2008-07-25 12:45:58 +04:00
if ( ! rs - > begin )
rs - > begin = jiffies ;
2008-04-29 11:59:43 +04:00
2008-07-25 12:45:58 +04:00
if ( time_is_before_jiffies ( rs - > begin + rs - > interval ) ) {
if ( rs - > missed )
printk ( KERN_WARNING " %s: %d callbacks suppressed \n " ,
__func__ , rs - > missed ) ;
rs - > begin = 0 ;
rs - > printed = 0 ;
rs - > missed = 0 ;
2008-04-29 11:59:43 +04:00
}
2008-07-25 12:45:58 +04:00
if ( rs - > burst & & rs - > burst > rs - > printed )
goto print ;
rs - > missed + + ;
2008-04-29 11:59:43 +04:00
spin_unlock_irqrestore ( & ratelimit_lock , flags ) ;
return 0 ;
2008-07-25 12:45:58 +04:00
print :
rs - > printed + + ;
spin_unlock_irqrestore ( & ratelimit_lock , flags ) ;
return 1 ;
2008-04-29 11:59:43 +04:00
}
EXPORT_SYMBOL ( __ratelimit ) ;