8

これは、dequeue_huge_page_vma()とalloc_buddy_huge_page()を使って1つの巨大なページを割り当てるモジュールです。それらを独立したvmにするために、私は__get_vm_area_node()から利用可能なVM領域を得て、その仮想アドレスを取得します。私は1つの2メガバイトのページを割り当てたい、しかし、カーネルは言う:私のモジュールがカーネルページングリクエストを処理できないのはなぜですか?

[ 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"); 
+0

各文の後にprintk文を追加し、クラッシュする箇所を確認します。また、デバッガにデバッグシンボルをロードし、クラッシュした場所を確認することもできます。クラッシュレポートからさらに情報を貼り付けます。あなたが含まれている以上のものがあるはずです。 – hebbo

+0

エリアオブジェクトのダンプを提供できますか? – t0k3n1z3r

答えて

0

これは本当に古い質問ですが、一体何...

__get_vm_area_nodeを( )いくつかの理由でNULLを返すことができます、あなたは無条件にその戻り値を尊重します。これは賢明ではありません。

関連する問題