为啥我的模块无法处理内核分页请求?
Posted
技术标签:
【中文标题】为啥我的模块无法处理内核分页请求?【英文标题】:Why is my module unable to handle kernel paging request?为什么我的模块无法处理内核分页请求? 【发布时间】:2012-01-04 12:02:19 【问题描述】:这是我使用 dequeue_huge_page_vma() 和 alloc_buddy_huge_page() 分配一个大页面的模块。为了使它们独立于 vma,我从 __get_vm_area_node() 获取可用的 vm 区域,然后获取其虚拟地址。我想分配一个 2MB 的页面,但是内核说:
[ 84.944634] BUG: unable to handle kernel paging request at ffffc90013d02000
[ 84.944641] IP: [<ffffffffa0ac9063>] vma_null_test+0x63/0xa3 [vma_null_test]
[ 84.944650] PGD bd019067 PUD bd01a067 PMD b35c0067 PTE 0
[ 84.944657] Oops: 0000 [#1] SMP
我的代码:
/*
* vma_null_test.c - Cindy: to test if vma can be set to NULL in alloc_huge_page()
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/hugetlb.h>
#include <linux/mm.h>
#include <linux/list.h>
#include <asm/page.h>
#include <linux/nodemask.h>
#include <linux/gfp.h>
#include <linux/mm_types.h>
#include <asm-generic/pgtable.h>
#include <linux/err.h>
#include <linux/vmalloc.h>
#define TWO_MB 0x200000
struct hstate *h;
struct vm_struct *__get_vm_area_node(unsigned long size,
unsigned long align, unsigned long flags, unsigned long start,
unsigned long end, int node, gfp_t gfp_mask, void *caller);
struct page *dequeue_huge_page_vma(struct hstate *,struct vm_area_struct *,
unsigned long, int);
struct page *alloc_buddy_huge_page(struct hstate *,struct vm_area_struct *,
unsigned long);
struct page *alloc_huge_page_node_mod(unsigned long vaddr)
struct page *page;
page = dequeue_huge_page_vma(h, NULL, vaddr, 0);
if (!page)
page = alloc_buddy_huge_page(h, NULL, vaddr);
return page;
static int __init vma_null_test(void)
struct vm_struct *area;
h=&default_hstate;
unsigned long *address;
struct page *page;
int ret;
area=__get_vm_area_node(TWO_MB, 1, VM_ALLOC, VMALLOC_START, VMALLOC_END, -1, GFP_KERNEL|__GFP_HIGHMEM, __builtin_return_address(0));
address=(unsigned long *)area->addr;
page=alloc_huge_page_node_mod(*address);
if(IS_ERR(page))
ret=-PTR_ERR(page);
printk(KERN_ERR "Cannot allocate page\n");
else
ret=0;
printk(KERN_ERR "Allocate one huge page at virtual address:%x\n",*address);
return ret;
static void __exit vma_null_exit(void)
printk(KERN_ERR ".............Exit..........\n");
module_init(vma_null_test);
module_exit(vma_null_exit);
MODULE_LICENSE("GPL");
【问题讨论】:
在每个语句之后添加一个 printk 语句,看看它在哪里崩溃。此外,您可以尝试将调试符号加载到调试器中并检查它崩溃的位置。并粘贴崩溃报告中的更多信息。应该比你包含的更多。 你能提供区域对象的转储吗? 【参考方案1】:这是一个非常古老的问题,但到底是什么......
__get_vm_area_node() 可以出于多种原因返回 NULL,您可以无条件地尊重它的返回值。这是不明智的。
【讨论】:
以上是关于为啥我的模块无法处理内核分页请求?的主要内容,如果未能解决你的问题,请参考以下文章