如何延迟 Linux 内核模块临界区
How to Delay in Linux Kernel Module Critical Section
我需要在 USB 内核模块中添加一个短暂的延迟,以避免在小型嵌入式 Linux 设备启动时出现极其罕见的内核恐慌。有问题的代码如下。如果我在代码中加入一些小技巧,设备会在之前失败的地方成功运行一整晚。我想添加一个小延迟,但 usleep_range 和 msleep 导致内核回溯 "Scheduling While Atomic"。如何在不休眠的情况下在这段代码中添加延迟?是 while 循环吗?
usb_hub_for_each_child(udev, chix, childdev) {
printk(KERN_ERR "r8a66597: Start USB Discover\n");
//usleep_range(10000, 11000);
//preempt_disable();
//msleep(1);
collect_usb_address_map(childdev, map);
//usleep_range(10000, 11000);
printk(KERN_ERR "r8a66597: Stop USB Discover\n");
//msleep(1);
//preempt_enable();
}
Header linux/delay.h 提供delay without sleep的功能。这些函数可以在中断(原子)上下文中使用:
- ndelay(ns) - 等待给定的纳秒数,
- udelay(us) - 等待给定的微秒数,
- mdelay(ms) - 等待给定的毫秒数。
我需要在 USB 内核模块中添加一个短暂的延迟,以避免在小型嵌入式 Linux 设备启动时出现极其罕见的内核恐慌。有问题的代码如下。如果我在代码中加入一些小技巧,设备会在之前失败的地方成功运行一整晚。我想添加一个小延迟,但 usleep_range 和 msleep 导致内核回溯 "Scheduling While Atomic"。如何在不休眠的情况下在这段代码中添加延迟?是 while 循环吗?
usb_hub_for_each_child(udev, chix, childdev) {
printk(KERN_ERR "r8a66597: Start USB Discover\n");
//usleep_range(10000, 11000);
//preempt_disable();
//msleep(1);
collect_usb_address_map(childdev, map);
//usleep_range(10000, 11000);
printk(KERN_ERR "r8a66597: Stop USB Discover\n");
//msleep(1);
//preempt_enable();
}
Header linux/delay.h 提供delay without sleep的功能。这些函数可以在中断(原子)上下文中使用:
- ndelay(ns) - 等待给定的纳秒数,
- udelay(us) - 等待给定的微秒数,
- mdelay(ms) - 等待给定的毫秒数。