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:0.149 / U:1.496 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site