after using rmmod program freezes

徘徊边缘 提交于 2020-05-17 07:44:05

问题


I have some problem with my code. In my code i solve the reader writers problem using RCU, when i load the module (insmod) everything works ok, and it works as i expected, but when i unload module (rmmod) my program freezes and I have to restart Ubuntu. In this program i have to use call_rcu() to delete previous version of the shared resource and i think that problem is here, because if i have not if I do not use this function and simply delete via kmalloc () then the program works as it should

#include<linux/module.h>
#include<linux/kthread.h>
#include<linux/wait.h>
#include<linux/slab.h>
#include<linux/rcupdate.h>

enum thread_index {WAKING_THREAD, WRITER_THREAD, FIRST_READER_THREAD, SECOND_READER_THREAD};

static struct thread_structure
{
    struct task_struct *thread[4];
} threads;

struct st
{
    int number;
    struct rcu_head rcu;
};

static wait_queue_head_t wait_queue;
static bool condition;
static struct st *number_pointer = NULL; 
static const int first_reader_number = 1, second_thread_number = 2;

static int reader_thread(void *data)
{
    struct st *local_number_pointer = NULL;
    for(;;) {
        rcu_read_lock();
        local_number_pointer = rcu_dereference(number_pointer);
        if(local_number_pointer)
            pr_info("[reader_number: %d] Value of \"number\" variable: %d\n",
        *(int *)data,local_number_pointer->number);
        rcu_read_unlock();
        if(kthread_should_stop())
            return 0;
        set_current_state(TASK_INTERRUPTIBLE);
        if(schedule_timeout(HZ>>2))
            pr_info("Signal received!\n");
    }
}

static void remove(struct rcu_head *x)
{
    struct st *pntr = container_of(x, struct st, rcu);
    kfree(pntr);
}

static int writer_thread(void *data)
{
    struct st *local_number_pointer = NULL;
    int number = 0;
    DEFINE_WAIT(wait);
    for(;;) {
        struct st  *old_pointer = NULL;
        local_number_pointer = kmalloc(sizeof(*local_number_pointer),GFP_KERNEL);
        if(IS_ERR(local_number_pointer)) {
            pr_alert("Error allocating memory: %ld\n",PTR_ERR(local_number_pointer));
            return 0;
        }
        local_number_pointer->number = number++;
        old_pointer = number_pointer;
        rcu_assign_pointer(number_pointer,local_number_pointer);
        synchronize_rcu();
        if(old_pointer)
            call_rcu(&old_pointer->rcu, remove);
        add_wait_queue(&wait_queue,&wait);
        while(!condition) {
            prepare_to_wait(&wait_queue,&wait,TASK_INTERRUPTIBLE);
            if(kthread_should_stop())
                return 0;
            pr_info("[writer_thread]: awake\n");
            schedule();
        }
        condition=false;
        finish_wait(&wait_queue,&wait);
    }
}

static int waking_thread(void *data)
{
    for(;;) {
        if(kthread_should_stop())
            return 0;
        set_current_state(TASK_INTERRUPTIBLE);
        if(schedule_timeout(HZ))
            pr_info("Signal received!\n");
        condition=true;
        wake_up(&wait_queue);
    }

}

static int __init threads_init(void)
{
    init_waitqueue_head(&wait_queue);
    threads.thread[WRITER_THREAD] = kthread_run(writer_thread,NULL,"writer_thread");
    threads.thread[WAKING_THREAD] = kthread_run(waking_thread,NULL,"waking_thread");
    threads.thread[FIRST_READER_THREAD] =
    kthread_run(reader_thread,(void *)&first_reader_number,"first_reader_thread");
    threads.thread[SECOND_READER_THREAD] =
    kthread_run(reader_thread,(void *)&second_thread_number,"second_reader_thread");
    return 0;
}

static void __exit threads_exit(void)
{
    kthread_stop(threads.thread[WAKING_THREAD]);
    kthread_stop(threads.thread[WRITER_THREAD]);
    kthread_stop(threads.thread[FIRST_READER_THREAD]);
    kthread_stop(threads.thread[SECOND_READER_THREAD]);
}

module_init(threads_init);
module_exit(threads_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("An example of using the kernel linux threads and an RCU mechanism.");
MODULE_AUTHOR("Arkadiusz Chrobot <a.chrobot@tu.kielce.pl>");

来源:https://stackoverflow.com/questions/61367001/after-using-rmmod-program-freezes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!