linux-kernel - Linux 内核模块在卸载期间挂起

我正在尝试根据“操作系统概念”一书的第一章制作编程项目。任务是编写 Linux 内核模块,它使用内核列表数据结构迭代结构。我写了以下代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>

struct birthday {
    int day;
    int month;
    int year;
    struct list_head list;  
};

struct list_head birthday_list;

struct birthday *createBirthday(int day, int month, int year)
{
    struct birthday *person = kmalloc(sizeof(struct birthday), GFP_KERNEL);

    person->day = day;
    person->month = month;
    person->year = year;

    return person;
}

void printInfo(char *str)
{
    printk(KERN_INFO "OS Module: %s", str);
}

int simple_init(void)
{
    struct birthday *person = createBirthday(13, 4, 1987);
    struct birthday *ptr;

    printInfo("Loading Module\n");

    LIST_HEAD(birthday_list);

    list_add_tail(&person->list, &birthday_list);
    person = createBirthday(14, 4, 1987);
    list_add_tail(&person->list, &birthday_list);
    person = createBirthday(15, 4, 1987);
    list_add_tail(&person->list, &birthday_list);
    person = createBirthday(16, 4, 1987);
    list_add_tail(&person->list, &birthday_list);
    person = createBirthday(17, 4, 1987);
    list_add_tail(&person->list, &birthday_list);

    list_for_each_entry(ptr, &birthday_list, list) {
        printk(KERN_INFO "OS Module: Day %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
    }

       return 0;
}

void simple_exit(void)
{
    struct birthday *tmp;
    struct list_head *ptr, *next;

    printInfo("Removing Module\n");

    if (list_empty(&birthday_list)) {
        printInfo("List is empty");
        return;
    }

    list_for_each_safe(ptr, next, &birthday_list){
        tmp = list_entry(ptr, struct birthday, list);
        printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", tmp->day, tmp->month, tmp->year);
        list_del(ptr);
        kfree(tmp);
    }

    //list_for_each_entry_safe(ptr, next, &birthday_list, list) {
    //  printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
    //  list_del(&ptr->list);
    //  kfree(ptr);
    //}

    printInfo("Module removed\n");
}

module_init( simple_init );
module_exit( simple_exit );

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("MP");

安装和删除模块后,我没有看到有关删除模块的消息。

~/kernelModule $ sudo insmod simple.ko
~/kernelModule $ sudo rmmod -f simple
~/kernelModule $ dmesg | grep 'OS Module'
[  386.590198] OS Module: Loading Module
[  386.590201] OS Module: Day 13.4.1987
[  386.590202] OS Module: Day 14.1.1964
[  386.590203] OS Module: Day 2.6.1964
[  386.590204] OS Module: Day 13.8.1986
[  386.590204] OS Module: Day 10.6.1990
[  396.647828] OS Module: Removing Module
~/kernelModule $ sudo rmmod -f simple
rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'simple': Device or resource busy
rmmod: ERROR: could not remove module simple: Device or resource busy

据我了解,我的模块在删除过程中挂起。我不明白为什么。两个发布代码(也有注释)都会使模块挂起。

最佳答案

使用 INIT_LIST_HEAD(&birthday_list) 而不是 LIST_HEAD(birthday_list) 有助于解决问题。

https://stackoverflow.com/questions/33334393/

相关文章:

javascript - three.js 边缘和文本在旋转时呈锯齿状/模糊

java - Android,如何在运行时设置导航 View 组可见性?

r - Shiny 应用程序的初始加载没有更新

python - AssertListEqual 不改变类 __eq__ 方法

java - Kafka集群zookeeper故障处理

python - 使用 pyresample 绘制卫星 strip 数据

git - 我们可以将 git-annex 添加到 GitLab CE 吗?

Java - 系统进程监听器

google-chrome - 如何禁用谷歌浏览器 url 转义?

javascript - 当鼠标进入非事件浏览器窗口时触发一次 mousemove (Chrome)