红联Linux门户
Linux帮助

Linux下Log中的Message supressed解析

发布时间:2006-08-16 08:22:17来源:红联作者:bear10214
在Linux系统某些异常情况下,大家常会在log文件中看到N messages supressed (N为数字)。下面来解析一下产生原因和含义。

假设有如下情况(仅仅是假设):。

某设备收到数据后,需要在内核空分配一缓冲区,如果因为某种原因分配缓冲区失败时,驱动程序用printk打印日志:“Allocte Mem failed".。

象上述异常处理情况看似没什么问题,但是在异常情况下,如果每个数据包分配内存都失败,那会出现用户的console或日志文件中不断出现"Allocate Mem failed".这样会导致“拒绝服务”。。

为此,Linux对日志的输出使用了RateLimit机制。将上述过程改写为:
if (net_ratelimit()){

`printk(KERN_WARNING "Allocate Mem failed.\n");

}


int net_msg_cost = 5*HZ;

int net_msg_burst = 10;


int net_ratelimit(void)

{

return __printk_ratelimit(net_msg_cost, net_msg_burst);

}


int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)

{

static DEFINE_SPINLOCK(ratelimit_lock);

static unsigned long toks = 10 * 5 * HZ;

/*last_msg:是上个message 产生的时间*/

static unsigned long last_msg;

static int missed;

unsigned long flags;

unsigned long now = jiffies;



spin_lock_irqsave(&ratelimit_lock, flags);

/*当toks不超过阈值时,返回0,否则,输出N messages supressed 消息并返回1,注意toks是个静态变量*/

/*toks随时间增加*/

toks += now - last_msg;

/*更新last_msg*/

last_msg = now;

/*toks设置上限*/

if (toks > (ratelimit_burst * ratelimit_jiffies))

toks = ratelimit_burst * ratelimit_jiffies;

/*toks超过阈值,阈值为ratelimit_jiffies*/

if (toks >= ratelimit_jiffies) {



int lost = missed;

/*missed复位*/

missed = 0;

toks -= ratelimit_jiffies;

spin_unlock_irqrestore(&ratelimit_lock, flags);

if (lost)

printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);

return 1;

}

missed++;

spin_unlock_irqrestore(&ratelimit_lock, flags);

return 0;

}

思考:

1.ratelimit_jiffies的含义到底是什么?从表面看,ratelimit_jiffies代表了阈值,仔细分析下来发现,其实它还有个作用就是控制多少时间之内的message不重复显示,而在超过该段时间后,输出 N message suppressed消息,其中N为这段时间内欲输出但被suppressed的数目


2.ratelimit_burst的含义是什么?从表面看ratelimit_burst*ratelimit_jiffies控制了toks的上限.在最开始的阶段,当toks达到最大上限时,此时必定超过阈值,但missed又为0,因此,不会输出message suppressed消息,但由于返回值为1,因此会让相应的模块输出应有的message,因为:

if (net_ratelimit()){

printk(KERN_WARNING "Allocate Mem failed.\n");

}

此后toks递减ratelimit_jiffies,当再次调用__printk_ratelimit后,如果上次递减后的数值+"now - last_msg"还超过阈值则还会再输出相应的消息。

因此ratelimit_burst*ratelimit_jiffies控制了在消息抑制前输出的消息多少。

3.注意:toks、missed是静态局部变量


以上几点为我自己的一些理解,如果有不妥或错误的地方欢迎指正
文章评论

共有 0 条评论