8

Questo è il mio modulo per allocare una pagina enorme usando dequeue_huge_page_vma() e alloc_buddy_huge_page(). Per renderli indipendenti da vma, ottengo l'area vm disponibile da __get_vm_area_node(), e quindi ottengo il suo indirizzo virtuale. Voglio allocare una pagina 2MB, tuttavia, il kernel dice:Perché il mio modulo non è in grado di gestire la richiesta di paging del kernel?

[ 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 

Il mio codice:

/* 
* 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

aggiungere una dichiarazione printk dopo ogni dichiarazione e vedere dove si blocca. Inoltre, puoi provare a caricare i simboli di debug nel debugger e controllare dove si è bloccato. E incolla più informazioni dal rapporto sugli arresti anomali. Ci dovrebbe essere più di quello che hai incluso. – hebbo

+0

È possibile fornire il dump dell'oggetto area? – t0k3n1z3r

risposta

0

Questa è una domanda molto vecchio, ma che diamine ...

__get_vm_area_node () può restituire NULL per diversi motivi, si deferisce il suo valore di ritorno incondizionatamente. Questo non è saggio.

Problemi correlati