在linux驱动程序中,为什么kfree不起作用,当数据指针在函数中传递时?

时间:2016-03-22 03:51:19

标签: linux linux-kernel linux-device-driver embedded-linux

我尝试制作一个简单的程序。 源代码如下。 当插入模块时,我尝试kmalloc一些内存。然后释放内存,当删除模块时。 但是我使用了命令,发现它在移除模块时没有释放内存。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>

#define FILE_NAME       "test"

typedef struct info
{
    char data[1048576];
}sInfo;

static sInfo* Info;

int mmap_alloc2(void* buf, int require_buf_size)
{
    struct page *page;
    void* mmap_buf;

    unsigned long mmap_size = PAGE_ALIGN(require_buf_size);
    printk("size=%lu\n",mmap_size);
    buf = kzalloc(mmap_size, GFP_KERNEL);
    if (!buf) {
        return -1;
    }
    mmap_buf = buf;
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) {
        SetPageReserved(page);
    }

    return 0;
}

void mmap_free2(void* buf, int require_buf_size)
{
    struct page *page;
    void *mmap_buf = buf;

    unsigned long mmap_size = PAGE_ALIGN(require_buf_size);
    printk("size=%lu\n",mmap_size);
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) {
        ClearPageReserved(page);
    }
    kfree((sInfo*)buf);
    mmap_buf = NULL;
}

static int mmap_example_init(void)
{
    struct proc_dir_entry *pEntry = NULL;
    printk("mmap example init\n");

    if(!(pEntry = create_proc_entry(FILE_NAME, 0666, NULL)))
    {
        printk("create proc entry fail\n");
        return -EFAULT;
    }

    mmap_alloc2(Info, sizeof(sInfo));
    return 0;
}

static void mmap_example_exit(void)
{
    printk("mmap example exit\n");
    mmap_free2(Info, sizeof(sInfo));
    remove_proc_entry(FILE_NAME,NULL);
}

module_init(mmap_example_init);
module_exit(mmap_example_exit);

但是当我将数据指针从函数更改为全局范围时,kfree可以工作。 代码如下。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>


#define FILE_NAME       "test"

static void* mmap_buf;
typedef struct info
{
    char data[1048576];
}sInfo;

static sInfo* Info;

int mmap_alloc1(int require_buf_size)
{
    struct page *page;

    int mmap_size = PAGE_ALIGN(require_buf_size);
    mmap_buf = kzalloc(mmap_size, GFP_KERNEL);
    if (!mmap_buf) {
        return -1;
    }
    for (page = virt_to_page(mmap_buf ); page < virt_to_page(mmap_buf + mmap_size); page++) {
        SetPageReserved(page);
    }

    return 0;
}

void mmap_free1(int require_buf_size)
{
    struct page *page;
    unsigned long mmap_size = PAGE_ALIGN(require_buf_size);
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) {
        ClearPageReserved(page);
    }
    kfree(mmap_buf);
    mmap_buf = NULL;
}


static int mmap_example_init(void)
{
    struct proc_dir_entry *pEntry = NULL;
    printk("mmap example init\n");

    if(!(pEntry = create_proc_entry(FILE_NAME, 0666, NULL)))
    {
        printk("create proc entry fail\n");
        return -EFAULT;
    }
    mmap_alloc1(sizeof(sInfo));
    return 0;
}

static void mmap_example_exit(void)
{
    printk("mmap example exit\n");
    mmap_free1(sizeof(sInfo));
    remove_proc_entry(FILE_NAME,NULL);
}

module_init(mmap_example_init);
module_exit(mmap_example_exit);

那么这两个代码的区别是什么?以及如何修改sample1以使kfree工作?

1 个答案:

答案 0 :(得分:0)

在第一个代码示例中,您正在分配内存,但实际上并没有将地址分配给指针变量Info。而你的mmap_buf是一个局部变量,它在第一种情况下并没有真正做任何事情。所以你试图释放一些随机地址。哪个可能有效,也可能无效。通常它不会,也绝对不是你想要释放的东西。

您可以让mmap_alloc2()返回指针并将其指定给Info,例如Info = mmap_alloc2(sizeof(sInfo));或将Info的地址传递给函数,例如int mmap_alloc2(void **buf, int require_buf_size)*buf = kzalloc(mmap_size, GFP_KERNEL);。使用mmap_alloc2(&Info, sizeof(sInfo));

进行调用