Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C linux内核中自旋锁并发的内核崩溃_C_Linux_Concurrency_Linux Kernel_Locking - Fatal编程技术网

C linux内核中自旋锁并发的内核崩溃

C linux内核中自旋锁并发的内核崩溃,c,linux,concurrency,linux-kernel,locking,C,Linux,Concurrency,Linux Kernel,Locking,我想清除一个由内核定义的类型列表。我有两个主要结构,num_wrapper和num.num_wapper有一个num列表,当我执行del_all_节点函数时,内核崩溃 我尝试标记列表,内核不会崩溃。我不明白为什么会出现崩溃问题,因为我使用了自旋锁来保护这个数字列表 任何提示都将不胜感激 下面是简化的代码 #include <linux/init.h> #include <linux/module.h> #include <linux/list.h> #incl

我想清除一个由内核定义的类型列表。我有两个主要结构,num_wrapper和num.num_wapper有一个num列表,当我执行del_all_节点函数时,内核崩溃

我尝试标记列表,内核不会崩溃。我不明白为什么会出现崩溃问题,因为我使用了自旋锁来保护这个数字列表

任何提示都将不胜感激

下面是简化的代码

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

struct num_wrapper {
    struct list_head num_list;
    spinlock_t list_lock;
    u8 check_num;
};

struct num {
    struct list_head node;
    int number;
    struct num_wrapper* num_w_ptr;
};

s32 del_all_node(struct num_wrapper *number_wrap)
{
    struct num *tmp;    
    struct num *num_head; 
    spin_lock(&number_wrap->list_lock); 
    list_for_each_entry_safe(num_head, tmp, &number_wrap->num_list, node) {
        printk("num_head is %d\n", num_head->number); 
        list_del(&num_head->node);//this line seems to have problem 
    }
    spin_unlock(&number_wrap->list_lock); 
    return 0;
}

static int __init hello_init(void)
{
    /*Setup Scenario*/     
    struct num_wrapper *number_wrap = kzalloc(sizeof(struct num_wrapper)
            , GFP_KERNEL);  
    struct num *number = kzalloc(sizeof(struct num), GFP_KERNEL);  
    number->number = 10; 
    number_wrap->check_num = 20;
    INIT_LIST_HEAD(&number->node);   
    INIT_LIST_HEAD(&number_wrap->num_list); 
    list_add_tail(&number->node, &number_wrap->num_list); 

    del_all_node(number_wrap);
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT "Good, haha\n");
}

module_init(hello_init);
module_exit(hello_exit);
由于free_netdev还将释放私有数据xx_if,因此代码被破坏。。。 我的修复方法是将序列更改为这两个语句,并修复崩溃问题


更奇怪的是,我必须检查xx_if是否为NULL,但如果我不交换这两个语句,仍然会导致崩溃。

我不清楚以下代码:

INIT_LIST_HEAD(&number->node);   
INIT_LIST_HEAD(&number_wrap->num_list); 
list_add_tail(&number->node, &number_wrap->num_list); 
初始化两种不同的结构,然后将一种类型的列表添加到另一种类型的列表

你能这样做吗

我认为,你需要这样的东西:

  struct num{
        u8 check_num;
        struct list_head list;
    };

    struct num_wrapper{
        struct num* num_ptr;
        spinlock_t list_lock;
    };

    int init_num_wrapper(struct num_wrapper** prt){
        if(!ptr && *ptr){
            return -EINVAL;
        }

        *ptr = kzalloc(sizeof(struct num_wrapper), GFP_KERNEL);
        if(!*ptr){
            return -ENOMEM;
        }
        INIT_LIST_HEAD(& (*ptr)->num_ptr->list);
        ... init spinlock
        return 0;
    }

    int add_num(num_wrapper* prt_wrap, u8 check_num){
        ... checking pointers
        struct num num* = NULL;
        num = kmalloc(sizeof(struct num), GFP_KERNEL);
        if(! num){
            return -ENOMEM;
        }

        INIT_LIST_HEAD(&num->list);
        num->check_num = check_num;
        spin_lock(&prt_wrap->list_lock);
        list_add_tail(&num->list, &prt_wrap->num_ptr.list);
        spin_unlock(&prt_wrap->list_lock);
        return 0;
    }

    int remove_all_nodes(num_wrapper* prt_wrap){
        ... checking pointer
        struct num *tmp = NULL;    
        struct num *num_head = NULL; 
        spin_lock(&number_wrap->list_lock); 
        list_for_each_entry_safe(num_head, tmp, &prt_wrap->list, list)
        {
            printk("num_head is %d\n", num_head->number); 
            list_del(&num_head->node);//this line seems to have problem 
        }
        spin_unlock(&num_wrapper->list_lock); 
        return 0;
    }
更新

然后,您可以使用上述函数来操作num_包装器。 例如:

 //...
    struct num_wrapper* nums = NULL;
    init_num_wrapper(&nums); // after this call, you will have inited nums var, which can be used with others functions for manipulating with num_wrapper list.
     u8 num = 2;
     add_num(nums, num); // after this call new node with num will be added to num_wrapper 
    //... 

是否有任何输出支持您的断言?你也可以展示一下吗?你没有初始化number-wrap对象的list-lock成员:spin-lock-init&number-wrap->list-lock;在我的实际代码中,我已经初始化了自旋锁,我在每条语句之后打印一些消息。并发现列表删除后的打印消息未显示。顺便说一下,我已经启用了CONFIG_LOCK_STAT,我发现debug_locks_off在list_del之后调用了很多次。你不需要在问题中线性检查num_head指针,实际上我想要的是num_wrapper可以存储num_list的head,并且只有一个num_wrapper,但是num struct的列表我不确定我是否理解您的init_包装函数。你能举例说明如何使用你的函数吗?
 //...
    struct num_wrapper* nums = NULL;
    init_num_wrapper(&nums); // after this call, you will have inited nums var, which can be used with others functions for manipulating with num_wrapper list.
     u8 num = 2;
     add_num(nums, num); // after this call new node with num will be added to num_wrapper 
    //...