8

Este es mi módulo para asignar una página enorme usando dequeue_huge_page_vma() y alloc_buddy_huge_page(). Para que sean independientes de vma, obtengo el área vm disponible de __get_vm_area_node() y luego obtengo su dirección virtual. Quiero asignar una página de 2 MB, sin embargo, el núcleo dice:¿Por qué mi módulo no puede manejar la solicitud de paginación 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 

Mi código:

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

agregue una instrucción printk después de cada declaración y vea dónde se cuelga. Además, puede intentar cargar símbolos de depuración en el depurador y comprobar dónde se colgó. Y pegue más información del informe de bloqueo. Debería haber más de lo que incluiste. – hebbo

+0

¿Puede proporcionar un volcado del objeto de área? – t0k3n1z3r

Respuesta

0

Ésta es una pregunta muy viejo, pero qué diablos ...

__get_vm_area_node () puede devolver NULL por varias razones, respeta su valor de retorno incondicionalmente. Esto no es sabio

Cuestiones relacionadas