当前位置: 首页 > 工具软件 > syj-ratelimit > 使用案例 >

JJJ:printk_ratelimit() 函数

樊浩初
2023-12-01

内核版本:2.6.38

此函数的功能是:限制在一定时间间隔内的打印次数。

printk_ratelimit()

include/linux/printk.h

#define printk_ratelimit() __printk_ratelimit(__func__)

__printk_ratelimit(__func__)

kernel/printk.c

/*
 * printk rate limiting, lifted from the networking subsystem.
 *
 * This enforces a rate limit: not more than 10 kernel messages
 * every 5s to make a denial-of-service attack impossible.
 */
 // 就是5秒内最多打印10次
DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); 

int __printk_ratelimit(const char *func)
{
    return ___ratelimit(&printk_ratelimit_state, func);
}
EXPORT_SYMBOL(__printk_ratelimit);

关于 DEFINE_RATELIMIT_STATE,定义在:./include/linux/ratelimit.h

#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init)     \
                                    \
    struct ratelimit_state name = {                 \
        .lock       = __SPIN_LOCK_UNLOCKED(name.lock),  \
        .interval   = interval_init,            \
        .burst      = burst_init,               \
    }

struct ratelimit_state 数据类型

struct ratelimit_state {
    raw_spinlock_t  lock;       /* protect the state */

    int     interval;
    int     burst;
    int     printed;
    int     missed;
    unsigned long   begin;
    unsigned long 	flags;
};

___ratelimit

lib/ratelimit.c

/*
 * __ratelimit - rate limiting
 * @rs: ratelimit_state data
 * @func: name of calling function
 *
 * This enforces a rate limit: not more than @rs->burst callbacks
 * in every @rs->interval
 *
 * RETURNS:
 * 0 means callbacks will be suppressed.
 * 1 means go ahead and do it.
 */
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
    unsigned long flags;
    int ret;

    if (!rs->interval)
        return 1;

    /*  
     * 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 0;

    if (!rs->begin)
        rs->begin = jiffies;

    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;
    }
    if (rs->burst && rs->burst > rs->printed) {
        rs->printed++;
        ret = 1;
    } else {
        rs->missed++;
        ret = 0;
    }
    spin_unlock_irqrestore(&rs->lock, flags);

    return ret;
}
EXPORT_SYMBOL(___ratelimit);
 类似资料: