lkml.org 
[lkml]   [2013]   [Aug]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH 00/14] Fix bug about invalid wake up problem
    On 2013/8/29 21:57, Libin wrote:
    ....
    > 2)Test:
    > I have written a test module to trigger the problem by adding some
    > synchronization condition. I will post it in the form of an attachment soon.
    >
    > Test result as follows:
    > [103135.332683] wakeup_test: create two kernel threads - producer & consumer
    > [103135.332686] wakeup_test: module loaded successfully
    > [103135.332692] wakeup_test: kthread producer try to wake up the kthread consumer
    > [103165.299865] wakeup_test: kthread consumer have waited for 30s, indicating
    > trigger an invalid wakeup problem!
    >
    ....






    /*
    * wakeup_test.c -- Linux kernel invalid wake up problem simulation test module
    *
    * Written By: Libin <huawei.libin@huawei.com>
    *
    * History
    * -------
    */
    #include <linux/init.h>
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/kthread.h>
    #include <linux/sched.h>
    #include <linux/list.h>
    #include <linux/slab.h>
    #include <linux/completion.h>
    #include <linux/timer.h>

    #define NAME "wakeup_test"
    #define WAIT_TIMEOUT HZ*30
    static LIST_HEAD(product_list);
    struct product_struct{
    int data;
    struct list_head list;
    };
    static struct task_struct *producer, *consumer;
    static struct completion done;

    static int producer_thread(void *unused)
    {
    struct product_struct *product;
    product = (struct product_struct *)kmalloc(sizeof (struct product_struct), GFP_KERNEL);
    product->data = 1;

    list_add_tail(&product->list, &product_list);

    wake_up_process(consumer);
    printk(KERN_INFO "%s: kthread producer try to wake up the kthread consumer\n", NAME);
    complete(&done); /* NOTE: added for problem trigger simulation */

    while (!kthread_should_stop()){
    set_current_state(TASK_INTERRUPTIBLE);
    schedule_timeout(HZ);
    }

    printk(KERN_INFO "%s: kthread producer exit\n", NAME);
    return 0;
    }
    static void simulate_preempted(void)
    {
    schedule();
    }

    static void wakeup_wait_timeout(unsigned long unused)
    {
    printk(KERN_ERR "%s: kthread consumer have waited for %ds, "
    "indicating trigger an invalid wakeup problem!\n", NAME, WAIT_TIMEOUT/HZ);
    }
    static int consumer_thread(void *unused)
    {
    struct timer_list wakeup_wait_timer;
    setup_timer(&wakeup_wait_timer, wakeup_wait_timeout, (unsigned long)NULL);
    wait_for_completion(&done); /* NOTE: added for problem trigger simulation */

    mod_timer(&wakeup_wait_timer, jiffies + WAIT_TIMEOUT);
    set_current_state(TASK_INTERRUPTIBLE);

    simulate_preempted(); /* NOTE: added for problem trigger simulation */
    while (list_empty(&product_list)){
    schedule();
    set_current_state(TASK_INTERRUPTIBLE);
    }
    __set_current_state(TASK_RUNNING);

    del_timer_sync(&wakeup_wait_timer);
    if (kthread_should_stop()){
    goto out;
    }

    if (!list_empty(&product_list)){
    printk(KERN_INFO "%s: kthread consumer be woken up successfully, all right!\n", NAME);
    }

    while (!kthread_should_stop()){
    set_current_state(TASK_INTERRUPTIBLE);
    schedule_timeout(HZ);
    }

    out:
    printk(KERN_INFO "%s: kthread consumer exit\n", NAME);
    return 0;
    }

    static int __init wakeup_test_init(void)
    {
    producer = kthread_create(producer_thread, NULL, "producer");
    consumer = kthread_create(consumer_thread, NULL, "consumer");
    init_completion(&done);

    wake_up_process(producer);
    wake_up_process(consumer);
    printk(KERN_INFO "%s: create two kernel threads - producer & consumer\n", NAME);
    printk(KERN_INFO "%s: module loaded successfully\n", NAME);
    return 0;
    }
    static void __exit wakeup_test_exit(void)
    {
    kthread_stop(producer);
    kthread_stop(consumer);
    printk(KERN_INFO "%s: module unloaded successfully\n", NAME);
    }
    module_init(wakeup_test_init);
    module_exit(wakeup_test_exit);
    MODULE_LICENSE("GPL");

    \
     
     \ /
      Last update: 2013-08-30 09:21    [W:3.719 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site