PhilBot
PhilBot

Reputation: 60

How to Delay in Linux Kernel Module Critical Section

I need to add a short delay in a USB kernel module to avoid extremely rare kernel panics on bootup for a small embedded Linux device. The problematic code is below. If I put a prink in the code, the device runs all night successfully where it used to fail before. I want to add a small delay but usleep_range and msleep cause a Kernel traceback "Scheduling While Atomic". How can I add a delay in this section of code without sleeping? Is a while loop the way to do it?

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();
}

Upvotes: 2

Views: 9104

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66288

Header linux/delay.h provides functions for delay without sleep. These functions can be used in interrupt (atomic) context:

  • ndelay(ns) - wait for given number of nanoseconds,
  • udelay(us) - wait for given number of microseconds,
  • mdelay(ms) - wait for given number of milliseconds.

Upvotes: 6

Related Questions