Rate Limiting
If you are not careful, you can find yourself generating thousands of messages with printk, overwhelming the console and, possibly, overflowing the system log file. When using a slow console device (e.g., a serial port), an excessive message rate can also slow down the system or just make it unresponsive. It can be very hard to get a handle on what is wrong with a system when the console is spewing out data nonstop. Therefore, you should be very careful about what you print, especially in production versions of drivers and especially once initialization is complete. In general, production code should never print anything during normal operation; printed output should be an indication of an exceptional situation requiring attention. 如果您不小心,您会发现自己使用 printk 生成了数千条消息,使控制台不堪重负,并且可能会溢出系统日志文件。 当使用慢速控制台设备(例如,串行端口)时,过高的消息速率也会减慢系统速度或使其无响应。 当控制台不停地喷出数据时,很难处理系统出了什么问题。 因此,您应该非常小心打印的内容,尤其是在驱动程序的生产版本中,尤其是在初始化完成后。 一般来说,生产代码在正常运行期间不应该打印任何东西; 打印输出应表明需要注意的特殊情况。
On the other hand, you may want to emit a log message if a device you are driving stops working. But you should be careful not to overdo things. An unintelligent process that continues forever in the face of failures can generate thousands of retries per second; if your driver prints a "my device is broken" message every time, it could create vast amounts of output and possibly hog the CPU if the console device is slow—no interrupts can be used to driver the console, even if it is a serial port or a line printer. 另一方面,如果您驾驶的设备停止工作,您可能希望发出日志消息。 但是你应该注意不要做太多事情。 一个在失败面前永远持续下去的非智能过程每秒会产生数千次重试; 如果您的驱动程序每次都打印“我的设备已损坏”消息,则它可能会产生大量输出,并且如果控制台设备很慢,则可能会占用 CPU——即使它是串行的,也不能使用中断来驱动控制台 端口或行式打印机。
In many cases, the best behavior is to set a flag saying, "I have already complained about this," and not print any further messages once the flag gets set. In others, though, there are reasons to emit an occasional "the device is still broken" notice. The kernel has provided a function that can be helpful in such cases: 在许多情况下,最好的行为是设置一个标志,说“我已经抱怨过这个”,并且在设置标志后不再打印任何进一步的消息。 但是,在其他情况下,有理由偶尔发出“设备仍然损坏”的通知。 内核提供了一个在这种情况下很有帮助的函数:
int printk_ratelimit(void);
This function should be called before you consider printing a message that could be repeated often. If the function returns a nonzero value, go ahead and print your message, otherwise skip it. Thus, typical calls look like this: 在考虑打印可能经常重复的消息之前,应调用此函数。 如果函数返回非零值,请继续打印您的消息,否则跳过它。 因此,典型的调用如下所示:
if (printk_ratelimit( ))
printk(KERN_NOTICE "The printer is still on fire\n");
printk_ratelimit works by tracking how many messages are sent to the console. When the level of output exceeds a threshold, printk_ratelimit starts returning 0 and causing messages to be dropped. printk_ratelimit 通过跟踪发送到控制台的消息数量来工作。 当输出级别超过阈值时, printk_ratelimit 开始返回 0 并导致消息被丢弃。
The behavior of printk_ratelimit can be customized by modifying /proc/sys/kernel/printk_ratelimit (the number of seconds to wait before re-enabling messages) and are /proc/sys/kernel/printk_ratelimit_burst (the number of messages accepted before rate-limiting). printk_ratelimit 的行为可以通过修改 /proc/sys/kernel/printk_ratelimit(重新启用消息之前等待的秒数)和 /proc/sys/kernel/printk_ratelimit_burst(限速之前接受的消息数)来定制 )。
Printing Device Numbers
Occasionally, when printing a message from a driver, you will want to print the device number associated with the hardware of interest. It is not particularly hard to print the major and minor numbers, but, in the interest of consistency, the kernel provides a couple of utility macros (defined in <linux/kdev_t.h>) for this purpose: 有时,在打印来自驱动程序的消息时,您会想要打印与感兴趣的硬件相关联的设备号。 打印主要和次要数字并不是特别难,但是为了保持一致性,内核为此提供了几个实用宏(在 <linux/kdev_t.h> 中定义):
int print_dev_t(char *buffer, dev_t dev);
char *format_dev_t(char *buffer, dev_t dev);
Both macros encode the device number into the given buffer; the only difference is that print_dev_t returns the number of characters printed, while format_dev_t returns buffer; therefore, it can be used as a parameter to a printk call directly, although one must remember that printk doesn't flush until a trailing newline is provided. The buffer should be large enough to hold a device number; given that 64-bit device numbers are a distinct possibility in future kernel releases, the buffer should probably be at least 20 bytes long. 两个宏都将设备号编码到给定的缓冲区中; 唯一的区别是 print_dev_t 返回打印的字符数,而 format_dev_t 返回缓冲区; 因此,它可以直接用作 printk 调用的参数,但必须记住 printk 在提供尾随换行符之前不会刷新。 缓冲区应该足够大以容纳设备号; 考虑到 64 位设备号在未来的内核版本中很可能出现,缓冲区应该至少有 20 字节长。
Debugging by Querying
The previous section described how printk works and how it can be used. What it didn't talk about are its disadvantages. 上一节描述了 printk 的工作原理以及如何使用它。 它没有谈论的是它的缺点。
A massive use of printk can slow down the system noticeably, even if you lower console_loglevel to avoid loading the console device, because syslogd keeps syncing its output files; thus, every line that is printed causes a disk operation. This is the right implementation from syslogd 's perspective. It tries to write everything to disk in case the system crashes right after printing the message; however, you don't want to slow down your system just for the sake of debugging messages. This problem can be solved by prefixing the name of your log file as it appears in /etc/syslogd.conf with a hyphen.[2] The problem with changing the configuration file is that the modification will likely remain there after you are done debugging, even though during normal system operation you do want messages to be flushed to disk as soon as possible. An alternative to such a permanent change is running a program other than klogd (such as cat /proc/kmsg, as suggested earlier), but this may not provide a suitable environment for normal system operation. 大量使用 printk 会显着降低系统速度,即使您降低 console_loglevel 以避免加载控制台设备,因为 syslogd 会不断同步其输出文件;因此,打印的每一行都会导致磁盘操作。从 syslogd 的角度来看,这是正确的实现。它会尝试将所有内容写入磁盘,以防系统在打印消息后立即崩溃;但是,您不想仅仅为了调试消息而减慢系统速度。这个问题可以通过在 /etc/syslogd.conf 中出现的日志文件名称前加上连字符来解决。[2]更改配置文件的问题是在您完成调试后修改可能会保留在那里,即使在正常系统操作期间您确实希望消息尽快刷新到磁盘。这种永久性更改的替代方法是运行 klogd 以外的程序(如 cat /proc/kmsg,如前所述),但这可能无法为正常系统操作提供合适的环境。
More often than not, the best way to get relevant information is to query the system when you need the information, instead of continually producing data. In fact, every Unix system provides many tools for obtaining system information: ps, netstat, vmstat, and so on. 通常,获取相关信息的最佳方式是在需要信息时查询系统,而不是不断产生数据。 事实上,每个Unix系统都提供了很多获取系统信息的工具:ps、netstat、vmstat等。文章来源:https://www.toymoban.com/news/detail-470792.html
A few techniques are available to driver developers for querying the system: creating a file in the /proc filesystem, using the ioctl driver method, and exporting attributes via sysfs. The use of sysfs requires quite some background on the driver model. It is discussed in Chapter 14. 驱动程序开发人员可以使用一些技术来查询系统:在 /proc 文件系统中创建文件,使用 ioctl 驱动程序方法,以及通过 sysfs 导出属性。 使用 sysfs 需要相当多的驱动模型背景知识。 第 14 章对此进行了讨论。文章来源地址https://www.toymoban.com/news/detail-470792.html
到了这里,关于Rate Limiting的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!