简体   繁体   中英

Wake up a Kthread which is sleeping

static struct task_struct *control = NULL;
static long call_ioctl(struct file *filp, unsigned int iocmd, unsigned long arg) 
{
    switch (iocmd)
    {
        case SETMODE:
            /* get buffer data from userspace which is either 0 or 1 */
            /* 0: Manual 1: Automatic*/
            switch (buffer)
            {
            case MANUAL:
                if (control)
                {
                    kthread_stop(control);
                    control = NULL;
                    printk(KERN_ALERT "Switching to MANUAL disabling kernel thread for Automatic\n");
                }
                mode = MANUAL_MODE;
                printk(KERN_ALERT "IN MANUAL \n");
                break;

            case AUTOMATIC:
            if (automatic_fan_control() != 0)
            {
                printk(KERN_ALERT "Failed to set fan to  AUTOMATIC!!! \n");
                return -1;
            }
            break;

            default:
                printk(KERN_ALERT "Entered value is incorrect\n");
                return -EINVAL;
            }
        break;
    }
       
}

static inline int automatic_fan_control(void)
{
    control = kthread_run(sense_cpu_temperature, NULL, "Temperature Thread");
    if (control)
    {
        printk(KERN_ALERT "Kthread Created Successfully\n");
    }
    else
    {
        printk(KERN_ALERT "Failed to create kthread. \n");
        control = NULL;
        return -1;
    }
    return 0;
}

int temperature(void *arg)
{

    while (!kthread_should_stop())
    {
        mutex_lock(&mutex);
        get_temperature();
        mutex_unlock(&mutex);
        /* Process the temperature value */
        msleep_interruptible(polling_interval);
    }
    return 0;
}

This the above code that i have written for a driver:

  • When I switch to automatic mode the thread is created which fetches temperature and process it, once it does that it will sleep for polling_interval time, then process again once time is elapsed.
  • When I switch to manual mode, have to stop the kthread and go to manual mode which is not a thread.
  • Issue I am facing here is when switch happens to manual, it will respond after the sleep time of kthread has been completed, if the sleep time interval provided is very big it takes a lot of time to switch to manual mode.
  • Is there any way to come out of sleep in kthread the when it switches to manual mode. Sort of stuck in this am newbie to driver any help would be great

Let's look at the source of msleep_interruptible :

unsigned long msleep_interruptible(unsigned int msecs)
{
        unsigned long timeout = msecs_to_jiffies(msecs) + 1;

        while (timeout && !signal_pending(current))
                timeout = schedule_timeout_interruptible(timeout);
        return jiffies_to_msecs(timeout);
}

schedule_timeout_interruptible puts the asleep until the timeout expires, or a signal is delivered, or it is explicitly woken up. It returns the remaining time in jiffies. As can be seen above, msleep_interruptible will go back to sleep if woken early and no signal is pending.

kthread_stop wakes up the thread task explicitly, but does not send a signal, so msleep_interruptible will run to completion, putting the thread task back to sleep if woken early.

In this case, a simple fix would be to replace this call in temperature :

        msleep_interruptible(polling_interval);

with the following call:

        schedule_timeout_uninterruptible(msecs_to_jiffies(polling_interval) + 1);

Then, if woken up early, it won't go back to sleep.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM