`
sunzixun
  • 浏览: 75945 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

<Learn From Kernel> printk_ratelimit()

阅读更多


今天在看ldd网卡驱动的时候,发现一个有趣的函数 printk_ratelimit()

 

 他的主要做用和 prco文件系统下的,这两个接口有关系

printk_ratelimit 定义了消息之间允许的最小时间间隔。

printk_ratelimit_burst 定义消息数量

 

 

于是我机器上显示的就是 5s 内最多10条。

 

只是一个非常有意义的函数。 我们知道

ldd3 写道
hundreds or thousands of console messages per second is a good way to bog down
the system entirely and hide the real source of problems

 

以前在做 服务器的时候  ,都是通过一个信号 重定向 a:打屏 b:dev/null c:文件 ,压力测试的时候打屏一直是瓶颈。我们来看看内核怎么处理大量的prink的。

 

#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,
		.begin = // long 				\
	}

 

这里的 interval_init 就是 5 , burst_init 是10

___ratelimit(&printk_ratelimit_state, func);
/*func 就是当前执行的函数 
*printk_ratelimit_state 就是那个初始化过的结构体*/
 

  

 主要代码和分析如下

int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
	unsigned long flags;
	int ret;

	if (!rs->interval)
		return 1;

	/*这里当然要用 非阻塞的自选锁 ,保存并且禁止了本地中断 */
	if (!spin_trylock_irqsave(&rs->lock, flags))
		return 0;
	/*如果之前过了一个 打印时间点 就继续记录当前jiffies*/
	if (!rs->begin)
		rs->begin = jiffies;
	/*这里其实 用了宏 time_after,用来判断当前的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;
	}
	/*没过的话 就继续看rs->printed 剩余的
	*过了的话肯定打印*/
	if (rs->burst && rs->burst > rs->printed) {
		rs->printed++;//打印计数
		ret = 1;
	} else {
		rs->missed++;//忽略掉的
		ret = 0;
	}
	/*恢复 */
	spin_unlock_irqrestore(&rs->lock, flags);

	return ret;
}

 

 从以上的步骤可以看出,我们很容易在应用中,实现类似的功能。

 

 #define DEBUG_ONE(a) { 
if( printk_ratelimit()){\
 printf("*** %s DEBUG[%s:%d]: ", nowtime(time(NULL)), __FILE__, __LINE__); \
  printf a; printf("\n");} \
}

 

 

#define  time_after(now,after)宏

 

也很容易通过

static long  get_time()
{
	struct timeb tm;
	long Req_Begin=0,Req_Begin_ms=0,Res_Begin_Time=0;
	ftime(&tm);
	Req_Begin = tm.time;
	Req_Begin_ms = tm.millitm;
	Res_Begin_Time = ((long)Req_Begin*1000 +(long)Req_Begin_ms);
	return Res_Begin_Time;
}

 

这样的函数实现。

 

  • 大小: 14.7 KB
  • 大小: 14.7 KB
分享到:
评论

相关推荐

    Linux 内核参数详解-KERNEL.docx

    `kernel.printk_ratelimit_burst` 和 `kernel.printk_ratelimit` **参数描述**: - `kernel.printk_ratelimit_burst`:在短时间内允许通过的信息数量。默认值为10。 - `kernel.printk_ratelimit`:指定在限定时间...

    spi_csdn_tinav2.1验证通过_SPI0接口配置流行屏_20171106_1958没有外层目录.7z

    lcd_gpio_0 = port:PH07&lt;1&gt;&lt;0&gt;&lt;default&gt;&lt;0&gt; 2、 W:\liuxing_csdn_tinav2.1\target\allwinner\astar-parrot\configs\sys_config.fex 生成的SPI的设备名: ;----------------------------------------------------...

    printk_linux_

    《深入探索Linux内核中的printk函数》 在开源操作系统Linux的世界里,源代码是学习其内部机制的金钥匙。"linux-1.0.tar.gz"这个早期版本的Linux源码,为开发者和爱好者提供了宝贵的参考资料,特别是对于那些希望...

    thl_r16_tinav2.0_hm1375验证通过_增加打印设备ID_20170824_1447.7z

    if((dev-&gt;dev_qty &gt; 1) && (input_num+1&lt;dev-&gt;dev_qty)) { if((!strcmp(dev-&gt;ccm_cfg[input_num]-&gt;ccm,dev-&gt;ccm_cfg[input_num+1]-&gt;ccm))) dev-&gt;is_same_module = 1; } if(dev-&gt;vip_define_sensor_...

    hm1375_tinav2.1验证通过_增加设备ID的读取显示_20170825_1333没有外层目录.7z

    if((dev-&gt;dev_qty &gt; 1) && (input_num+1&lt;dev-&gt;dev_qty)) { if((!strcmp(dev-&gt;ccm_cfg[input_num]-&gt;ccm,dev-&gt;ccm_cfg[input_num+1]-&gt;ccm))) dev-&gt;is_same_module = 1; } if(dev-&gt;vip_define_sensor_...

    ( ap6181_sina33m_sc3817r验证通过_20170710_1608没有外层目录.7z

    &lt;integer name="def_screen_off_timeout"&gt;1800000&lt;/integer&gt; &lt;bool name="def_lockscreen_disabled"&gt;true&lt;/bool&gt; 7、请严重注意,全志在这里埋坑了!(坑爹无敌!) Android里面调入配置文件:nvram.txt,里面...

    虚拟网卡驱动源代码(原版)

    #include &lt;linux/kernel.h&gt; /* printk() */ #include &lt;linux/slab.h&gt; /* kmalloc() */ #include &lt;linux/errno.h&gt; /* error codes */ #include &lt;linux/types.h&gt; /* size_t */ #include &lt;linux/interrupt.h&gt; /* mark_...

    embedded_linux_kernel_and_drivers

    #include&lt;linux/kernel.h&gt; static int __init hello_init(void) { printk(KERN_ALERT "Good morrow to this fair assembly.\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_ALERT "Alas,...

    usb-serial

    usb_serial_driver.id_table[0].driver_info=(kernel_ulong_t)&usb_serial_driver; //注册设备ID表 if(device_register(&usb_serial_driver)){ printk(KERN_ERR"usb-serial:%s-failedtoregisterDeviceIDTable\n",__...

    pt7c4307 驱动

    if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; set_time(&tm); } return 0; case RTC_IRQP_READ: return put_user(rtc_freq, (unsigned long *)arg); ...

    利用kernel提供的接口打印进程号(pid)

    代码如下:#include &lt;linux&gt;#include &lt;linux&gt;#include &lt;linux&gt;#include &lt;linux&gt;#include &lt;linux&gt; static __init int printPid(void) //安装模块函数{ struct task_struct *task,*p; struct list_head *ps; int ...

    编写linux驱动时的头文件

    `&lt;asm/uaccess.h&gt;`定义了用于用户空间和内核空间之间数据交换的函数,如`copy_to_user`、`copy_from_user`等。这些函数确保了数据的正确传输并防止了安全问题。 `&lt;mach/regs-gpio.h&gt;`则包含了特定于机器的GPIO...

    linux内核 0.11版本源码 带中文注释

    #include &lt;unistd.h&gt; // *.h 头文件所在的默认目录是include/,则在代码中就不用明确指明位置。 // 如果不是UNIX 的标准头文件,则需要指明所在的目录,并用双引号括住。 // 标准符号常数与类型文件。定义了各种...

    linux下的i2c驱动以及与时钟芯片pcf8563通信(二)

    (tm-&gt;tm_year &gt;= 100) : (tm-&gt;tm_year &lt; 100)) { buf[PCF8563_REG_MO] |= PCF8563_MO_C; } buf[PCF8563_REG_DW] = tm-&gt;tm_wday & 0x07; /* 写入寄存器数据 */ for (i = 0; i &lt; 7; i++) { unsigned char ...

    The_Linux_Kernel_Module_Programming_Guide_2.6中文版

    通过这个简单的例子,读者可以学习到如何创建一个基本的模块,如何处理模块初始化和清理过程,以及如何使用`printk`函数向系统日志输出信息。 本书后续章节会深入探讨更复杂的主题,如设备驱动程序、中断处理、内存...

    The_Linux_Kernel_Module_Programming_Guide.rar_it

    通过学习`printk`、`dmesg`以及使用`SystemTap`和`Kernel DebugKit`等工具,开发者可以更有效地追踪和修复问题。 除了上述内容,书中还可能涵盖一些高级主题,比如内存管理(包括物理和虚拟内存)、网络协议栈的...

    r40_tinav2.1_最终验证通过_使用CB-S来验证OV5640有横条纹fpscamera+SPI2.0成功_20171114_1443没有外层目录.7z

    if(cap-&gt;status == OFF && cap-&gt;cmd == START_STREAMMING){ hv_dbg("capture start streaming\n"); type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(videofh, VIDIOC_STREAMON, &type;) == -1) { hv_err(...

    高通平台printk输出log到串口

    1、查看当前打印级别 ... # echo 8 &gt; /proc/sys/kernel/printk //这样串口才能打印数据 3、内核函数printk的打印级别宏定义:Include/linux/kernel.h #define KERN_EMERG /* system is unusable */ #define KERN_ALERT

    Linux驱动_mmap1

    #include &lt;linux/kernel.h&gt; #include &lt;linux/fs.h&gt; #include &lt;linux/device.h&gt; #include &lt;linux/io.h&gt; #include &lt;linux/cdev.h&gt; #include &lt;asm/uaccess.h&gt; #define USE_KMALLOC 0 #define MEMC_SIZE 4096 #define ...

Global site tag (gtag.js) - Google Analytics