Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * ratelimit.c - Do something with rate limit. 4 : : * 5 : : * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com> 6 : : * 7 : : * 2008-05-01 rewrite the function and use a ratelimit_state data struct as 8 : : * parameter. Now every user can use their own standalone ratelimit_state. 9 : : */ 10 : : 11 : : #include <linux/ratelimit.h> 12 : : #include <linux/jiffies.h> 13 : : #include <linux/export.h> 14 : : 15 : : /* 16 : : * __ratelimit - rate limiting 17 : : * @rs: ratelimit_state data 18 : : * @func: name of calling function 19 : : * 20 : : * This enforces a rate limit: not more than @rs->burst callbacks 21 : : * in every @rs->interval 22 : : * 23 : : * RETURNS: 24 : : * 0 means callbacks will be suppressed. 25 : : * 1 means go ahead and do it. 26 : : */ 27 : 2257 : int ___ratelimit(struct ratelimit_state *rs, const char *func) 28 : : { 29 : 2257 : unsigned long flags; 30 : 2257 : int ret; 31 : : 32 [ + + ]: 2257 : if (!rs->interval) 33 : : return 1; 34 : : 35 : : /* 36 : : * If we contend on this state's lock then almost 37 : : * by definition we are too busy to print a message, 38 : : * in addition to the one that will be printed by 39 : : * the entity that is holding the lock already: 40 : : */ 41 [ - + ]: 4394 : if (!raw_spin_trylock_irqsave(&rs->lock, flags)) 42 : 0 : return 0; 43 : : 44 [ + + ]: 2197 : if (!rs->begin) 45 : 210 : rs->begin = jiffies; 46 : : 47 [ - + ]: 2197 : if (time_is_before_jiffies(rs->begin + rs->interval)) { 48 [ # # ]: 0 : if (rs->missed) { 49 [ # # ]: 0 : if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { 50 : 0 : printk_deferred(KERN_WARNING 51 : : "%s: %d callbacks suppressed\n", 52 : : func, rs->missed); 53 : 0 : rs->missed = 0; 54 : : } 55 : : } 56 : 0 : rs->begin = jiffies; 57 : 0 : rs->printed = 0; 58 : : } 59 [ + - + + ]: 2197 : if (rs->burst && rs->burst > rs->printed) { 60 : 573 : rs->printed++; 61 : 573 : ret = 1; 62 : : } else { 63 : 1624 : rs->missed++; 64 : 1624 : ret = 0; 65 : : } 66 : 2197 : raw_spin_unlock_irqrestore(&rs->lock, flags); 67 : : 68 : 2197 : return ret; 69 : : } 70 : : EXPORT_SYMBOL(___ratelimit);