15f97a5a8SDave Young /* 25f97a5a8SDave Young * ratelimit.c - Do something with rate limit. 35f97a5a8SDave Young * 45f97a5a8SDave Young * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com> 55f97a5a8SDave Young * 6717115e1SDave Young * 2008-05-01 rewrite the function and use a ratelimit_state data struct as 7717115e1SDave Young * parameter. Now every user can use their own standalone ratelimit_state. 8717115e1SDave Young * 95f97a5a8SDave Young * This file is released under the GPLv2. 105f97a5a8SDave Young * 115f97a5a8SDave Young */ 125f97a5a8SDave Young 135f97a5a8SDave Young #include <linux/kernel.h> 145f97a5a8SDave Young #include <linux/jiffies.h> 155f97a5a8SDave Young #include <linux/module.h> 165f97a5a8SDave Young 17717115e1SDave Young static DEFINE_SPINLOCK(ratelimit_lock); 18717115e1SDave Young 195f97a5a8SDave Young /* 205f97a5a8SDave Young * __ratelimit - rate limiting 21717115e1SDave Young * @rs: ratelimit_state data 225f97a5a8SDave Young * 23717115e1SDave Young * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks 24717115e1SDave Young * in every @rs->ratelimit_jiffies 255f97a5a8SDave Young */ 26717115e1SDave Young int __ratelimit(struct ratelimit_state *rs) 275f97a5a8SDave Young { 28*4d9c377cSAlexey Dobriyan unsigned long flags; 29*4d9c377cSAlexey Dobriyan 30717115e1SDave Young if (!rs->interval) 31717115e1SDave Young return 1; 325f97a5a8SDave Young 335f97a5a8SDave Young spin_lock_irqsave(&ratelimit_lock, flags); 34717115e1SDave Young if (!rs->begin) 35717115e1SDave Young rs->begin = jiffies; 365f97a5a8SDave Young 37717115e1SDave Young if (time_is_before_jiffies(rs->begin + rs->interval)) { 38717115e1SDave Young if (rs->missed) 39717115e1SDave Young printk(KERN_WARNING "%s: %d callbacks suppressed\n", 40717115e1SDave Young __func__, rs->missed); 41717115e1SDave Young rs->begin = 0; 42717115e1SDave Young rs->printed = 0; 43717115e1SDave Young rs->missed = 0; 445f97a5a8SDave Young } 45717115e1SDave Young if (rs->burst && rs->burst > rs->printed) 46717115e1SDave Young goto print; 47717115e1SDave Young 48717115e1SDave Young rs->missed++; 495f97a5a8SDave Young spin_unlock_irqrestore(&ratelimit_lock, flags); 505f97a5a8SDave Young return 0; 51717115e1SDave Young 52717115e1SDave Young print: 53717115e1SDave Young rs->printed++; 54717115e1SDave Young spin_unlock_irqrestore(&ratelimit_lock, flags); 55717115e1SDave Young return 1; 565f97a5a8SDave Young } 575f97a5a8SDave Young EXPORT_SYMBOL(__ratelimit); 58